[Pkg-openldap-devel] r892 - in openldap/trunk: . build clients clients/tools contrib contrib/ldapc++ contrib/ldapc++/examples contrib/ldapc++/src contrib/ldapc++/src/ac contrib/slapd-modules contrib/slapd-modules/acl contrib/slapd-modules/comp_match contrib/slapd-modules/dsaschema contrib/slapd-modules/passwd contrib/slapd-modules/smbk5pwd debian debian/schema doc doc/devel doc/guide doc/guide/admin doc/guide/images doc/guide/release doc/man doc/man/man1 doc/man/man3 doc/man/man5 doc/man/man8 include include/ac libraries libraries/liblber libraries/libldap libraries/libldap_r libraries/liblunicode libraries/liblunicode/ucdata libraries/liblunicode/ure libraries/liblunicode/utbm libraries/liblutil libraries/librewrite servers servers/slapd servers/slapd/back-bdb servers/slapd/back-dnssrv servers/slapd/back-hdb servers/slapd/back-ldap servers/slapd/back-ldif servers/slapd/back-meta servers/slapd/back-monitor servers/slapd/back-null servers/slapd/back-passwd servers/slapd/back-perl servers/slapd/back-relay servers/slapd/back-shell servers/slapd/back-sql servers/slapd/back-sql/rdbms_depend/ibmdb2 servers/slapd/back-sql/rdbms_depend/mysql servers/slapd/back-sql/rdbms_depend/oracle servers/slapd/back-sql/rdbms_depend/pgsql servers/slapd/back-sql/rdbms_depend/timesten servers/slapd/overlays servers/slapd/schema servers/slapd/shell-backends servers/slapd/slapi tests tests/data tests/data/sql-concurrency tests/progs tests/scripts

Steve Langasek vorlon at alioth.debian.org
Sat Dec 15 10:25:35 UTC 2007


Author: vorlon
Date: 2007-12-15 10:25:31 +0000 (Sat, 15 Dec 2007)
New Revision: 892

Added:
   openldap/trunk/build/db.4.2.52.patch
   openldap/trunk/clients/tools/ldapexop.c
   openldap/trunk/contrib/ConfigOIDs
   openldap/trunk/contrib/ldapc++/examples/urlTest.cpp
   openldap/trunk/contrib/ldaptcl/
   openldap/trunk/contrib/slapd-modules/addpartial/
   openldap/trunk/contrib/slapd-modules/allop/
   openldap/trunk/contrib/slapd-modules/denyop/
   openldap/trunk/contrib/slapd-modules/lastmod/
   openldap/trunk/contrib/slapd-modules/passwd/radius.c
   openldap/trunk/contrib/slapd-modules/proxyOld/
   openldap/trunk/contrib/slapd-modules/trace/
   openldap/trunk/debian/schema/collective.schema
   openldap/trunk/doc/guide/admin/README.spellcheck
   openldap/trunk/doc/guide/admin/allmail-en.png
   openldap/trunk/doc/guide/admin/allusersgroup-en.png
   openldap/trunk/doc/guide/admin/appendix-changes.sdf
   openldap/trunk/doc/guide/admin/appendix-common-errors.sdf
   openldap/trunk/doc/guide/admin/appendix-configs.sdf
   openldap/trunk/doc/guide/admin/appendix-contrib.sdf
   openldap/trunk/doc/guide/admin/appendix-deployments.sdf
   openldap/trunk/doc/guide/admin/appendix-ldap-result-codes.sdf
   openldap/trunk/doc/guide/admin/appendix-recommended-versions.sdf
   openldap/trunk/doc/guide/admin/appendix-upgrading.sdf
   openldap/trunk/doc/guide/admin/aspell.en.pws
   openldap/trunk/doc/guide/admin/backends.sdf
   openldap/trunk/doc/guide/admin/config_dit.png
   openldap/trunk/doc/guide/admin/config_local.png
   openldap/trunk/doc/guide/admin/config_ref.png
   openldap/trunk/doc/guide/admin/dual_dc.png
   openldap/trunk/doc/guide/admin/glossary.sdf
   openldap/trunk/doc/guide/admin/guide.book
   openldap/trunk/doc/guide/admin/intro_dctree.png
   openldap/trunk/doc/guide/admin/intro_tree.png
   openldap/trunk/doc/guide/admin/maintenance.sdf
   openldap/trunk/doc/guide/admin/overlays.sdf
   openldap/trunk/doc/guide/admin/refint.png
   openldap/trunk/doc/guide/admin/troubleshooting.sdf
   openldap/trunk/doc/guide/images/src/
   openldap/trunk/doc/man/Project
   openldap/trunk/doc/man/man3/Deprecated
   openldap/trunk/doc/man/man3/lber-sockbuf.3
   openldap/trunk/doc/man/man3/ldap_controls.3
   openldap/trunk/doc/man/man3/ldap_controls.3.links
   openldap/trunk/doc/man/man3/ldap_extended_operation.3
   openldap/trunk/doc/man/man3/ldap_extended_operation.3.links
   openldap/trunk/doc/man/man3/ldap_get_option.3
   openldap/trunk/doc/man/man3/ldap_get_option.3.links
   openldap/trunk/doc/man/man3/ldap_memory.3
   openldap/trunk/doc/man/man3/ldap_memory.3.links
   openldap/trunk/doc/man/man3/ldap_parse_sort_control.3
   openldap/trunk/doc/man/man3/ldap_parse_vlv_control.3
   openldap/trunk/doc/man/man3/ldap_rename.3
   openldap/trunk/doc/man/man3/ldap_rename.3.links
   openldap/trunk/doc/man/man3/ldap_sync.3
   openldap/trunk/doc/man/man3/ldap_tls.3
   openldap/trunk/doc/man/man3/ldap_tls.3.links
   openldap/trunk/doc/man/man5/slapd-config.5
   openldap/trunk/doc/man/man5/slapd.backends.5
   openldap/trunk/doc/man/man5/slapd.overlays.5
   openldap/trunk/doc/man/man5/slapo-constraint.5
   openldap/trunk/doc/man/man5/slapo-dds.5
   openldap/trunk/doc/man/man5/slapo-dyngroup.5
   openldap/trunk/doc/man/man5/slapo-memberof.5
   openldap/trunk/libraries/libldap/dds.c
   openldap/trunk/libraries/libldap/ldap_sync.c
   openldap/trunk/libraries/libldap/pagectrl.c
   openldap/trunk/libraries/libldap/stctrl.c
   openldap/trunk/libraries/libldap/urltest.c
   openldap/trunk/libraries/libldap_r/rmutex.c
   openldap/trunk/libraries/liblutil/testtavl.c
   openldap/trunk/servers/slapd/back-bdb/monitor.c
   openldap/trunk/servers/slapd/back-ldap/distproc.c
   openldap/trunk/servers/slapd/back-ldap/monitor.c
   openldap/trunk/servers/slapd/overlays/constraint.c
   openldap/trunk/servers/slapd/overlays/dds.c
   openldap/trunk/servers/slapd/overlays/memberof.c
   openldap/trunk/servers/slapd/schema/cosine.ldif
   openldap/trunk/servers/slapd/schema/duaconf.schema
   openldap/trunk/servers/slapd/schema/inetorgperson.ldif
   openldap/trunk/servers/slapd/schema/nadf.schema
   openldap/trunk/servers/slapd/schema/nis.ldif
   openldap/trunk/servers/slapd/slapd.ldif
   openldap/trunk/servers/slapd/txn.c
   openldap/trunk/tests/data/dds.out
   openldap/trunk/tests/data/do_bind.0
   openldap/trunk/tests/data/memberof.out
   openldap/trunk/tests/data/regressions/
   openldap/trunk/tests/data/slapd-config-naked.conf
   openldap/trunk/tests/data/slapd-config-undo.conf
   openldap/trunk/tests/data/slapd-dds.conf
   openldap/trunk/tests/data/slapd-dynamic.ldif
   openldap/trunk/tests/data/slapd-meta-target1.conf
   openldap/trunk/tests/data/slapd-meta-target2.conf
   openldap/trunk/tests/data/slapd-repl-slave-remote.conf
   openldap/trunk/tests/data/slapd-syncrepl-multiproxy.conf
   openldap/trunk/tests/data/slapd-syncrepl-slave-persist-ldap.conf
   openldap/trunk/tests/data/sql-concurrency/do_bind.0
   openldap/trunk/tests/progs/slapd-common.c
   openldap/trunk/tests/progs/slapd-common.h
   openldap/trunk/tests/scripts/its-all
   openldap/trunk/tests/scripts/test045-syncreplication-proxied
   openldap/trunk/tests/scripts/test046-dds
   openldap/trunk/tests/scripts/test047-ldap
   openldap/trunk/tests/scripts/test048-syncrepl-multiproxy
   openldap/trunk/tests/scripts/test049-sync-config
   openldap/trunk/tests/scripts/test050-syncrepl-multimaster
   openldap/trunk/tests/scripts/test051-config-undo
   openldap/trunk/tests/scripts/test052-memberof
Removed:
   openldap/trunk/contrib/ldapc++/acconfig.h
   openldap/trunk/contrib/ldapc++/mkinstalldirs
   openldap/trunk/contrib/ldapc++/stamp-h.in
   openldap/trunk/doc/guide/admin/config_dit.gif
   openldap/trunk/doc/guide/admin/config_local.gif
   openldap/trunk/doc/guide/admin/config_ref.gif
   openldap/trunk/doc/guide/admin/config_x500fe.gif
   openldap/trunk/doc/guide/admin/config_x500ref.gif
   openldap/trunk/doc/guide/admin/intro_dctree.gif
   openldap/trunk/doc/guide/admin/intro_tree.gif
   openldap/trunk/doc/guide/admin/proxycache.sdf
   openldap/trunk/doc/guide/admin/replication.gif
   openldap/trunk/doc/guide/admin/syncrepl.sdf
   openldap/trunk/doc/man/man5/slapd-tcl.5
   openldap/trunk/doc/man/man5/slapd.replog.5
   openldap/trunk/doc/man/man5/slapo-lastmod.5
   openldap/trunk/doc/man/man8/slurpd.8
   openldap/trunk/include/ac/krb.h
   openldap/trunk/include/ac/krb5.h
   openldap/trunk/libraries/libldap/groupings.c
   openldap/trunk/libraries/libldap/kbind.c
   openldap/trunk/servers/slapd/back-ldbm/
   openldap/trunk/servers/slapd/back-relay/config.c
   openldap/trunk/servers/slapd/kerberos.c
   openldap/trunk/servers/slapd/overlays/denyop.c
   openldap/trunk/servers/slapd/overlays/lastmod.c
   openldap/trunk/servers/slapd/repl.c
   openldap/trunk/servers/slurpd/
   openldap/trunk/tests/data/slapd-meta2.conf
   openldap/trunk/tests/data/slapd-repl-master.conf
   openldap/trunk/tests/data/slapd-repl-slave.conf
   openldap/trunk/tests/scripts/test007-replication
Modified:
   openldap/trunk/ANNOUNCEMENT
   openldap/trunk/CHANGES
   openldap/trunk/COPYRIGHT
   openldap/trunk/Makefile.in
   openldap/trunk/README
   openldap/trunk/build/config.guess
   openldap/trunk/build/config.sub
   openldap/trunk/build/crupdate
   openldap/trunk/build/dir.mk
   openldap/trunk/build/info.mk
   openldap/trunk/build/lib-shared.mk
   openldap/trunk/build/lib-static.mk
   openldap/trunk/build/lib.mk
   openldap/trunk/build/ltmain.sh
   openldap/trunk/build/man.mk
   openldap/trunk/build/mkdep
   openldap/trunk/build/mkrelease
   openldap/trunk/build/mkvers.bat
   openldap/trunk/build/mkversion
   openldap/trunk/build/mod.mk
   openldap/trunk/build/openldap.m4
   openldap/trunk/build/rules.mk
   openldap/trunk/build/srv.mk
   openldap/trunk/build/top.mk
   openldap/trunk/build/version.sh
   openldap/trunk/build/version.var
   openldap/trunk/clients/Makefile.in
   openldap/trunk/clients/tools/Makefile.in
   openldap/trunk/clients/tools/common.c
   openldap/trunk/clients/tools/common.h
   openldap/trunk/clients/tools/ldapcompare.c
   openldap/trunk/clients/tools/ldapdelete.c
   openldap/trunk/clients/tools/ldapmodify.c
   openldap/trunk/clients/tools/ldapmodrdn.c
   openldap/trunk/clients/tools/ldappasswd.c
   openldap/trunk/clients/tools/ldapsearch.c
   openldap/trunk/clients/tools/ldapwhoami.c
   openldap/trunk/configure
   openldap/trunk/configure.in
   openldap/trunk/contrib/README
   openldap/trunk/contrib/ldapc++/Makefile.in
   openldap/trunk/contrib/ldapc++/aclocal.m4
   openldap/trunk/contrib/ldapc++/configure
   openldap/trunk/contrib/ldapc++/configure.in
   openldap/trunk/contrib/ldapc++/depcomp
   openldap/trunk/contrib/ldapc++/examples/Makefile.am
   openldap/trunk/contrib/ldapc++/examples/Makefile.in
   openldap/trunk/contrib/ldapc++/examples/main.cpp
   openldap/trunk/contrib/ldapc++/examples/readSchema.cpp
   openldap/trunk/contrib/ldapc++/install-sh
   openldap/trunk/contrib/ldapc++/ltmain.sh
   openldap/trunk/contrib/ldapc++/missing
   openldap/trunk/contrib/ldapc++/src/LDAPAsynConnection.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPAsynConnection.h
   openldap/trunk/contrib/ldapc++/src/LDAPAttrType.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPAttrType.h
   openldap/trunk/contrib/ldapc++/src/LDAPAttribute.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPAttributeList.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPBindRequest.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPEntry.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPEntry.h
   openldap/trunk/contrib/ldapc++/src/LDAPException.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPException.h
   openldap/trunk/contrib/ldapc++/src/LDAPExtRequest.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPMessageQueue.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPMessageQueue.h
   openldap/trunk/contrib/ldapc++/src/LDAPModList.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPResult.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPUrl.cpp
   openldap/trunk/contrib/ldapc++/src/LDAPUrl.h
   openldap/trunk/contrib/ldapc++/src/Makefile.am
   openldap/trunk/contrib/ldapc++/src/Makefile.in
   openldap/trunk/contrib/ldapc++/src/StringList.cpp
   openldap/trunk/contrib/ldapc++/src/ac/time.h
   openldap/trunk/contrib/ldapc++/src/config.h.in
   openldap/trunk/contrib/slapd-modules/acl/posixgroup.c
   openldap/trunk/contrib/slapd-modules/comp_match/Makefile
   openldap/trunk/contrib/slapd-modules/dsaschema/dsaschema.c
   openldap/trunk/contrib/slapd-modules/passwd/README
   openldap/trunk/contrib/slapd-modules/passwd/kerberos.c
   openldap/trunk/contrib/slapd-modules/passwd/netscape.c
   openldap/trunk/contrib/slapd-modules/smbk5pwd/smbk5pwd.c
   openldap/trunk/debian/changelog
   openldap/trunk/doc/Makefile.in
   openldap/trunk/doc/devel/args
   openldap/trunk/doc/devel/todo
   openldap/trunk/doc/devel/toolargs
   openldap/trunk/doc/guide/COPYRIGHT
   openldap/trunk/doc/guide/admin/Makefile
   openldap/trunk/doc/guide/admin/abstract.sdf
   openldap/trunk/doc/guide/admin/admin.sdf
   openldap/trunk/doc/guide/admin/config.sdf
   openldap/trunk/doc/guide/admin/dbtools.sdf
   openldap/trunk/doc/guide/admin/guide.html
   openldap/trunk/doc/guide/admin/guide.sdf
   openldap/trunk/doc/guide/admin/index.sdf
   openldap/trunk/doc/guide/admin/install.sdf
   openldap/trunk/doc/guide/admin/intro.sdf
   openldap/trunk/doc/guide/admin/master.sdf
   openldap/trunk/doc/guide/admin/monitoringslapd.sdf
   openldap/trunk/doc/guide/admin/preface.sdf
   openldap/trunk/doc/guide/admin/quickstart.sdf
   openldap/trunk/doc/guide/admin/referrals.sdf
   openldap/trunk/doc/guide/admin/replication.sdf
   openldap/trunk/doc/guide/admin/runningslapd.sdf
   openldap/trunk/doc/guide/admin/sasl.sdf
   openldap/trunk/doc/guide/admin/schema.sdf
   openldap/trunk/doc/guide/admin/security.sdf
   openldap/trunk/doc/guide/admin/slapdconf2.sdf
   openldap/trunk/doc/guide/admin/slapdconfig.sdf
   openldap/trunk/doc/guide/admin/title.sdf
   openldap/trunk/doc/guide/admin/tls.sdf
   openldap/trunk/doc/guide/admin/tuning.sdf
   openldap/trunk/doc/guide/plain.sdf
   openldap/trunk/doc/guide/preamble.sdf
   openldap/trunk/doc/guide/release/copyright-plain.sdf
   openldap/trunk/doc/guide/release/copyright.sdf
   openldap/trunk/doc/guide/release/install.sdf
   openldap/trunk/doc/guide/release/license-plain.sdf
   openldap/trunk/doc/guide/release/license.sdf
   openldap/trunk/doc/man/Makefile.in
   openldap/trunk/doc/man/man1/Makefile.in
   openldap/trunk/doc/man/man1/ldapcompare.1
   openldap/trunk/doc/man/man1/ldapdelete.1
   openldap/trunk/doc/man/man1/ldapmodify.1
   openldap/trunk/doc/man/man1/ldapmodrdn.1
   openldap/trunk/doc/man/man1/ldappasswd.1
   openldap/trunk/doc/man/man1/ldapsearch.1
   openldap/trunk/doc/man/man1/ldapwhoami.1
   openldap/trunk/doc/man/man3/Makefile.in
   openldap/trunk/doc/man/man3/lber-decode.3
   openldap/trunk/doc/man/man3/lber-encode.3
   openldap/trunk/doc/man/man3/lber-memory.3
   openldap/trunk/doc/man/man3/lber-types.3
   openldap/trunk/doc/man/man3/ldap.3
   openldap/trunk/doc/man/man3/ldap_abandon.3
   openldap/trunk/doc/man/man3/ldap_add.3
   openldap/trunk/doc/man/man3/ldap_bind.3
   openldap/trunk/doc/man/man3/ldap_bind.3.links
   openldap/trunk/doc/man/man3/ldap_compare.3
   openldap/trunk/doc/man/man3/ldap_delete.3
   openldap/trunk/doc/man/man3/ldap_error.3
   openldap/trunk/doc/man/man3/ldap_first_attribute.3
   openldap/trunk/doc/man/man3/ldap_first_entry.3
   openldap/trunk/doc/man/man3/ldap_first_message.3
   openldap/trunk/doc/man/man3/ldap_first_reference.3
   openldap/trunk/doc/man/man3/ldap_get_dn.3
   openldap/trunk/doc/man/man3/ldap_get_values.3
   openldap/trunk/doc/man/man3/ldap_modify.3
   openldap/trunk/doc/man/man3/ldap_modrdn.3
   openldap/trunk/doc/man/man3/ldap_open.3
   openldap/trunk/doc/man/man3/ldap_open.3.links
   openldap/trunk/doc/man/man3/ldap_parse_reference.3
   openldap/trunk/doc/man/man3/ldap_parse_result.3
   openldap/trunk/doc/man/man3/ldap_result.3
   openldap/trunk/doc/man/man3/ldap_schema.3
   openldap/trunk/doc/man/man3/ldap_search.3
   openldap/trunk/doc/man/man3/ldap_sort.3
   openldap/trunk/doc/man/man3/ldap_url.3
   openldap/trunk/doc/man/man5/Makefile.in
   openldap/trunk/doc/man/man5/ldap.conf.5
   openldap/trunk/doc/man/man5/ldif.5
   openldap/trunk/doc/man/man5/slapd-bdb.5
   openldap/trunk/doc/man/man5/slapd-dnssrv.5
   openldap/trunk/doc/man/man5/slapd-ldap.5
   openldap/trunk/doc/man/man5/slapd-ldbm.5
   openldap/trunk/doc/man/man5/slapd-ldif.5
   openldap/trunk/doc/man/man5/slapd-meta.5
   openldap/trunk/doc/man/man5/slapd-monitor.5
   openldap/trunk/doc/man/man5/slapd-null.5
   openldap/trunk/doc/man/man5/slapd-passwd.5
   openldap/trunk/doc/man/man5/slapd-perl.5
   openldap/trunk/doc/man/man5/slapd-relay.5
   openldap/trunk/doc/man/man5/slapd-shell.5
   openldap/trunk/doc/man/man5/slapd-sql.5
   openldap/trunk/doc/man/man5/slapd.access.5
   openldap/trunk/doc/man/man5/slapd.conf.5
   openldap/trunk/doc/man/man5/slapd.plugin.5
   openldap/trunk/doc/man/man5/slapo-accesslog.5
   openldap/trunk/doc/man/man5/slapo-auditlog.5
   openldap/trunk/doc/man/man5/slapo-chain.5
   openldap/trunk/doc/man/man5/slapo-dynlist.5
   openldap/trunk/doc/man/man5/slapo-pcache.5
   openldap/trunk/doc/man/man5/slapo-ppolicy.5
   openldap/trunk/doc/man/man5/slapo-refint.5
   openldap/trunk/doc/man/man5/slapo-retcode.5
   openldap/trunk/doc/man/man5/slapo-rwm.5
   openldap/trunk/doc/man/man5/slapo-syncprov.5
   openldap/trunk/doc/man/man5/slapo-translucent.5
   openldap/trunk/doc/man/man5/slapo-unique.5
   openldap/trunk/doc/man/man5/slapo-valsort.5
   openldap/trunk/doc/man/man8/Makefile.in
   openldap/trunk/doc/man/man8/slapacl.8
   openldap/trunk/doc/man/man8/slapadd.8
   openldap/trunk/doc/man/man8/slapauth.8
   openldap/trunk/doc/man/man8/slapcat.8
   openldap/trunk/doc/man/man8/slapd.8
   openldap/trunk/doc/man/man8/slapdn.8
   openldap/trunk/doc/man/man8/slapindex.8
   openldap/trunk/doc/man/man8/slappasswd.8
   openldap/trunk/doc/man/man8/slaptest.8
   openldap/trunk/include/Makefile.in
   openldap/trunk/include/ac/alloca.h
   openldap/trunk/include/ac/assert.h
   openldap/trunk/include/ac/bytes.h
   openldap/trunk/include/ac/crypt.h
   openldap/trunk/include/ac/ctype.h
   openldap/trunk/include/ac/dirent.h
   openldap/trunk/include/ac/errno.h
   openldap/trunk/include/ac/fdset.h
   openldap/trunk/include/ac/localize.h
   openldap/trunk/include/ac/param.h
   openldap/trunk/include/ac/regex.h
   openldap/trunk/include/ac/setproctitle.h
   openldap/trunk/include/ac/signal.h
   openldap/trunk/include/ac/socket.h
   openldap/trunk/include/ac/stdarg.h
   openldap/trunk/include/ac/stdlib.h
   openldap/trunk/include/ac/string.h
   openldap/trunk/include/ac/sysexits.h
   openldap/trunk/include/ac/syslog.h
   openldap/trunk/include/ac/termios.h
   openldap/trunk/include/ac/time.h
   openldap/trunk/include/ac/unistd.h
   openldap/trunk/include/ac/wait.h
   openldap/trunk/include/avl.h
   openldap/trunk/include/getopt-compat.h
   openldap/trunk/include/lber.h
   openldap/trunk/include/lber_pvt.h
   openldap/trunk/include/lber_types.hin
   openldap/trunk/include/ldap.h
   openldap/trunk/include/ldap_cdefs.h
   openldap/trunk/include/ldap_config.hin
   openldap/trunk/include/ldap_defaults.h
   openldap/trunk/include/ldap_features.hin
   openldap/trunk/include/ldap_int_thread.h
   openldap/trunk/include/ldap_log.h
   openldap/trunk/include/ldap_pvt.h
   openldap/trunk/include/ldap_pvt_thread.h
   openldap/trunk/include/ldap_pvt_uc.h
   openldap/trunk/include/ldap_queue.h
   openldap/trunk/include/ldap_rq.h
   openldap/trunk/include/ldap_schema.h
   openldap/trunk/include/ldap_utf8.h
   openldap/trunk/include/ldif.h
   openldap/trunk/include/lutil.h
   openldap/trunk/include/lutil_hash.h
   openldap/trunk/include/lutil_ldap.h
   openldap/trunk/include/lutil_lockf.h
   openldap/trunk/include/lutil_md5.h
   openldap/trunk/include/lutil_sha1.h
   openldap/trunk/include/portable.hin
   openldap/trunk/include/rewrite.h
   openldap/trunk/include/slapi-plugin.h
   openldap/trunk/include/sysexits-compat.h
   openldap/trunk/libraries/Makefile.in
   openldap/trunk/libraries/liblber/Makefile.in
   openldap/trunk/libraries/liblber/assert.c
   openldap/trunk/libraries/liblber/bprint.c
   openldap/trunk/libraries/liblber/debug.c
   openldap/trunk/libraries/liblber/decode.c
   openldap/trunk/libraries/liblber/dtest.c
   openldap/trunk/libraries/liblber/encode.c
   openldap/trunk/libraries/liblber/etest.c
   openldap/trunk/libraries/liblber/idtest.c
   openldap/trunk/libraries/liblber/io.c
   openldap/trunk/libraries/liblber/lber-int.h
   openldap/trunk/libraries/liblber/memory.c
   openldap/trunk/libraries/liblber/nt_err.c
   openldap/trunk/libraries/liblber/options.c
   openldap/trunk/libraries/liblber/sockbuf.c
   openldap/trunk/libraries/liblber/stdio.c
   openldap/trunk/libraries/libldap/Makefile.in
   openldap/trunk/libraries/libldap/abandon.c
   openldap/trunk/libraries/libldap/add.c
   openldap/trunk/libraries/libldap/addentry.c
   openldap/trunk/libraries/libldap/apitest.c
   openldap/trunk/libraries/libldap/bind.c
   openldap/trunk/libraries/libldap/cancel.c
   openldap/trunk/libraries/libldap/charray.c
   openldap/trunk/libraries/libldap/compare.c
   openldap/trunk/libraries/libldap/controls.c
   openldap/trunk/libraries/libldap/cyrus.c
   openldap/trunk/libraries/libldap/delete.c
   openldap/trunk/libraries/libldap/dnssrv.c
   openldap/trunk/libraries/libldap/dntest.c
   openldap/trunk/libraries/libldap/error.c
   openldap/trunk/libraries/libldap/extended.c
   openldap/trunk/libraries/libldap/filter.c
   openldap/trunk/libraries/libldap/free.c
   openldap/trunk/libraries/libldap/ftest.c
   openldap/trunk/libraries/libldap/getattr.c
   openldap/trunk/libraries/libldap/getdn.c
   openldap/trunk/libraries/libldap/getentry.c
   openldap/trunk/libraries/libldap/getvalues.c
   openldap/trunk/libraries/libldap/init.c
   openldap/trunk/libraries/libldap/ldap-int.h
   openldap/trunk/libraries/libldap/ldap.conf
   openldap/trunk/libraries/libldap/messages.c
   openldap/trunk/libraries/libldap/modify.c
   openldap/trunk/libraries/libldap/modrdn.c
   openldap/trunk/libraries/libldap/open.c
   openldap/trunk/libraries/libldap/options.c
   openldap/trunk/libraries/libldap/os-ip.c
   openldap/trunk/libraries/libldap/os-local.c
   openldap/trunk/libraries/libldap/passwd.c
   openldap/trunk/libraries/libldap/ppolicy.c
   openldap/trunk/libraries/libldap/print.c
   openldap/trunk/libraries/libldap/references.c
   openldap/trunk/libraries/libldap/request.c
   openldap/trunk/libraries/libldap/result.c
   openldap/trunk/libraries/libldap/sasl.c
   openldap/trunk/libraries/libldap/sbind.c
   openldap/trunk/libraries/libldap/schema.c
   openldap/trunk/libraries/libldap/search.c
   openldap/trunk/libraries/libldap/sort.c
   openldap/trunk/libraries/libldap/sortctrl.c
   openldap/trunk/libraries/libldap/string.c
   openldap/trunk/libraries/libldap/t61.c
   openldap/trunk/libraries/libldap/test.c
   openldap/trunk/libraries/libldap/tls.c
   openldap/trunk/libraries/libldap/turn.c
   openldap/trunk/libraries/libldap/txn.c
   openldap/trunk/libraries/libldap/unbind.c
   openldap/trunk/libraries/libldap/url.c
   openldap/trunk/libraries/libldap/utf-8-conv.c
   openldap/trunk/libraries/libldap/utf-8.c
   openldap/trunk/libraries/libldap/util-int.c
   openldap/trunk/libraries/libldap/vlvctrl.c
   openldap/trunk/libraries/libldap/whoami.c
   openldap/trunk/libraries/libldap_r/Makefile.in
   openldap/trunk/libraries/libldap_r/ldap_thr_debug.h
   openldap/trunk/libraries/libldap_r/rdwr.c
   openldap/trunk/libraries/libldap_r/rq.c
   openldap/trunk/libraries/libldap_r/thr_cthreads.c
   openldap/trunk/libraries/libldap_r/thr_debug.c
   openldap/trunk/libraries/libldap_r/thr_lwp.c
   openldap/trunk/libraries/libldap_r/thr_nt.c
   openldap/trunk/libraries/libldap_r/thr_posix.c
   openldap/trunk/libraries/libldap_r/thr_pth.c
   openldap/trunk/libraries/libldap_r/thr_stub.c
   openldap/trunk/libraries/libldap_r/thr_thr.c
   openldap/trunk/libraries/libldap_r/threads.c
   openldap/trunk/libraries/libldap_r/tpool.c
   openldap/trunk/libraries/liblunicode/Makefile.in
   openldap/trunk/libraries/liblunicode/ucdata/ucdata.c
   openldap/trunk/libraries/liblunicode/ucdata/ucdata.h
   openldap/trunk/libraries/liblunicode/ucdata/ucgendat.c
   openldap/trunk/libraries/liblunicode/ucdata/ucpgba.c
   openldap/trunk/libraries/liblunicode/ucdata/ucpgba.h
   openldap/trunk/libraries/liblunicode/ucstr.c
   openldap/trunk/libraries/liblunicode/ure/ure.c
   openldap/trunk/libraries/liblunicode/ure/ure.h
   openldap/trunk/libraries/liblunicode/ure/urestubs.c
   openldap/trunk/libraries/liblunicode/utbm/utbm.c
   openldap/trunk/libraries/liblunicode/utbm/utbm.h
   openldap/trunk/libraries/liblunicode/utbm/utbmstub.c
   openldap/trunk/libraries/liblutil/Makefile.in
   openldap/trunk/libraries/liblutil/avl.c
   openldap/trunk/libraries/liblutil/base64.c
   openldap/trunk/libraries/liblutil/csn.c
   openldap/trunk/libraries/liblutil/detach.c
   openldap/trunk/libraries/liblutil/entropy.c
   openldap/trunk/libraries/liblutil/fetch.c
   openldap/trunk/libraries/liblutil/getopt.c
   openldap/trunk/libraries/liblutil/getpass.c
   openldap/trunk/libraries/liblutil/getpeereid.c
   openldap/trunk/libraries/liblutil/hash.c
   openldap/trunk/libraries/liblutil/ldif.c
   openldap/trunk/libraries/liblutil/lockf.c
   openldap/trunk/libraries/liblutil/md5.c
   openldap/trunk/libraries/liblutil/memcmp.c
   openldap/trunk/libraries/liblutil/ntservice.c
   openldap/trunk/libraries/liblutil/passfile.c
   openldap/trunk/libraries/liblutil/passwd.c
   openldap/trunk/libraries/liblutil/ptest.c
   openldap/trunk/libraries/liblutil/sasl.c
   openldap/trunk/libraries/liblutil/setproctitle.c
   openldap/trunk/libraries/liblutil/sha1.c
   openldap/trunk/libraries/liblutil/signal.c
   openldap/trunk/libraries/liblutil/sockpair.c
   openldap/trunk/libraries/liblutil/tavl.c
   openldap/trunk/libraries/liblutil/testavl.c
   openldap/trunk/libraries/liblutil/utils.c
   openldap/trunk/libraries/liblutil/uuid.c
   openldap/trunk/libraries/librewrite/Makefile.in
   openldap/trunk/libraries/librewrite/config.c
   openldap/trunk/libraries/librewrite/context.c
   openldap/trunk/libraries/librewrite/info.c
   openldap/trunk/libraries/librewrite/ldapmap.c
   openldap/trunk/libraries/librewrite/map.c
   openldap/trunk/libraries/librewrite/params.c
   openldap/trunk/libraries/librewrite/parse.c
   openldap/trunk/libraries/librewrite/rewrite-int.h
   openldap/trunk/libraries/librewrite/rewrite-map.h
   openldap/trunk/libraries/librewrite/rewrite.c
   openldap/trunk/libraries/librewrite/rule.c
   openldap/trunk/libraries/librewrite/session.c
   openldap/trunk/libraries/librewrite/subst.c
   openldap/trunk/libraries/librewrite/var.c
   openldap/trunk/libraries/librewrite/xmap.c
   openldap/trunk/servers/Makefile.in
   openldap/trunk/servers/slapd/DB_CONFIG
   openldap/trunk/servers/slapd/Makefile.in
   openldap/trunk/servers/slapd/abandon.c
   openldap/trunk/servers/slapd/aci.c
   openldap/trunk/servers/slapd/acl.c
   openldap/trunk/servers/slapd/aclparse.c
   openldap/trunk/servers/slapd/ad.c
   openldap/trunk/servers/slapd/add.c
   openldap/trunk/servers/slapd/alock.c
   openldap/trunk/servers/slapd/alock.h
   openldap/trunk/servers/slapd/at.c
   openldap/trunk/servers/slapd/attr.c
   openldap/trunk/servers/slapd/ava.c
   openldap/trunk/servers/slapd/back-bdb/Makefile.in
   openldap/trunk/servers/slapd/back-bdb/add.c
   openldap/trunk/servers/slapd/back-bdb/attr.c
   openldap/trunk/servers/slapd/back-bdb/back-bdb.h
   openldap/trunk/servers/slapd/back-bdb/bind.c
   openldap/trunk/servers/slapd/back-bdb/cache.c
   openldap/trunk/servers/slapd/back-bdb/compare.c
   openldap/trunk/servers/slapd/back-bdb/config.c
   openldap/trunk/servers/slapd/back-bdb/dbcache.c
   openldap/trunk/servers/slapd/back-bdb/delete.c
   openldap/trunk/servers/slapd/back-bdb/dn2entry.c
   openldap/trunk/servers/slapd/back-bdb/dn2id.c
   openldap/trunk/servers/slapd/back-bdb/error.c
   openldap/trunk/servers/slapd/back-bdb/extended.c
   openldap/trunk/servers/slapd/back-bdb/filterindex.c
   openldap/trunk/servers/slapd/back-bdb/id2entry.c
   openldap/trunk/servers/slapd/back-bdb/idl.c
   openldap/trunk/servers/slapd/back-bdb/idl.h
   openldap/trunk/servers/slapd/back-bdb/index.c
   openldap/trunk/servers/slapd/back-bdb/init.c
   openldap/trunk/servers/slapd/back-bdb/key.c
   openldap/trunk/servers/slapd/back-bdb/modify.c
   openldap/trunk/servers/slapd/back-bdb/modrdn.c
   openldap/trunk/servers/slapd/back-bdb/nextid.c
   openldap/trunk/servers/slapd/back-bdb/operational.c
   openldap/trunk/servers/slapd/back-bdb/proto-bdb.h
   openldap/trunk/servers/slapd/back-bdb/referral.c
   openldap/trunk/servers/slapd/back-bdb/search.c
   openldap/trunk/servers/slapd/back-bdb/tools.c
   openldap/trunk/servers/slapd/back-bdb/trans.c
   openldap/trunk/servers/slapd/back-dnssrv/Makefile.in
   openldap/trunk/servers/slapd/back-dnssrv/bind.c
   openldap/trunk/servers/slapd/back-dnssrv/compare.c
   openldap/trunk/servers/slapd/back-dnssrv/config.c
   openldap/trunk/servers/slapd/back-dnssrv/init.c
   openldap/trunk/servers/slapd/back-dnssrv/proto-dnssrv.h
   openldap/trunk/servers/slapd/back-dnssrv/referral.c
   openldap/trunk/servers/slapd/back-dnssrv/search.c
   openldap/trunk/servers/slapd/back-hdb/Makefile.in
   openldap/trunk/servers/slapd/back-hdb/back-bdb.h
   openldap/trunk/servers/slapd/back-ldap/Makefile.in
   openldap/trunk/servers/slapd/back-ldap/add.c
   openldap/trunk/servers/slapd/back-ldap/back-ldap.h
   openldap/trunk/servers/slapd/back-ldap/bind.c
   openldap/trunk/servers/slapd/back-ldap/chain.c
   openldap/trunk/servers/slapd/back-ldap/compare.c
   openldap/trunk/servers/slapd/back-ldap/config.c
   openldap/trunk/servers/slapd/back-ldap/delete.c
   openldap/trunk/servers/slapd/back-ldap/extended.c
   openldap/trunk/servers/slapd/back-ldap/init.c
   openldap/trunk/servers/slapd/back-ldap/modify.c
   openldap/trunk/servers/slapd/back-ldap/modrdn.c
   openldap/trunk/servers/slapd/back-ldap/proto-ldap.h
   openldap/trunk/servers/slapd/back-ldap/search.c
   openldap/trunk/servers/slapd/back-ldap/unbind.c
   openldap/trunk/servers/slapd/back-ldif/Makefile.in
   openldap/trunk/servers/slapd/back-ldif/ldif.c
   openldap/trunk/servers/slapd/back-meta/Makefile.in
   openldap/trunk/servers/slapd/back-meta/add.c
   openldap/trunk/servers/slapd/back-meta/back-meta.h
   openldap/trunk/servers/slapd/back-meta/bind.c
   openldap/trunk/servers/slapd/back-meta/candidates.c
   openldap/trunk/servers/slapd/back-meta/compare.c
   openldap/trunk/servers/slapd/back-meta/config.c
   openldap/trunk/servers/slapd/back-meta/conn.c
   openldap/trunk/servers/slapd/back-meta/delete.c
   openldap/trunk/servers/slapd/back-meta/dncache.c
   openldap/trunk/servers/slapd/back-meta/init.c
   openldap/trunk/servers/slapd/back-meta/map.c
   openldap/trunk/servers/slapd/back-meta/modify.c
   openldap/trunk/servers/slapd/back-meta/modrdn.c
   openldap/trunk/servers/slapd/back-meta/proto-meta.h
   openldap/trunk/servers/slapd/back-meta/search.c
   openldap/trunk/servers/slapd/back-meta/suffixmassage.c
   openldap/trunk/servers/slapd/back-meta/unbind.c
   openldap/trunk/servers/slapd/back-monitor/Makefile.in
   openldap/trunk/servers/slapd/back-monitor/back-monitor.h
   openldap/trunk/servers/slapd/back-monitor/backend.c
   openldap/trunk/servers/slapd/back-monitor/bind.c
   openldap/trunk/servers/slapd/back-monitor/cache.c
   openldap/trunk/servers/slapd/back-monitor/compare.c
   openldap/trunk/servers/slapd/back-monitor/conn.c
   openldap/trunk/servers/slapd/back-monitor/database.c
   openldap/trunk/servers/slapd/back-monitor/entry.c
   openldap/trunk/servers/slapd/back-monitor/init.c
   openldap/trunk/servers/slapd/back-monitor/listener.c
   openldap/trunk/servers/slapd/back-monitor/log.c
   openldap/trunk/servers/slapd/back-monitor/modify.c
   openldap/trunk/servers/slapd/back-monitor/operation.c
   openldap/trunk/servers/slapd/back-monitor/operational.c
   openldap/trunk/servers/slapd/back-monitor/overlay.c
   openldap/trunk/servers/slapd/back-monitor/proto-back-monitor.h
   openldap/trunk/servers/slapd/back-monitor/rww.c
   openldap/trunk/servers/slapd/back-monitor/search.c
   openldap/trunk/servers/slapd/back-monitor/sent.c
   openldap/trunk/servers/slapd/back-monitor/thread.c
   openldap/trunk/servers/slapd/back-monitor/time.c
   openldap/trunk/servers/slapd/back-null/Makefile.in
   openldap/trunk/servers/slapd/back-null/null.c
   openldap/trunk/servers/slapd/back-passwd/Makefile.in
   openldap/trunk/servers/slapd/back-passwd/back-passwd.h
   openldap/trunk/servers/slapd/back-passwd/config.c
   openldap/trunk/servers/slapd/back-passwd/init.c
   openldap/trunk/servers/slapd/back-passwd/proto-passwd.h
   openldap/trunk/servers/slapd/back-passwd/search.c
   openldap/trunk/servers/slapd/back-perl/Makefile.in
   openldap/trunk/servers/slapd/back-perl/SampleLDAP.pm
   openldap/trunk/servers/slapd/back-perl/add.c
   openldap/trunk/servers/slapd/back-perl/asperl_undefs.h
   openldap/trunk/servers/slapd/back-perl/bind.c
   openldap/trunk/servers/slapd/back-perl/close.c
   openldap/trunk/servers/slapd/back-perl/compare.c
   openldap/trunk/servers/slapd/back-perl/config.c
   openldap/trunk/servers/slapd/back-perl/delete.c
   openldap/trunk/servers/slapd/back-perl/init.c
   openldap/trunk/servers/slapd/back-perl/modify.c
   openldap/trunk/servers/slapd/back-perl/modrdn.c
   openldap/trunk/servers/slapd/back-perl/perl_back.h
   openldap/trunk/servers/slapd/back-perl/proto-perl.h
   openldap/trunk/servers/slapd/back-perl/search.c
   openldap/trunk/servers/slapd/back-relay/Makefile.in
   openldap/trunk/servers/slapd/back-relay/init.c
   openldap/trunk/servers/slapd/back-relay/op.c
   openldap/trunk/servers/slapd/back-relay/proto-back-relay.h
   openldap/trunk/servers/slapd/back-shell/Makefile.in
   openldap/trunk/servers/slapd/back-shell/add.c
   openldap/trunk/servers/slapd/back-shell/bind.c
   openldap/trunk/servers/slapd/back-shell/compare.c
   openldap/trunk/servers/slapd/back-shell/config.c
   openldap/trunk/servers/slapd/back-shell/delete.c
   openldap/trunk/servers/slapd/back-shell/fork.c
   openldap/trunk/servers/slapd/back-shell/init.c
   openldap/trunk/servers/slapd/back-shell/modify.c
   openldap/trunk/servers/slapd/back-shell/modrdn.c
   openldap/trunk/servers/slapd/back-shell/proto-shell.h
   openldap/trunk/servers/slapd/back-shell/result.c
   openldap/trunk/servers/slapd/back-shell/search.c
   openldap/trunk/servers/slapd/back-shell/searchexample.conf
   openldap/trunk/servers/slapd/back-shell/searchexample.sh
   openldap/trunk/servers/slapd/back-shell/shell.h
   openldap/trunk/servers/slapd/back-shell/unbind.c
   openldap/trunk/servers/slapd/back-sql/Makefile.in
   openldap/trunk/servers/slapd/back-sql/add.c
   openldap/trunk/servers/slapd/back-sql/back-sql.h
   openldap/trunk/servers/slapd/back-sql/bind.c
   openldap/trunk/servers/slapd/back-sql/compare.c
   openldap/trunk/servers/slapd/back-sql/config.c
   openldap/trunk/servers/slapd/back-sql/delete.c
   openldap/trunk/servers/slapd/back-sql/entry-id.c
   openldap/trunk/servers/slapd/back-sql/init.c
   openldap/trunk/servers/slapd/back-sql/modify.c
   openldap/trunk/servers/slapd/back-sql/modrdn.c
   openldap/trunk/servers/slapd/back-sql/operational.c
   openldap/trunk/servers/slapd/back-sql/proto-sql.h
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/ibmdb2/slapd.conf
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_create.sql
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_data.sql
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/slapd.conf
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_create.sql
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_data.sql
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql
   openldap/trunk/servers/slapd/back-sql/rdbms_depend/timesten/slapd.conf
   openldap/trunk/servers/slapd/back-sql/schema-map.c
   openldap/trunk/servers/slapd/back-sql/search.c
   openldap/trunk/servers/slapd/back-sql/sql-wrap.c
   openldap/trunk/servers/slapd/back-sql/util.c
   openldap/trunk/servers/slapd/backend.c
   openldap/trunk/servers/slapd/backglue.c
   openldap/trunk/servers/slapd/backover.c
   openldap/trunk/servers/slapd/bconfig.c
   openldap/trunk/servers/slapd/bind.c
   openldap/trunk/servers/slapd/cancel.c
   openldap/trunk/servers/slapd/ch_malloc.c
   openldap/trunk/servers/slapd/compare.c
   openldap/trunk/servers/slapd/component.c
   openldap/trunk/servers/slapd/component.h
   openldap/trunk/servers/slapd/config.c
   openldap/trunk/servers/slapd/config.h
   openldap/trunk/servers/slapd/connection.c
   openldap/trunk/servers/slapd/controls.c
   openldap/trunk/servers/slapd/cr.c
   openldap/trunk/servers/slapd/ctxcsn.c
   openldap/trunk/servers/slapd/daemon.c
   openldap/trunk/servers/slapd/delete.c
   openldap/trunk/servers/slapd/dn.c
   openldap/trunk/servers/slapd/entry.c
   openldap/trunk/servers/slapd/extended.c
   openldap/trunk/servers/slapd/filter.c
   openldap/trunk/servers/slapd/filterentry.c
   openldap/trunk/servers/slapd/frontend.c
   openldap/trunk/servers/slapd/globals.c
   openldap/trunk/servers/slapd/index.c
   openldap/trunk/servers/slapd/init.c
   openldap/trunk/servers/slapd/ldapsync.c
   openldap/trunk/servers/slapd/limits.c
   openldap/trunk/servers/slapd/lock.c
   openldap/trunk/servers/slapd/main.c
   openldap/trunk/servers/slapd/matchedValues.c
   openldap/trunk/servers/slapd/modify.c
   openldap/trunk/servers/slapd/modrdn.c
   openldap/trunk/servers/slapd/mods.c
   openldap/trunk/servers/slapd/module.c
   openldap/trunk/servers/slapd/mr.c
   openldap/trunk/servers/slapd/mra.c
   openldap/trunk/servers/slapd/nt_svc.c
   openldap/trunk/servers/slapd/oc.c
   openldap/trunk/servers/slapd/oidm.c
   openldap/trunk/servers/slapd/operation.c
   openldap/trunk/servers/slapd/operational.c
   openldap/trunk/servers/slapd/overlays/Makefile.in
   openldap/trunk/servers/slapd/overlays/accesslog.c
   openldap/trunk/servers/slapd/overlays/auditlog.c
   openldap/trunk/servers/slapd/overlays/collect.c
   openldap/trunk/servers/slapd/overlays/dyngroup.c
   openldap/trunk/servers/slapd/overlays/dynlist.c
   openldap/trunk/servers/slapd/overlays/overlays.c
   openldap/trunk/servers/slapd/overlays/pcache.c
   openldap/trunk/servers/slapd/overlays/ppolicy.c
   openldap/trunk/servers/slapd/overlays/refint.c
   openldap/trunk/servers/slapd/overlays/retcode.c
   openldap/trunk/servers/slapd/overlays/rwm.c
   openldap/trunk/servers/slapd/overlays/rwm.h
   openldap/trunk/servers/slapd/overlays/rwmconf.c
   openldap/trunk/servers/slapd/overlays/rwmdn.c
   openldap/trunk/servers/slapd/overlays/rwmmap.c
   openldap/trunk/servers/slapd/overlays/seqmod.c
   openldap/trunk/servers/slapd/overlays/syncprov.c
   openldap/trunk/servers/slapd/overlays/translucent.c
   openldap/trunk/servers/slapd/overlays/unique.c
   openldap/trunk/servers/slapd/overlays/valsort.c
   openldap/trunk/servers/slapd/passwd.c
   openldap/trunk/servers/slapd/phonetic.c
   openldap/trunk/servers/slapd/proto-slap.h
   openldap/trunk/servers/slapd/referral.c
   openldap/trunk/servers/slapd/result.c
   openldap/trunk/servers/slapd/root_dse.c
   openldap/trunk/servers/slapd/sasl.c
   openldap/trunk/servers/slapd/saslauthz.c
   openldap/trunk/servers/slapd/schema.c
   openldap/trunk/servers/slapd/schema/README
   openldap/trunk/servers/slapd/schema/dyngroup.schema
   openldap/trunk/servers/slapd/schema/inetorgperson.schema
   openldap/trunk/servers/slapd/schema/misc.schema
   openldap/trunk/servers/slapd/schema/nis.schema
   openldap/trunk/servers/slapd/schema/openldap.ldif
   openldap/trunk/servers/slapd/schema/openldap.schema
   openldap/trunk/servers/slapd/schema_check.c
   openldap/trunk/servers/slapd/schema_init.c
   openldap/trunk/servers/slapd/schema_prep.c
   openldap/trunk/servers/slapd/schemaparse.c
   openldap/trunk/servers/slapd/search.c
   openldap/trunk/servers/slapd/sets.c
   openldap/trunk/servers/slapd/sets.h
   openldap/trunk/servers/slapd/shell-backends/Makefile.in
   openldap/trunk/servers/slapd/shell-backends/passwd-shell.c
   openldap/trunk/servers/slapd/shell-backends/shellutil.c
   openldap/trunk/servers/slapd/shell-backends/shellutil.h
   openldap/trunk/servers/slapd/sl_malloc.c
   openldap/trunk/servers/slapd/slap.h
   openldap/trunk/servers/slapd/slapacl.c
   openldap/trunk/servers/slapd/slapadd.c
   openldap/trunk/servers/slapd/slapauth.c
   openldap/trunk/servers/slapd/slapcat.c
   openldap/trunk/servers/slapd/slapcommon.c
   openldap/trunk/servers/slapd/slapcommon.h
   openldap/trunk/servers/slapd/slapd.conf
   openldap/trunk/servers/slapd/slapdn.c
   openldap/trunk/servers/slapd/slapi/Makefile.in
   openldap/trunk/servers/slapd/slapi/TODO
   openldap/trunk/servers/slapd/slapi/plugin.c
   openldap/trunk/servers/slapd/slapi/printmsg.c
   openldap/trunk/servers/slapd/slapi/proto-slapi.h
   openldap/trunk/servers/slapd/slapi/slapi.h
   openldap/trunk/servers/slapd/slapi/slapi_dn.c
   openldap/trunk/servers/slapd/slapi/slapi_ext.c
   openldap/trunk/servers/slapd/slapi/slapi_ops.c
   openldap/trunk/servers/slapd/slapi/slapi_overlay.c
   openldap/trunk/servers/slapd/slapi/slapi_pblock.c
   openldap/trunk/servers/slapd/slapi/slapi_utils.c
   openldap/trunk/servers/slapd/slapindex.c
   openldap/trunk/servers/slapd/slappasswd.c
   openldap/trunk/servers/slapd/slaptest.c
   openldap/trunk/servers/slapd/starttls.c
   openldap/trunk/servers/slapd/str2filter.c
   openldap/trunk/servers/slapd/syncrepl.c
   openldap/trunk/servers/slapd/syntax.c
   openldap/trunk/servers/slapd/unbind.c
   openldap/trunk/servers/slapd/user.c
   openldap/trunk/servers/slapd/value.c
   openldap/trunk/servers/slapd/zn_malloc.c
   openldap/trunk/tests/Makefile.in
   openldap/trunk/tests/README
   openldap/trunk/tests/data/acl.out.master
   openldap/trunk/tests/data/certificate.tls
   openldap/trunk/tests/data/ditcontentrules.conf
   openldap/trunk/tests/data/do_search.0
   openldap/trunk/tests/data/dynlist.out
   openldap/trunk/tests/data/meta.out
   openldap/trunk/tests/data/proxycache.out
   openldap/trunk/tests/data/slapd-aci.conf
   openldap/trunk/tests/data/slapd-acl.conf
   openldap/trunk/tests/data/slapd-cache-master.conf
   openldap/trunk/tests/data/slapd-chain1.conf
   openldap/trunk/tests/data/slapd-chain2.conf
   openldap/trunk/tests/data/slapd-component.conf
   openldap/trunk/tests/data/slapd-deltasync-master.conf
   openldap/trunk/tests/data/slapd-deltasync-slave.conf
   openldap/trunk/tests/data/slapd-dn.conf
   openldap/trunk/tests/data/slapd-dynlist.conf
   openldap/trunk/tests/data/slapd-emptydn.conf
   openldap/trunk/tests/data/slapd-glue-ldap.conf
   openldap/trunk/tests/data/slapd-glue-syncrepl1.conf
   openldap/trunk/tests/data/slapd-glue-syncrepl2.conf
   openldap/trunk/tests/data/slapd-glue.conf
   openldap/trunk/tests/data/slapd-idassert.conf
   openldap/trunk/tests/data/slapd-ldapglue.conf
   openldap/trunk/tests/data/slapd-ldapgluegroups.conf
   openldap/trunk/tests/data/slapd-ldapgluepeople.conf
   openldap/trunk/tests/data/slapd-limits.conf
   openldap/trunk/tests/data/slapd-master.conf
   openldap/trunk/tests/data/slapd-meta.conf
   openldap/trunk/tests/data/slapd-nis-master.conf
   openldap/trunk/tests/data/slapd-ppolicy.conf
   openldap/trunk/tests/data/slapd-proxycache.conf
   openldap/trunk/tests/data/slapd-pw.conf
   openldap/trunk/tests/data/slapd-ref-slave.conf
   openldap/trunk/tests/data/slapd-referrals.conf
   openldap/trunk/tests/data/slapd-refint.conf
   openldap/trunk/tests/data/slapd-relay.conf
   openldap/trunk/tests/data/slapd-retcode.conf
   openldap/trunk/tests/data/slapd-schema.conf
   openldap/trunk/tests/data/slapd-sql-syncrepl-master.conf
   openldap/trunk/tests/data/slapd-sql.conf
   openldap/trunk/tests/data/slapd-syncrepl-master.conf
   openldap/trunk/tests/data/slapd-syncrepl-slave-persist1.conf
   openldap/trunk/tests/data/slapd-syncrepl-slave-persist2.conf
   openldap/trunk/tests/data/slapd-syncrepl-slave-persist3.conf
   openldap/trunk/tests/data/slapd-syncrepl-slave-refresh1.conf
   openldap/trunk/tests/data/slapd-syncrepl-slave-refresh2.conf
   openldap/trunk/tests/data/slapd-translucent-local.conf
   openldap/trunk/tests/data/slapd-translucent-remote.conf
   openldap/trunk/tests/data/slapd-unique.conf
   openldap/trunk/tests/data/slapd-valsort.conf
   openldap/trunk/tests/data/slapd-whoami.conf
   openldap/trunk/tests/data/slapd.conf
   openldap/trunk/tests/data/slapd2.conf
   openldap/trunk/tests/data/sql-read.out
   openldap/trunk/tests/data/sql-write.out
   openldap/trunk/tests/data/test.schema
   openldap/trunk/tests/progs/Makefile.in
   openldap/trunk/tests/progs/slapd-addel.c
   openldap/trunk/tests/progs/slapd-bind.c
   openldap/trunk/tests/progs/slapd-modify.c
   openldap/trunk/tests/progs/slapd-modrdn.c
   openldap/trunk/tests/progs/slapd-read.c
   openldap/trunk/tests/progs/slapd-search.c
   openldap/trunk/tests/progs/slapd-tester.c
   openldap/trunk/tests/run.in
   openldap/trunk/tests/scripts/acfilter.sh
   openldap/trunk/tests/scripts/all
   openldap/trunk/tests/scripts/conf.sh
   openldap/trunk/tests/scripts/defines.sh
   openldap/trunk/tests/scripts/passwd-search
   openldap/trunk/tests/scripts/relay
   openldap/trunk/tests/scripts/sql-all
   openldap/trunk/tests/scripts/sql-test000-read
   openldap/trunk/tests/scripts/sql-test001-concurrency
   openldap/trunk/tests/scripts/sql-test900-write
   openldap/trunk/tests/scripts/sql-test901-syncrepl
   openldap/trunk/tests/scripts/start-server
   openldap/trunk/tests/scripts/start-server-nolog
   openldap/trunk/tests/scripts/start-server2
   openldap/trunk/tests/scripts/start-server2-nolog
   openldap/trunk/tests/scripts/startup_nis_ldap_server.sh
   openldap/trunk/tests/scripts/test000-rootdse
   openldap/trunk/tests/scripts/test001-slapadd
   openldap/trunk/tests/scripts/test002-populate
   openldap/trunk/tests/scripts/test003-search
   openldap/trunk/tests/scripts/test004-modify
   openldap/trunk/tests/scripts/test005-modrdn
   openldap/trunk/tests/scripts/test006-acls
   openldap/trunk/tests/scripts/test008-concurrency
   openldap/trunk/tests/scripts/test009-referral
   openldap/trunk/tests/scripts/test010-passwd
   openldap/trunk/tests/scripts/test011-glue-slapadd
   openldap/trunk/tests/scripts/test012-glue-populate
   openldap/trunk/tests/scripts/test013-language
   openldap/trunk/tests/scripts/test014-whoami
   openldap/trunk/tests/scripts/test015-xsearch
   openldap/trunk/tests/scripts/test016-subref
   openldap/trunk/tests/scripts/test017-syncreplication-refresh
   openldap/trunk/tests/scripts/test018-syncreplication-persist
   openldap/trunk/tests/scripts/test019-syncreplication-cascade
   openldap/trunk/tests/scripts/test020-proxycache
   openldap/trunk/tests/scripts/test021-certificate
   openldap/trunk/tests/scripts/test022-ppolicy
   openldap/trunk/tests/scripts/test023-refint
   openldap/trunk/tests/scripts/test024-unique
   openldap/trunk/tests/scripts/test025-limits
   openldap/trunk/tests/scripts/test026-dn
   openldap/trunk/tests/scripts/test027-emptydn
   openldap/trunk/tests/scripts/test028-idassert
   openldap/trunk/tests/scripts/test029-ldapglue
   openldap/trunk/tests/scripts/test030-relay
   openldap/trunk/tests/scripts/test031-component-filter
   openldap/trunk/tests/scripts/test032-chain
   openldap/trunk/tests/scripts/test033-glue-syncrepl
   openldap/trunk/tests/scripts/test034-translucent
   openldap/trunk/tests/scripts/test035-meta
   openldap/trunk/tests/scripts/test036-meta-concurrency
   openldap/trunk/tests/scripts/test037-manage
   openldap/trunk/tests/scripts/test038-retcode
   openldap/trunk/tests/scripts/test039-glue-ldap-concurrency
   openldap/trunk/tests/scripts/test040-subtree-rename
   openldap/trunk/tests/scripts/test041-aci
   openldap/trunk/tests/scripts/test042-valsort
   openldap/trunk/tests/scripts/test043-delta-syncrepl
   openldap/trunk/tests/scripts/test044-dynlist
Log:
merge OpenLDAP 2.4.7 onto the trunk

/svn/pkg-openldap/hooks/commit-email.pl: `/usr/bin/svnlook diff /svn/pkg-openldap -r 892' failed with this output:
Modified: openldap/trunk/ANNOUNCEMENT
===================================================================
--- openldap/trunk/ANNOUNCEMENT	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/ANNOUNCEMENT	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,35 +1,42 @@
-A N N O U N C E M E N T -- OpenLDAP 2.3
+A N N O U N C E M E N T -- OpenLDAP 2.4
 
     The OpenLDAP Project is pleased to announce the availability
-    of OpenLDAP Software 2.3, a suite of the Lightweight Directory
+    of OpenLDAP Software 2.4, a suite of the Lightweight Directory
     Access Protocol (v3) servers, clients, utilities, and
     development tools.
 
     This release contains the following major enhancements:
 
         * Slapd(8) enhancements
-            - Updated slapd "overlay" interface, and several
-              example (and mostly experimental) overlays.
-            - Updated LDAP "sync" Engine with replication support,
-              provider now an "overlay"
-            - Numerous access control enhancements, including
-              experimental "don't disclose on error" capability
-            - Configuration backend
-        * LDAPv3 extensions, including:
-            - LDAP Password Policy
-            - LDAP Component Matching (requires OpenLDAP snacc)
-            - LDAP Modify Increment
+            - Syncrepl enhancements, including push-mode and
+              Multi-Master support
+            - Dynamic configuration enhancements, including
+              online schema editing and full access control
+            - Dynamic monitoring enhancements, including
+              cache usage information
+        * New overlays
+            - Attribute value constraints
+            - Dynamic Directory Services (RFC2589)
+            - Reverse Group Membership maintenance (memberof)
+        * Clients and tools
+            - Full support of request/response controls
+            - New ldapexop tool for arbitrary extend operations
+            - Support of DNS SRV records for default server
+        * Significant performance enhancements throughout
+            the client and server code base
+        * Multiple new features in libldap and liblber
+        * Expanded documentation
+            - Function-complete manual pages
+            - Numerous new examples in the Admin Guide
 
     This release includes the following major components:
 
         * slapd - a stand-alone LDAP directory server
-        * slurpd - a stand-alone LDAP replication server
         * -lldap - a LDAP client library
         * -llber - a lightweight BER/DER encoding/decoding library
         * LDIF tools - data conversion tools for use with slapd
         * LDAP tools - A collection of command line LDAP utilities
         * Admin Guide, Manual Pages - associated documentation
-        * SNACC - ASN.1 development tools for OpenLDAP
 
     In addition, there are some contributed components:
 
@@ -40,9 +47,9 @@
 ACKNOWLEDGEMENTS
 
     OpenLDAP Software is developed by the OpenLDAP Project.  The
-    Project consists of a team of volunteers whose use the
+    Project consists of a team of volunteers who use the
     Internet to coordinate their activities.  The Project is
-    managed by the OpenLDAP Foundation.
+    an organized activity of the OpenLDAP Foundation.
 
     OpenLDAP Software is derived from University of Michigan LDAP,
     release 3.3.
@@ -51,7 +58,7 @@
 AVAILABILITY
 
     This software is available under the OpenLDAP Public License,
-    an non-restrictive, "free", open-source license.  For download
+    an non-restrictive, "free", open-source license.  Download
     information is available at:
 
         http://www.OpenLDAP.org/software/download/
@@ -73,7 +80,7 @@
         http://www.openldap.org/faq/
 
     In addition, there are also a number of discussion lists
-    related OpenLDAP Software.  A list of mailing lists is
+    related to OpenLDAP Software.  A list of mailing lists is
     available at:
 
         http://www.OpenLDAP.org/lists/
@@ -94,7 +101,7 @@
     platforms including Darwin, FreeBSD, Linux, NetBSD, OpenBSD
     and most commercial UNIX systems.  The release has also been
     ported (in part or in whole) to other platforms including
-    Apple MacOS X, IBM zOS, and Microsoft Windows 2000.
+    Apple MacOS X, IBM zOS, and Microsoft Windows NT/2000/etc.
 
 ---
 OpenLDAP is a registered trademark of the OpenLDAP Foundation.

Modified: openldap/trunk/CHANGES
===================================================================
--- openldap/trunk/CHANGES	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/CHANGES	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,869 +1,47 @@
-OpenLDAP 2.3 Change Log
+OpenLDAP 2.4 Change Log
 
-OpenLDAP 2.3.39 Release (2007/10/26)
-	Fixed slapd database/overlay config conflict (ITS#4848)
-	Fixed slapd password_hash config order (ITS#5082)
-	Fixed slapd slap_mods_check bug (ITS#5119)
-	Fixed slapd ACL sets memory handling (ITS#4860,ITS#4873)
-	Fixed slapd ordered values add normalization issue (ITS#5136)
-	Fixed slapd-bdb DB_CONFIG conversion bug (ITS#5118)
-	Fixed slapd-ldap search control parsing (ITS#5138)
-	Fixed slapd-ldap SASL idassert w/o authcId
-	Fixed slapd-ldif directory separators in DN (ITS#5172)
-	Fixed slapd-meta conn caching on bind failure (ITS#5154)
-	Fixed slapd-meta bind timeout assertion (ITS#5185)
-	Fixed slapd-sql concurrency issue (ITS#5095)
-	Fixed slapo-chain double-free (ITS#5137)
-	Fixed slapo-pcache and -rwm interaction fix (ITS#4991) 
-	Fixed slapo-pcache non-null terminated array crasher (ITS#5163)
-	Fixed slapo-rwm modlist handling (ITS#5124)
-	Fixed slapo-rwm UUID in filter (ITS#5168)
-	Fixed sasl SASL_SSF_EXTERNAL type (ITS#3864)
-	Fixed liblber Windows x64 portability (ITS#5105)
-	Fixed libldap ppolicy control creation (ITS#5103)
+OpenLDAP 2.4.7 Release (2007/12/14)
+	Added slapd ordered indexing of integer attributes (ITS#5239)
+	Fixed slapd paged results control handling (ITS#5191)
+	Fixed slapd sasl-host parsing (ITS#5209)
+	Fixed slapd filter normalization (ITS#5212)
+	Fixed slapd multiple suffix checking (ITS#5186)
+	Fixed slapd paged results handling when using rootdn (ITS#5230)
+	Fixed slapd syncrepl presentlist handling (ITS#5231)
+	Fixed slapd core schema 'c' definition for RFC4519 (ITS#5236)
+	Fixed slapd 3-way Multi-Master Replication (ITS#5238)
+	Fixed slapd hash collisions in index slots (ITS#5183)
+	Fixed slapd replication of dSAOperation attributes (ITS#5268)
+	Fixed slapadd contextCSN updating (ITS#5225)
+	Fixed slapd-bdb/hdb to report and fail on internal errors (ITS#5232)
+	Fixed slapd-bdb/hdb dn2entry lock bug (ITS#5257)
+	Fixed slapd-bdb/hdb dn2id lock bug (ITS#5262)
+	Fixed slapd-hdb caching on rename ops (ITS#5221)
+	Fixed slapo-accesslog abandoned op cleanup (ITS#5161)
+	Fixed slapo-dds deleting from nonexistent db (ITS#5267)
+	Fixed slapo-memberOf deleted values saving (ITS#5258)
+	Fixed slapo-pcache op->o_abandon handling (ITS#5187)
+	Fixed slapo-ppolicy single password check on modify (ITS#5146)
+	Fixed slapo-ppolicy internal search (ITS#5235)
+	Fixed slapo-syncprov refresh and persist cookie sending (ITS#5210)
+	Fixed slapo-syncprov ignore invalid cookies (ITS#5211)
+	Fixed slapo-translucent interaction with slapo-rwm (ITS#4889)
+	Updated contrib addpartial module (ITS#3593)
 	Build Environment
-		Fixed termios macro check (ITS#4880)
-		Updated Makefiles
+		Fixed liblber socket library linking (ITS#5224)
+		Fixed Windows slapd.def rules (ITS#5215)
 	Documentation
-		Fixed slapd-bdb(5) note about dbconfig directives (ITS#5134)
-		Added slapd-sql(5) empty oc mapping workaround (ITS#4785)
-		Added max-depth/return-error to slapo-chain(5)
-		slapadd/slapindex note about file ownership (ITS#5166)
-		slapcat note about using against running slapd (ITS#5028)
-		Fixed Admin Guide URL in README (ITS#5107)
+		Fixed grammar errors (ITS#5223)
+		Refint overlay doc contribution (ITS#5217)
+		Dynamic Lists doc contribution to the admin guide (ITS#5216)
+		Fixed ldappasswd(1) and ldapmodify(1) typos (ITS#5269)
+		Fixed domain factor typos (ITS#5237)
+		Fixed slapd.conf(5) maxderefdepth default value typo (ITS#5200)
+		Clarified slapd.conf(5) limits issues in syncrepl (ITS#5243)
+		Fixed slapd-config(5) maxderefdepth default value typo (ITS#5200)
+		Patches for minor typos in man pages (ITS#5228)
+		admin24/replication.sdf spelling (ITS#5270)
 
-OpenLDAP 2.3.38 Release (2007/08/20)
-	Fixed slapadd check for ';binary' when required (ITS#5071)
-	Fixed slapd select_backend/ManageDSAit (ITS#4986)
-	Fixed slapd integer/pointer types and overflow (ITS#5035)
-	Fixed slapd AVA_Sort on multivalued RDNs (ITS#5057)
-	Fixed slapd LDIF parsing error handling (ITS#5090)
-	Fixed slapd syncrepl searchbase scope (ITS#5073)
-	Fixed slapd-bdb missing index warning (ITS#5037)
-	Fixed slapd-bdb Quick index for ID 0 (ITS#5052)
-	Fixed slapd-bdb spurious empty DN warnings during add (ITS#5079)
-	Fixed slapd-hdb slapacl behavior (ITS#5087)
-	Fixed slapd-relay configuration (ITS#4322,ITS#4340)
-	Fixed slapd-sql structuralObjectClass issue (ITS#5088)
-	Fixed slapo-ppolicy double-free on shutdown (ITS#5094)
-	Fixed slapo-rwm/slapd-meta dup attrs after mapping (ITS#5091)
-	Fixed slapo-syncprov uninit'd vars (ITS#5048,#5049)
-	Fixed libldap ldap_add_result_entry (ITS#5056)
-	Added client tools support for ppolicy response (ITS#5061)
-	Removed lint
-	Build Environment
-		Fixed macro definition of open() in glibc 2.6 (ITS#5075)
-	Documentation
-		aspell --lang=en_US -c <manpage> (ITS#5076)
-		Debug messages cleaned up (ITS#5085)
 
-OpenLDAP 2.3.37 Release (2007/07/20)
-	Fixed slapd-glue/syncprov interaction (ITS#4623)
-	Fixed slapd-ldap search reference crash (ITS#5025)
-	Fixed slapd-ldbm crash on Compare op (ITS#5044)
-	Fixed slapo-rwm searchFilter double free (ITS#5043)
-	Clarified slapd-perl SampleLDAP.pm usage (ITS#4995)
-	Documentation
-		Fixed slapd.conf(5) for default loglevel (ITS#5027)
-
-OpenLDAP 2.3.36 Release (2007/06/17)
-	Fixed slapd error code on Windows (ITS#4945, #4606)
-	Fixed slapd mutex bug after failed startup (ITS#4957)
-	Fixed slapd sasl failed Bind bug (ITS#4954)
-	Fixed slapd sasl ssf logging (ITS#5001)
-	Fixed slapd tool op init (ITS#4911)
-	Fixed slapd-bdb no-op crasher (ITS#4925)
-	Fixed slapd-config olcLogLevel (ITS#4949)
-	Fixed slapd-config olcModuleLoad replace (ITS#4921,ITS#4923)
-	Fixed slapd-relay crash when no database can be selected (ITS#4958)
-	Fixed slapo-chain RFC3062 passwd exop handling (ITS#4964)
-	Fixed slapo-dynlist multiple group/url[/member] config (ITS#4989)
-	Fixed slapo-pcache handling of abandoned Operations (#5015)
-	Fixed slapo-pcache and -rwm interaction (ITS#4991)
-	Fixed slapo-ppolicy pwdReset/pwdMinAge (ITS#4970)
-	Fixed slapo-ppolicy control cleanup from ITS#4665
-	Fixed slapo-syncprov cookie parsing error (ITS#4977)
-	Fixed slapo-valsort crash on delete op (ITS#4966)
-	Fixed liblber compilation problem (ITS#5007)
-	Fixed libldap referral chasing loop (ITS#4955)
-	Fixed libldap response code handling on rebind (ITS#4924)
-	Fixed libldap SASL_MAX_BUFF_SIZE (ITS#4935)
-	Fixed libldap cldap assert (ITS#4992)
-	Fixed libldap_r thread debug issues (ITS#4972)
-	Fixed liblutil reading passwd from pipe (ITS#4875)
-	Fixed ldap client usage typo (ITS#4939)
-	Build Environment
-		Fixed --disable-overlays Makefile problem (ITS#4988)
-		Fixed HP-UX socklen_t problem (ITS#4629)
-	Documentation
-		Updated ldapsearch(1) with details on -C option (ITS#5009)
-		Updated slapadd(8) with details on -s option
-		Fixed slapd.conf(5) for correct loglevel packets (ITS#5011)
-		Fixed slapo-ppolicy(5) permanent pwdAccountLockedTime (ITS#4978)
-
-OpenLDAP 2.3.35 Release (2007/04/09)
-	Fixed ldapmodify to use correct memory free functions (ITS#4901)
-	Fixed slapd acl set minor typo (ITS#4874)
-	Fixed slapd entry consistency check in str2entry2 (ITS#4852)
-	Fixed slapd ldapi:// credential issue (ITS#4893)
-	Fixed slapd str2anlist handling of undefined attrs/OCs (ITS#4854)
-	Fixed slapd syncrepl delta-sync modlist free (ITS#4904)
-	Added slapd syncrepl retry logging (ITS#4915)
-	Fixed slapd zero-length IA5string handling (ITS#4823)
-	Fixed slapd-bdb/hdb startup with missing shm env (ITS#4851)
-	Fixed slapd-ldap/meta consistency in referral proxying (ITS#4861)
-	Fixed slapd-ldap bind cleanup in case of unauthorized idassert
-	Fixed slapd-meta search cleanup
-	Fixed slapd-meta/slapo-rwm filter mapping
-	Fixed slapd-sql subtree shortcut (ITS#4856)
-	Fixed slapo-dynlist crasher (ITS#4891)
-	Fixed slapo-refint config message (ITS#4853)
-	Fixed libldap time_t signedness (ITS#4872)
-	Fixed libldap_r tpool reset (ITS#4855,#4899)
-	Documentation
-		Misc Doc fixes (ITS#4863, ITS#4877, ITS#4885, ITS#4897)
-
-OpenLDAP 2.3.34 Release (2007/02/16)
-	Fixed libldap missing get_option(TLS CipherSuite) (ITS#4815)
-	Fixed ldapmodify printing error from ldap_result() (ITS#4812)
-	Fixed slapadd LDIF parsing (ITS#4817)
-	Fixed slapd libltdl link ordering (ITS#4830)
-	Fixed slapd syncrepl memory leaks (ITS#4805)
-	Fixed slapd dynacl/ACI compatibility with 2.1
-	Fixed slapd-bdb/hdb be_entry_get with aliases/referrals (ITS#4810)
-	Fixed slapd-ldap more response handling bugs (ITS#4782)
-	Fixed slapd-ldap C-API code tests (ITS#4808)
-	Fixed slapd-monitor NULL printf (ITS#4811)
-	Fixed slapo-chain spurious additional info in response (ITS#4828)
-	Fixed slapo-syncprov presence list (ITS#4813)
-	Fixed slapo-syncprov contextCSN checkpoint again (ITS#4720)
-	Added slapo-ppolicy cn=config support (ITS#4836)
-	Added slapo-auditlog cn=config support
-	Fixed slapi late initialization (ITS#4468)
-	Build environment
-		Added Berkeley DB 4.5 detection
-	Documentation
-		Note slapo-dynlist interaction with manageDSAit (ITS#4831)
-
-OpenLDAP 2.3.33 Release (2007/01/17)
-	Fixed slapd syncrepl error logging with delta-syncrepl
-	Fixed slapd-ldap/meta privileged conn caching (ITS#4547)
-	Fixed slapd-ldap chase-referrals switch (ITS#4557)
-	Fixed slapd-ldap bind behavior when idassert is always used (ITS#4781)
-	Fixed slapd-ldap response handling bugs (ITS#4782)
-	Fixed slapd-ldap idassert mode=self anonymous ops (ITS#4798)
-	Fixed slapd-ldap/meta privileged connections handling (ITS#4791)
-	Fixed slapd-meta retrying (ITS#4594, 4762)
-	Fixed slapo-chain referral DN use (ITS#4776)
-	Fixed slapo-dynlist dangling pointer after entry free (ITS#4801)
-	Fixed libldap ldap_pvt_put_filter syntax checks (ITS#4648)
-	Documentation
-		Fixed reference to deprecated stmt in slapacl(8) (ITS#4803)
-
-OpenLDAP 2.3.32 Release (2007/01/04)
-	Fixed slapd add redundant duplicate value check (ITS#4600)
-	Fixed slapd ACL set memleak (ITS#4780)
-	Fixed slapd syncrepl shutdown hang (ITS#4790)
-	Fixed slapd connection_get race condition on Windows (ITS#4793)
-	Fixed slapd values return filter control leak (ITS#4794)
-	Fixed slapd-sql Debug typo (ITS#4784)
-	Fixed slapo-rwm parameter handling (ITS#3971, 4458, 4638, 4689)
-	Documentation
-		Fixed reference to deprecated option in admin guide (ITS#4795)
-
-OpenLDAP 2.3.31 Release (2006/12/17)
-	Fixed libldap unchased referral leak (ITS#4545)
-	Fixed libldap tls callback (ITS#4723)
-	Fixed liblutil ldif file: URL parsing
-	Fixed slapd syncrepl logging (ITS#4755)
-	Fixed slapd group ACL caching when proxyAuthz'ing (ITS#4760)
-	Fixed slapd "group" authz default member parsing (ITS#4761)
-	Fixed slapd uninitialized sd_actives array (ITS#4765)
-	Fixed slapd DN parsing in bindconf_parse (ITS#4766)
-	Fixed slapd conditional in macro argument (ITS#4769)
-	Fixed slapd send_search_reference should propagate errors
-	Fixed slapd memleak on failed bind (ITS#4771)
-	Fixed slapd schema preparation case to match RFCs (ITS#4764)
-	Fixed slapd kbind buffer overflow condition (ITS#4775)
-	Fixed slapd connections_shutdown assert
-	Fixed slapd glue parent/sub db overlay nesting (ITS#4615)
-	Fixed slapd-bdb/hdb/ldbm slap_add_opattrs error checking
-	Fixed slapd-bdb/hdb setting up tool threads when no indices specified
-	Fixed slapd-perl interpreter context (ITS#4751)
-	Fixed slapo-syncprov to complain if defined outside of a database
-	Fixed test021 modify ops to be syntactically correct
-	Fixed contrib smbk5pwd, check kadm5 init result
-	Documentation
-		Fixed typo in slapo-retcode(5) man page (ITS#4753)
-		Fixed syncrepl searchbase note (ITS#4540)
-		Added syncrepl starttls in the admin guide (ITS#4510)
-		Fixed reference to deprecated function in ldap_parse_result(3)
-
-OpenLDAP 2.3.30 Release (2006/11/14)
-	Fixed slapd authzTo/authzFrom URL matching (ITS#4744)
-	Fixed slapd syncrepl consumer memory leaks (ITS#4746)
-	Fixed slapd-hdb livelock (ITS#4738)
-	Fixed slapo-ppolicy external quality check (ITS#4741)
-	Documentation
-		Fixed ldapsearch(1) man page acknowledgement (ITS#4743)
-
-OpenLDAP 2.3.29 Release (2006/11/10)
-	Fixed liblber/libldap error codes on Windows (ITS#4606)
-	Fixed libldap string length assert (ITS#4740)
-	Fixed liblunicode case mapping (ITS#4724)
-	Fixed slapd ldapi:// socket permissions (ITS#4709)
-	Fixed slapd c_writewaiters assert (ITS#4696,4736)
-	Fixed slapo-accesslog purge contextCSN bug (ITS#4704)
-	Fixed slapo-accesslog modify/replace bug (ITS#4728)
-	Fixed slapo-dynlist leaks (ITS#4664)
-	Fixed slapo-ppolicy leaks (ITS#4665)
-	Fixed slapo-syncprov deadlock (ITS#4720)
-	Build environment
-		Added selection of ODBC (ITS#4735)
-	Documentation
-		Fixed slapd-ldap/meta(5) rebind-as-user usage (ITS#4715)
-		Fixed slapd-ldap/meta(5) missing network-timeout (ITS#4718)
-
-OpenLDAP 2.3.28 Release (2006/10/21)
-	Fixed libldap ldap.conf max line length (ITS#4669)
-	Fixed libldap use keepalive for syncrepl (ITS#4708)
-	Fixed liblutil LDIF CR/LF parsing bug (ITS#4635)
-	Fixed librewrite LDAP map parsing bug
-	Fixed librewrite map double free bug
-	Added ldapsearch bad filter pattern check (ITS#4647)
-	Fixed slapd global access controls initialization (ITS#4654)
-	Fixed slapd setting c_sasl_bindop only on SASL binds
-	Fixed slapd max line length issue (ITS#4651)
-	Fixed slapd return code not being propagated (ITS#4565)
-	Fixed slapd integerBitAndMatch (ITS#4672)
-	Fixed slapd syncrepl modrdn new superior (ITS#4695)
-	Fixed slapd-ldap retry with idassert (ITS#4686)
-	Fixed slapd-meta DN massage error code handling (ITS#4711)
-	Fixed slapd-monitor locking with scope "subordinate" (ITS#4668)
-	Fixed slapd-perl deletes (ITS#2612)
-	Fixed slapd-perl backend initialization (ITS#4358)
-	Fixed slapd-perl finding interpreter inside a thread (ITS#4358)
-	Fixed slapo-ppolicy pwdChangedTime behavior (ITS#4692)
-	Fixed slapo-translucent ldapmodify crash (ITS#4673)
-	Documentation
-		Updated ldapsearch(1) options (ITS#4371,4526,4647)
-		Fixed slapd.access(5) non-optional dn= error (ITS#4522)
-
-OpenLDAP 2.3.27 Release (2006/08/19)
-	Fixed libldap dangling pointer issue (previous fix was broken) (ITS#4405)
-	Fixed slapd-sql noop handling (ITS#4563)
-
-OpenLDAP 2.3.26 Release (2006/08/17)
-	Fixed libldap dnssrv bug with "not present" positive statement (ITS#4610)
-	Fixed libldap dangling pointer issue (ITS#4405)
-	Fixed slapd incorrect rebuilding of replica URI (ITS#4633)
-	Fixed slapd DN X.509 normalization crash (ITS#4644)
-	Fixed slapd-monitor operations order via callbacks (ITS#4631)
-	Fixed slapd-sql undefined filter handling (ITS#4604)
-	Fixed slapo-accesslog purge task during shutdown
-	Fixed slapo-ppolicy handling of default policy (ITS#4634)
-	Fixed slapo-ppolicy logging verbosity when using default policy
-	Fixed slapo-syncprov incomplete sync on restart issues (ITS#4622)
-
-OpenLDAP 2.3.25 Release (2006/08/01)
-	Fixed liblber ber_bvreplace_x argument checks
-	Add libldap_r TLS concurrency workaround (ITS#4583)
-	Fixed liblutil password length bug
-	Add slapd glue/subordinate conflict check (ITS#4614)
-	Fixed slapd acl selfwrite bug (ITS#4587)
-	Fixed slapd bconfig "require" and "none" handling (ITS#4574)
-	Fixed slapd bconfig segfault when ldapadding new schema entries
-	Fixed slapd syncrepl no rootdn bug (ITS#4582)
-	Fixed slapd syncrepl contextCSN issue (ITS#4622)
-	Fixed slapd-bdb/hdb lock bug with virtual root (ITS#4572)
-	Fixed slapd-bdb/hdb modrdn new entry disappearing bug (ITS#4616)
-	Fixed slapd-bdb/hdb cache job issue
-	Fixed slapo-syncprov need new CSN with delete syncID sets (ITS#4534)
-	Fixed slapo-syncprov startup when lastmod is off (ITS#4613)
-	Fixed slapo-accesslog cn=config purge bug (ITS#4595)
-	Fixed slapo-auditlog DB initialization
-	Fixed slapo-ppolicy password hashing bug (ITS#4575)
-	Fixed slapo-ppolicy password modify pwdMustChange reset bug (ITS#4576)
-	Fixed slapo-ppolicy control can be critical (ITS#4596)
-	Fixed slapo-retcode logical and bug
-	Fixed slapo-syncprov DEL propagation bug (ITS#4589)
-	Fixed slurpd ldaps:// default port bug (ITS#4580)
-	Build environment
-		Fix configure winsock.h detection for Cygwin (ITS#4621)
-		Fix configure GMP detection (ITS#4608)
-		Updated test006-acls to test selfwrite access (ITS#4587)
-	Documentation
-		Fixed ldapsearch(1) formatting (ITS#4619)
-		Updated slapd.conf(5) RFC references
-		Updated slapd.conf(5) lastmod discussion (ITS#4613)
-		Updated slapd.conf(5) "require" and "none" handling (ITS#4574)
-		Added slapd.conf(5) access control note to authz-regexp discussion
-		Updated slapo-syncprov(5) to clarify SyncProv and syncrepl diffs
-
-OpenLDAP 2.3.24 Release (2006/05/30)
-	Fixed slapd syncrepl timestamp bug (delta-sync/cascade) (ITS#4567)
-	Fixed slapd-bdb/hdb non-root users adding suffix/root entries (ITS#4552)
-	Re-fixed slapd-ldap improper free bug in exop (ITS#4550)
-	Fixed slapd-ldif assert bug (ITS#4568)
-	Fixed slapo-syncprov crash under glued database (ITS#4562)
-
-OpenLDAP 2.3.23 Release (2006/05/17)
-	Fixed slapd-ldap improper free bug (ITS#4550)
-
-OpenLDAP 2.3.22 Release (2006/05/15)
-	Fixed libldap referral input destroy issue (ITS#4533)
-	Fixed libldap ldap_sort_entries tail bug (ITS#4536)
-	Fixed libldap default connection concurrency issue (ITS#4541)
-	Fixed libldap_r thread debug missing break
-	Fixed libldap_r tpool cleanup
-	Fixed liblutil strtoul(3) usage (ITS#4503)
-	Fixed liblutil time resolution issue (ITS#4514)
-	Updated ldapdelete(1) to stdout bug (ITS#4453)
-	Updated ldapsearch(1) BASE output (ITS#4504)
-	Fixed slapd backglue issue (ITS#4529)
-	Fixed slapd cn=config (ITS#4512)
-	Fixed slapd cn=config ACL application fix
-	Fixed slapd cn=config olcLimits (ITS#4515)
-	Fixed slapd dynacl tgrant/tdeny initialization
-	Fixed slapd runqueue use of freed memory (ITS#4517)
-	Fixed slapd slap_send_ldap_result bug (ITS#4499)
-	Fixed slapd thread pool init issue (ITS#4513)
-	Added slapd syncrepl mandatory searchbase check
-	Fixed slapd-bdb/hdb pre/post-read freeing (ITS#4532)
-	Fixed slapd-bdb/hdb pre/post-read unavailable issue (ITS#4538)
-	Fixed slapd-bdb/hdb referral issue (ITS#4548)
-	Fixed slapd-hdb IDL sort issue (ITS#4531)
-	Fixed slapd-ldap proxyAuthz of bound identity/override (ITS#4497)
-	Fixed slapd-ldap/meta protocol version propagation (ITS#4488)
-	Fixed slapd-ldap fd cleanup (ITS#4474)
-	Fixed slapd-ldif deadlock (ITS#4500)
-	Fixed slapd-shell lutil_atoi issue (ITS#4495)
-	Fixed slapadd cn=config issue (ITS#4194)
-	Fixed slapo-accesslog log purging issue (ITS#4505)
-	Added slapo-accesslog reqOld feature
-	Fixed slapo-auditlog missing return codes
-	Fixed slapo-ppolicy BER tags issue (ITS#4528)
-	Fixed slapo-ppolicy rebind bug (ITS#4516)
-	Fixed slapo-refint delete prohibit issue (ITS#4442)
-	Fixed slapo-syncprov MODs cause DELs (ITS#4423)
-	Fixed slapo-syncprov/syncrepl sessionlog issue (ITS#4534)
-	Added slapo-syncprov extra logging
-	Fixed slapo-translucent modifications (ITS#4527)
-	Fixed slurpd potential overflow issue
-	Build Environment
-		Fixed OSF1 compilation problem (ITS#4537)
-		Fixed test020-proxycache disabled debug issue (ITS#4491)
-		Fixed test033-glue-syncrepl overlay detection (ITS#4544)
-	Documentation
-		Fixed slapd(8) logging header reference (ITS#4509)
-		Clarified slapd.conf(5) "disable bind_anon" feature
-
-OpenLDAP 2.3.21 Release (2006/04/08)
-	Fixed libldap referral chasing issue (ITS#4448)
-	Fixed libldap invalid free bug (ITS#4436)
-	Fixed libldap mutex leak (ITS#4441)
-	Fixed libldap_r thr_yield(2) return handling (ITS#4469)
-	Fixed slapd syncprov/glue interaction issue (ITS#4323, ITS#4417)
-	Fixed slapd operational attrs in presence of global overlays (ITS#4431)
-	Fixed slapd "threads" config value checking (ITS#4433)
-	Fixed slapd connection index bound check (ITS#4449)
-	Fixed slapd connection cleanup (ITS#4465)
-	Fixed slapd slap_realloc misuse (ITS#4477)
-	Fixed slapd size limit check when pagesize=1 (ITS#4479)
-	Fixed slapd-bdb/hdb cache issue (ITS#4439)
-	Fixed slapd-ldbm crash on modify bug (ITS#4464)
-	Fixed slapd-ldap potential bind deadlock (ITS#4409)
-	Fixed slapd-ldap/meta conn expiration concurrency (ITS#4429)
-	Fixed slapd-ldap failed bind connection trashing (ITS#4428)
-	Fixed slapd-ldap/meta chase-referrals disabling (ITS#4447)
-	Fixed slapd-ldap controls forwarding (ITS#4457)
-	Fixed slapd-ldap pretty DN in proxied requests (ITS#4456)
-	Fixed slapd-ldbm crash on modify bug (ITS#4464)
-	Fixed slapd-meta write error mapping (ITS#4419)
-	Removed lint
-	Build Environment
-		Added slapo-auditlog build support (ITS#4372)
-		Fixed multi-precision sizeof detection (ITS#4416)
-		Fixed liblunicode build (ITS#4435)
-		Updated libtool to version 1.5.22 (ITS#4471)
-		Updated shtool to version 2.0.5
-
-OpenLDAP 2.3.20 Release (2006/02/18)
-	Added libldap SASL workaround for broken LDAP servers (ITS#4391)
-	Fixed libldap/slapd valuesReturnFilter OID (ITS#4404)
-	Fixed slapd config_generic_wrapper missing parameter bug (ITS#4376)
-	Fixed slapd extensible filter value normalization bug (ITS#4380)
-	Fixed slapd context CSN not updating issue (ITS#4384)
-	Fixed slapd non-read/write epoll event handling (ITS#4395)
-	Fixed slapd syncrepl de-normalize UUID issue
-	Fixed slapd syncrepl dynamic reconfig issue (ITS#4401)
-	Added slapd syncrepl log messages (ITS#4369)
-	Added slapd permissive modify/increment support
-	Added slapd dynamically registered debug level support
-	Fixed slapd connectionless LDAP support
-	Fixed slapd cn=config error on create failure issue (ITS#4407)
-	Fixed slapd-bdb/hdb wake listener on runqueue submit (ITS#4385)
-	Fixed slapd-ldap/meta resources leaks on multiple binds (ITS#4387)
-	Fixed slapd-ldap/meta assert on connection shutdown (ITS#4390)
-	Added slapd-meta subtree-exclude feature
-	Fixed slapo-syncprov update latency issue (ITS#4385)
-	Fixed slapo-auditlog crash (ITS#4394)
-	Fixed slapo-accesslog unbind crash (ITS#4386)
-	Fixed slurpd reject error formating (ITS#4382)
-	Fixed ldappasswd unbind issue (ITS#4403)
-	Fixed slapo-pcache assert on attrsonly search (ITS#4406)
-	Added slapo-pcache max_queries enhancement (ITS#4225)
-	Added slapo-pcache negative caching enhancement
-	Build Environment
-		Fixed liblunicode cross compiling problem (ITS#4363)
-		Updated <netinet/tcp.h> detection for AIX (ITS#4312)
-		Updated multi-precision library detection
-	Documentation
-		Updated misc. manual pages
-
-OpenLDAP 2.3.19 Release (2006/01/25)
-	Fixed libldap disable DH key exchange with DH params (ITS#4354)
-	Fixed libldap_r thread pool destroy hang (ITS#4349,ITS#4368)
-	Fixed slapd slap_daemon destroy issue (ITS#4370)
-	Fixed slapd-hdb livelock issue (ITS#4360)
-	Fixed slapd-bdb/hdb auto-recovery issue (ITS#4361,ITS#4373)
-	Fixed slapd-bdb/hdb BDB 4.4 compatibility issues (ITS#4362)
-	Fixed slapo-ppolicy modify issue (ITS#4355)
-	Fixed slapo-syncprov/pcache filter dup issue (ITS#4364)
-	Fixed slapo-syncprov playlog nentries reset issue (ITS#4365)
-	Build environment
-		Fixed slaptools when --disable-debug (ITS#4351)
-		Fixed slapd(8) solaris select(2) issue (ITS#4357)
-
-OpenLDAP 2.3.18 Release (2006/01/17)
-	Fixed slapd syncrepl variable used before set bug (ITS#4331)
-	Updated slapd-meta retry capabilities (ITS#4328)
-	Fixed slapd-bdb slapcat autorecover bug (ITS#4324)
-	Fixed slapo-chain search limits (ITS#4336)
-	Fixed slapo-pcache attrsets issues (ITS#4316)
-	Fixed slapo-translucent connection destroy (ITS#4334)
-	Fixed slapd-config handling of attribute options (ITS#4339)
-	Fixed slapd-ldap idassert resource leak (ITS#4326)
-	Fixed slapd-meta nretries issue (ITS#4059)
-	Fixed slapd wake_listener loses wakes (ITS#4343)
-	Fixed slapd connection manager issue (ITS#4338)
-	Fixed slapd handling of old style configuration directives (ITS#4341)
-	Removed slapd-bdb/hdb extraneous yields (ITS#3950)
-	Build Environment
-		Removed problematic Linux sched_yield(2) workarounds (ITS#3950)
-	Documentation
-		Updated release documents
-		Updated misc. manual pages
-
-OpenLDAP 2.3.17 Release (2006/01/10)
-	Fixed slapd anonymous proxy authorization issue (ITS#4320)
-	Fixed slapd-ldap/meta session reuse issue (ITS#4315)
-	Fixed slapd-ldap idassert anon-to-anon issue (ITS#4321)
-	Fixed slapd-monitor thread issue (ITS#4318)
-	Build environment
-		Updated Linux sched_yield(2) workaround to use nanosleep(2) (ITS#3950)
-		Fixed configure report-to URL
-
-OpenLDAP 2.3.16 Release (2006/01/08)
-	Fixed slapd-bdb reindexing via cn=config not noticed issue (ITS#4260)
-	Fixed slapd-monitor connection search crash (ITS#4300)
-	Fixed slapd cn=config bad ACL syntax modify crash (ITS#4306)
-	Fixed slapd ACL/suffix configuration issue (ITS#4307)
-	Fixed slapd-bdb/hdb cache issue (ITS#4308)
-	Fixed slapd-bdb/hdb/ldbm suffix add with default referral issue (ITS#4310)
-	Fixed slapd-ldbm compare cache release issue (ITS#4313)
-	Fixed slapd syncrepl time/size limit parsing
-	Fixed slapi slapi_op_bind_callback fix (ITS#4311)
-	Fixed slapi pluginlog fix (ITS#4291)
-	Fixed ldapsearch response control handling issue
-	Build environment
-		Replace sched_yield(2) on Linux with select(2) (ITS#3950)
-	Documentation
-		Added slapd-bdb(5) cachefree description
-		Updated misc. manual pages
-
-OpenLDAP 2.3.15 Release (2006/01/04)
-	Fixed slapd strerror logging bug (ITS#4292)
-	Fixed slapd ACL add/delete fraction issue (ITS#4295)
-	Fixed slapd ACL users selfwrite issue (ITS#4299)
-	Fixed slapd attrs/objectclass replog issues (ITS#4298)
-	Fixed slapd-ldap password modify exop password return (ITS#4294)
-	Build environment
-		Disable test030-relay when threads are unavailable (ITS#4297)
-
-OpenLDAP 2.3.14 Release (2005/12/23)
-	Fixed slapd assertion control restrictions
-	Fixed slapd sc_prev update after free bug (ITS#4237)
-	Fixed slapd pid file creation (ITS#4241,4251)
-	Fixed slapd DEBUG dependency (ITS#4245)
-	Added slapd warning for excessive threads number (ITS#4249)
-	Fixed slapd passwd incomplete mod structure issue (ITS#4278)
-	Fixed slapd ACL exact attrval clause normalization (ITS#4255)
-	Fixed slapd modify/delete by ordered index issue
-	Fixed slapd strerror NULL bug (ITS#4285)
-	Fixed slapd-glue issues (ITS#4084,4133)
-	Fixed slapd-hdb idl Delete bug (ITS#4250)
-	Fixed slapd-hdb cache deadlock (ITS#4254)
-	Fixed slapd-bdb/hdb alock_close bug (ITS#4259)
-	Fixed slapd-bdb dn2id IDL cache bug (ITS#4263)
-	Fixed slapd-bdb/hdb mode argument parsing (ITS#4257)
-	Fixed slapd-bdb/hdb cn=config reindexing (ITS#4260)
-	Fixed slapd-bdb/hdb cn=config olcDbIndex modify/replace (ITS#4262)
-	Fixed slapd-bdb/hdb lockup issue (ITS#4184)
-	Fixed slapd-ldap anonymous identity assertion (ITS#4272)
-	Added slapd-ldap/meta idle-timeout support (ITS#4115)
-	Fixed slapd-meta bind-timeout handling
-	Fixed slapd-sql plug leak
-	Fixed slapo-dynlist/dyngroup nonexistant object return code (ITS#4224)
-	Updated slapo-dynlist (ITS#3756,3781)
-	Fixed slapo-rwm static DN free bug (ITS#4248)
-	Fixed slapo-syncprov unpublished control (ITS#4238)
-	Fixed slapo-syncprov message id issue
-	Fixed slapo-unique extraneous searches (ITS#4267)
-	Build environment
-		Fixed thread dependency of test028 (ITS#4141)
-		Updated test026-dn
-		Updated test033-glue-syncrepl (ITS#4264)
-	Documentation
-		Updated slapd.conf(5) and Admin Guide (ITS#4146,4266)
-		Updated slapo-dynlist(5) (ITS#4197)
-		Updated slapo-pcache(5) (ITS#4232)
-		Updated slapindex(8) (ITS#4242)
-
-OpenLDAP 2.3.13 Release (2005/11/30)
-	Fixed libldap/liblutil MSG_ACCRIGHTSLEN bug (ITS#4206)
-	Fixed libldap ldap_bv2escaped_filter_value issue (ITS#4212)
-	Fixed liblutil URL value-specs issue (ITS#4221)
-	Fixed slapd sizelimit disclose issue (ITS#4213)
-	Fixed slapd gentlehup write restrict issue (ITS#3717)
-	Fixed slapd gentlehup abnormal issue (ITS#4217)
-	Fixed slapd delta-sync subtree scope issue (ITS#4227)
-	Fixed slapd cn=config OID/name pollution issue (ITS#4185)
-	Fixed slapd cn=config rootdn issue (ITS#4192)
-	Fixed slapd cn=config slaptest -F without -f issue (ITS#4194)
-	Fixed slapd cn=config ACL issue (ITS#4218)
-	Fixed slapd-bdb negative results IDL cache issue (ITS#4223)
-	Fixed slapd-bdb cursor close issue (ITS#4226)
-	Fixed slapd-hdb slapadd -q issue (ITS#4210)
-	Fixed slapd-hdb missing results issue (ITS#4186)
-	Fixed slapd-ldap potential double free issue (ITS#4189)
-	Fixed slapd-meta matched DN issue (ITS#4195)
-	Fixed slapd-meta DN cache issue (ITS#4196)
-	Fixed slapd-monitor shadow issue (ITS#4214)
-	Fixed slapo-accesslog delta-syncrepl issue (ITS#4198)
-	Fixed slapo-accesslog cleanup issue (ITS#4209)
-	Fixed slapo-chain resource leak issue (ITS#4140)
-	Fixed slapo-chain identity assertion issue (ITS#4256)
-	Fixed slapo-pcache attrset check issue (ITS#4199)
-	Fixed slapd-bdb readonly dirty alock issue (ITS#4201)
-	Fixed slapd-pcache non-requested attributes issues (ITS#4203,4204)
-	Fixed slaptest -F -f success with unsupported issue (ITS#4220)
-	Build environment
-		Improved Berkeley DB detection (ITS#3809)
-		Updated DB_CONFIG example (ITS#4229)
-	Documentation
-		Updated ldif(5) to include change record description
-
-OpenLDAP 2.3.12 Release (2005/11/17)
-	Fixed libldap ldapi:// authdn construction
-	Added libldap ldap_bv2escaped_filter_value (ITS#2535)
-	Added libldap/slapd TLS DSA certificate support (ITS#4017)
-	Fixed libldap SASL bind issue (ITS#4158)
-	Fixed ldapmodrdn empty line handling (ITS#4101)
-	Fixed client tools additional info printing (ITS#4147)
-	Updated slapd ldaps:// not configured fix (ITS#4082,4083)
-	Fixed slapd connection crashes (ITS#4108)
-	Fixed slapd illegal S option bug (ITS#4119)
-	Fixed slapd cn=monitor log level mod issue (ITS#4091)
-	Fixed slapd cn=config bad access issue (ITS#4111)
-	Fixed slapd cn=config access modify issue (ITS#4127)
-	Fixed slapd cn=config init issue (ITS#4128)
-	Fixed slapd non-reentrant libwrap issue (ITS#4099)
-	Fixed slapd thread v. tools_threads settings
-	Fixed slapd spurious defer message (ITS#3850)
-	Fixed slapd attribute SYNTAX OIDM issue (ITS#4116)
-	Fixed slapd modify empty sequence bug (ITS#4183)
-	Fixed slapd-bdb uninitialized condition in tool mode (ITS#4143)
-	Fixed slapd-bdb empty suffix and syncprov issue (ITS#4171)
-	Fixed slapd-hdb syncrepl deadlock issue (ITS#4088)
-	Added slapd-ldap write op timeout support (ITS#4157)
-	Fixed slapd-ldap/slapo-chain matched dn handling (ITS#4176)
-	Fixed slapd-meta invalid DN attrs normalize/pretty issue (ITS#4107)
-	Fixed slapd-meta rootdn erroneous success issue (ITS#4122)
-	Fixed slapd-meta proxying bind result issue (ITS#4129)
-	Fixed slapd-meta/slapo-rwm rwm-mapping issue (ITS#4086)
-	Fixed slapd-meta per-target retry (ITS#4150)
-	Fixed slapd-meta size/time limit handling (ITS#4145)
-	Fixed slapd-sql size limit count (ITS#4181)
-	Fixed slapo-ppolicy pwdFailureTime after bind success issue (ITS#4134)
-	Fixed slapo-ppolicy add passord_hash quality config dependency
-	Fixed slapo-syncprov LDAP response types (ITS#4183)
-	Added slapd delta syncrepl support
-	Added slapadd thread support
-	Updated slapcat subordinate database handling (ITS#4089)
-	Added slapd/slaptest pid/arg file consistency check (ITS#4074)
-	Updated slaptools default debug level to "none" (ITS#4044)
-	Fixed slurpd backwards compat issue (ITS#4151)
-	Added slurpd pid/arg file consistency check (ITS#4152)
-	Updated contrib smbk5pwd module
-	Removed lint
-	Build environment
-		Fixed libldap HSTRERROR issue (ITS#4124)
-		Fixed slapd AIX IFMT issue (ITS#4123)
-		Added slapd-bind test program
-		Added inet_ntoa_b support for VxWorks (ITS#3440)
-		Updated test036 (ITS#4095)
-		Fixed test036 cmp issue (ITS#4142)
-		Dropped SSLeay support
-	Documentation
-		slapd.conf(5) defaultSearchBase issue (ITS#4162)
-		slap tool man pages wll typo (ITS#4169)
-
-OpenLDAP 2.3.11 Release (2005/10/12)
-	Fixed libldap reentrancy issue (ITS#3988)
-	Fixed libldap ndelay without timeout
-	Fixed slapd ldaps:// not configured issue (ITS#4082,4083)
-	Fixed slapd-bdb/hdb mode argument parsing (ITS#4077)
-	Fixed slapd WIN32 writefds init issue
-	Fixed slapadd buffer alignment issue (ITS#4078)
-	Updated slapd syncrepl to use ldap_unbind_ext
-	Removed lint
-
-OpenLDAP 2.3.10 Release (2005/10/10)
-	Fixed libldap chasing of chased referrals (ITS#2942)
-	Added libldap LDAP_NOT_SUPPORTED for TLS (ITS#4072)
-	Added libldap LDAP_MSG_RECEIVED support
-	Dropped libldap LDAP_MORE_RESULTS_TO_RETURN use
-	Fixed slapd cn=config updated rootdn issue (ITS#4035)
-	Fixed slapd-meta bus error (ITS#4073)
-	Fixed slapd-meta/ldap/rwm empty naming context issue (ITS#4071)
-
-OpenLDAP 2.3.9 Release (2005/10/07)
-	Fixed slapd req_pwdexop bug
-	Fixed slapo-syncprov queued UUIDs bug (ITS#4068)
-	Fixed slapo-syncprov memory leak
-	Fixed slapd anlist leak
-	Removed lint
-	Build Environment
-		Updated testsuite to test only primary backends by default
-		Disable test041-aci
-
-OpenLDAP 2.3.8 Release (2005/10/05)
-	Fixed slapd undef HAVE_EPOLL issue
-	Fixed slapd connection-get wake bug (ITS#3999)
-	Fixed slapd uninitialized var bug (ITS#3854)
-	Fixed slapd add entry without parent bug (ITS#2757)
-	Fixed slapd cn=config value escaping bug (ITS#3807)
-	Fixed slapd cn=config missing host/uri bug (ITS#4009)
-	Fixed slapd alock symbol bug (ITS#3978)
-	Fixed slapd replogfile assert (ITS#4003)
-	Fixed slapd rewrite session var set bug (ITS#4023)
-	Fixed slapd syncrepl empty uniqueMember bug (ITS#4040)
-	Fixed slapd alias resolution bug (ITS#4030)
-	Fixed slapd password-hash cleartext bug (ITS#4021)
-	Fixed slapd realloc zero bug (ITS#3981)
-	Fixed slapd nested overlay configuration bug (ITS#4047)
-	Fixed slapd password modify oldPassword ignore bug (ITS#4049)
-	Added slapd password oldPassword verify (ITS#4051)
-	Fixed slapd select_backend manageDSAit with glue issue (ITS#4027)
-	Updated slapd authz backend detection (ITS#4018)
-	Fixed slapd-bdb/hdb pointer/integer size mismatch (ITS#4015)
-	Updated slapd-hdb index management
-	Fixed slapd-glue mixtures bug (ITS#3979)
-	Fixed slapd-ldap unlock issue (ITS#4001)
-	Fixed slapd-ldap manageDIT check bug (ITS#4005)
-	Fixed slapd-ldap resource release issue (ITS#4016)
-	Fixed slapd-meta rootdn lookup bug (ITS#4004)
-	Fixed slapd-meta null value assert issue (ITS#4028)
-	Added slapd-meta pooled connections (ITS#4056)
-	Added slapd-meta target DSA bind defer when auth'd as rootdn (ITS#4057)
-	Fixed slapd-meta pseudorootdn issue
-	Fixed slapd-monitor unavailable issue (ITS#4013)
-	Fixed slapd-perl init/destroy bug (ITS#3923)
-	Fixed slapd-sql missing space issue (ITS#4061)
-	Fixed slapo-accesslog timestamp normalization issue
-	Fixed slapo-accesslog normalizer issue 
-	Fixed slapo-ppolicy replication issues (ITS#3980)
-	Added slapo-ppolicy pwdattribute descriptor support (ITS#4025)
-	Fixed slapo-syncprov/unique interact issues (ITS#3989)
-	Fixed slapo-syncprov/subordinate interact issues (ITS#3996)
-	Fixed slapo-syncprov schema check assert (ITS#4031)
-	Fixed slapo-syncprov psearch flush in qtask
-	Fixed slapo-syncprov abandon checks
-	Fixed slapo-unique ignore writes not under unique_base (ITS#4066)
-	Fixed slapo-valsort unknown valsort-attr bug (ITS#4047)
-	Fixed slapcat out-of-memory problem (ITS#4010)
-	Fixed slurpd unrecognized slave names bug (ITS#4012)
-	Fixed liblber dgram len bug (ITS#4046)
-	Fixed libldap SASL and TLS potential ld_error leaks (ITS#4064)
-	Fixed liblutil/csn time counter issue 
-	Updated contrib/ldapc++ to avoid deprecated functions
-	Documentation
-		Added slapo-valsort(5) man page (ITS#3994)
-		Added slap tool -F option documentation (ITS#4026)
-	Build Environment
-		Fixed misc POSIX conformance issues (ITS#2667)
-		Fixed --without-threads build issue (ITS#4006)
-		Fixed test script exit checks (ITS#4045)
-		Added test suite parameterized directory support
-		Fixed test suite tool error handling
-		Updated contrib/ldapc++ build environment
-
-OpenLDAP 2.3.7 Release (2005/08/31)
-	Updated slapd ManageDIT support
-	Updated slapd ACI syntax checking (ITS#3877)
-	Fixed slapd STATS2 referral logging
-	Refixed slapd cn=config default search base bug (ITS#3900)
-	Fixed slapd cn=config TLSVerifyClient bug (ITS#3962)
-	Fixed slapd winsock assert (ITS#3983)
-	Fixed slapd-bdb/hdb paged results deadlock (ITS#3940)
-	Fixed slapd-bdb/hdb/ldbm searchBase disclose (ITS#3964)
-	Fixed slapd-bdb/hdb bi_dbenv check (ITS#3992)
-	Fixed slapd-meta generic attribute normalize/pretty (ITS#3956)
-	Fixed slapd-ldap/meta 'undefined' attribute mutex protection (ITS#3958)
-	Added slapd-ldap/meta 'proxied' attribute support (ITS#3959)
-	Fixed slapd-meta no candidate target selected bug (ITS#3990)
-	Fixed slapd-meta matchedDN handling (ITS#3944)
-	Fixed slapd-monitor hiding issue (ITS#3986)
-	Fixed slapo-ppolicy lockout status at Bind (ITS#3946)
-	Moved slapo-glue into slapd core
-	Fixed slaptest cn=config segfault (ITS#3961)
-	Fixed slaptools logging issue (ITS#3937)
-	Fixed slaptools fails after db clean (ITS#3970)
-	Fixed slaptools reject unsupported -w (ITS#3939)
-	Fixed libldap global_opt failure 
-	Fixed libldap schema handling
-	Fixed libldap secprops parsing (ITS#3955)
-	Fixed libldap_r tpool (ITS#3925)
-	Updated liblutil password scheme check
-	Updated libldap schema to allow OID macros in syntaxes
-	Removed lint
-	Documentation
-		Updated misc. man pages
-	Build Environment
-		Updated build tools (ITS#3928)
-		Fixed tests diff -u usage (ITS#3969)
-		Fixed slapo-rwm dependency checking (ITS#3965)
-		Fixed tests --disable-monitor support
-		Fixed tests veryclean-local testdata cleanup
-		Add subtree rename test (hdb only)
-
-OpenLDAP 2.3.6 Release (2005/08/19)
-	Fixed slapd dnRelativeMatch return (ITS#3931)
-	Fixed slapd send_search_entry issue (ITS#3951)
-	Fixed slapd-bdb/hdb release entry in paged response
-	Fixed slapd-meta resources release issue (ITS#3943)
-	Fixed slapd-ldap/meta matched return (ITS#3942,ITS#3944)
-	Fixed slapo-ppolicy reset lockouts issue (ITS#3946)
-	Fixed nis.schema posixGroup object class kind (ITS#3941)
-	Revert librewrite regex mutex change (ITS#3932)
-	Updated slapd manage capability
-	Updated slapo-syncprov CSN filter checks
-	Updated libldap url list parsing
-	Added slapd SASL rootpw support (ITS#3845)
-	Added slapd Stats logging for additional cases
-	Added slapd ACI syntax validater (ITS#3877)
-	Added slapd posixgroup ACL module to contrib
-	Added slapi SLAPI_X_ADD_STRUCTURAL_CLASS extension
-	Added slapd-ldap subtree renaming proxing
-	Added slapd-meta overlapping targets enhancement (ITS#3711)
-	Removed lint
-	Documentation
-		Added slapcat(8) -a usage example (ITS#3930)
-		Updated slapo-unique(5) for clarity (ITS#3936)
-		Updated slapo-syncprov(5) sessionlog description (ITS#3935)
-		Updated doc/drafts
-	Build Environment
-		Updated test prog bind retry code
-		Fixed test015-xsearch regression (ITS#3506)
-		Added test040-subtree-rename
-
-OpenLDAP 2.3.5 Release (2005/08/14)
-	Fixed slapd integerBitOr/AndMatch logic (ITS#3782)
-	Fixed slapd substrings filter length checks (ITS#3790)
-	Fixed slapd thread pool initialization (ITS#3793)
-	Fixed slapd cancel exop (ITS#3549)
-	Fixed slapd syncrepl cookie problem (ITS#3917)
-	Fixed slapd inequality filter index bug (ITS#3920)
-	Fixed slapd syncrepl ctxcsn leak (ITS#3922)
-	Fixed slapd syncrepl scope issue (ITS#3831)
-	Fixed slapd syncrepl missing array subscript (ITS#3834)
-	Fixed slapd slapd_remove null deref (ITS#3842)
-	Fixed slapd ldapi credential normalization bug (ITS#3876)
-	Fixed slapd userPassword cleartext bug (ITS#3846)
-	Fixed slapd cn=config default search base bug (ITS#3900)
-	Fixed slapd cn=config olcDbConfig bug (ITS#3815)
-	Fixed slapd cn=config olcReadOnly bug (ITS#3820)
-	Fixed slapd cn=config hdb+bdb bug (ITS#3821)
-	Fixed slapd ACL attrs/val EQUALITY issue (ITS#3830)
-	Fixed slapd authx-regexp diagnostics (ITS#3819)
-	Fixed slapd index_substr_any_step keyword (ITS#3818)
-	Fixed slapd -f directory issue (ITS#3865)
-	Fixed slapd attributeOptions config parsing (ITS#3829)
-	Fixed slapd whitespace config parsing bug (ITS#3901)
-	Fixed slapd rootdn space issue (ITS#3806)
-	Fixed slapd passwd change w/ {CRYPT} bug (ITS#3805)
-	Fixed slapd backend_init_controls assert (ITS#3853)
-	Fixed slapd loglevel -1 bug (ITS#3858)
-	Fixed slapi bind bound DN issue (ITS#2971)
-	Fixed slapi issues (ITS#3884,3885,3886)
-	Fixed slapi authorization name issue (ITS#3892)
-	Fixed slapi slapi_int_connection_init operation problem (ITS#3868)
-	Fixed slapi slapi_entry_has_children bug (ITS#3879)
-	Fixed slapd-bdb manual recovery startup (ITS#3607,3824)
-	Fixed slapd-bdb manual recovery startup (ITS#3833)
-	Fixed slapd-bdb/hdb checkpoint before suffix bug (ITS#3784)
-	Fixed slapd-hdb modrdn base bug (ITS#3857)
-	Fixed slapd-ldap access to freed connection (ITS#3913)
-	Fixed slapd-ldap/meta filter bug (ITS#3785)
-	Fixed slapd-ldap/meta connection pooling (ITS#3813)
-	Fixed slapd-ldap/meta memory leak (ITS#3862)
-	Added slapd-sql enhancements (ITS#3432)
-	Fixed slapd-sql attribute with no values issue (ITS#3861)
-	Fixed slapd-sql truncating keyval column problem (ITS#3888)
-	Fixed slapd-sql return code ignored problem (ITS#3891)
-	Fixed slapo-glue alock bug (ITS#3817,3841)
-	Fixed slapo-dyngroup hidden subschemaSubentry bug (ITS#3844)
-	Fixed slapo-ppolicy hashed length problem (ITS#3783)
-	Fixed slapo-ppolicy quality check (ITS#3777)
-	Fixed slapo-ppolicy lockout duration (ITS#3779)
-	Fixed slapo-rwm leak (ITS#3914)
-	Fixed slapo-glue/rwm conflict (ITS#3788)
-	Fixed slapadd segfault (ITS#3926)
-	Fixed slapcat cn=config segfault (ITS#3796)
-	Fixed slaptest -F crash (ITS#3912)
-	Fixed slapd authzTo/From syntax issue (ITS#3921)
-	Fixed libldap abandon concurrency issue (ITS#3800)
-	Fixed libldap start_tls referral chasing (ITS#3791)
-	Fixed libldap referral chasing issues (ITS#2894,3578)
-	Fixed librewrite concurrency issue (ITS#3932)
-	Use IANA-assigned OIDs for recently approved IETF LDAP extensions
-	Removed lint (ITS#3857)
-	Build Environment
-		Upgraded shtool (ITS#3752)
-		Upgraded config.guess/config.sub
-		Fixed FreeBSD thread stacksize problem (ITS#3456)
-		Fixed cygwin shared libraries build problem (ITS#3712)
-		Fixed acl_get/acl_mask v AIX symbol clash (ITS#3787)
-		Fixed test020 logging problem (ITS#3811)
-		Fixed duplicate symbol problem (ITS#3843)
-		Fixed liblunicode 64bit builds (ITS#3869)
-		Fixed passwd/kerberos module builds (ITS#3896)
-		Fixed test037 manageDIT discovery issue (ITS#3898)
-		Fixed installed man page symlinks (ITS#3904)
-		Fixed <sasl.h> inclusion (ITS#3905)
-		Fixed smbk5pwd Heimdal compat issue (ITS#3910)
-		Fixed slapd make install issue (ITS#3929)
-		Fixed DESTDIR reporting (ITS#3916)
-	Documentation
-		Fixed Admin Guide authz v. saslauthz problem (ITS#3875)
-		Fixed Admin Guide --disable-bdb issue (ITS#3837)
-		Fixed slapd-meta(5) lastmod issue (ITS#3789)
-		Updated slapd.conf(5) (ITS#3866)
-		Updated slapd(8) OPTIONS section (ITS#3816)
-		Updated slapd-monitor(5) (ITS#3822,3836)
-		Updated slapd-bdb(5) (ITS#3823)
-
-OpenLDAP 2.3.4 Release (2005/06/10)
+OpenLDAP 2.4.6 Release (2007/10/31)
 	Initial release for "general use".
-

Modified: openldap/trunk/COPYRIGHT
===================================================================
--- openldap/trunk/COPYRIGHT	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/COPYRIGHT	2007-12-15 10:25:31 UTC (rev 892)
@@ -36,9 +36,11 @@
 
 ---
 
-Portions Copyright 1999-2005 Howard Y.H. Chu.
-Portions Copyright 1999-2005 Symas Corporation.
+Portions Copyright 1999-2007 Howard Y.H. Chu.
+Portions Copyright 1999-2007 Symas Corporation.
 Portions Copyright 1998-2003 Hallvard B. Furuseth.
+Portions Copyright 2007 Gavin Henry
+Portions Copyright 2007 Suretec Systems
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without

Modified: openldap/trunk/Makefile.in
===================================================================
--- openldap/trunk/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Master Makefile for OpenLDAP
-# $OpenLDAP: pkg/ldap/Makefile.in,v 1.27.2.4 2007/01/02 21:43:21 kurt Exp $
+# $OpenLDAP: pkg/ldap/Makefile.in,v 1.30.2.2 2007/08/31 23:13:44 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/README
===================================================================
--- openldap/trunk/README	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/README	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,10 +1,10 @@
-OpenLDAP 2.3 README
+OpenLDAP 2.4 README
     For a description of what this distribution contains, see the
     ANNOUNCEMENT file in this directory.  For a description of
     changes from previous releases, see the CHANGES file in this
     directory.
 
-    This is 2.3 release, it includes significant changes from prior
+    This is 2.4 release, it includes significant changes from prior
     releases.
 
 REQUIRED SOFTWARE
@@ -14,19 +14,15 @@
 
     Base system (libraries and tools):
         Standard C compiler (required)
-        Cyrus SASL 2.1.18+ (recommended)
+        Cyrus SASL 2.1.21+ (recommended)
         OpenSSL 0.9.7+ (recommended)
         POSIX REGEX software (required)
 
     SLAPD:
         BDB and HDB backends require Oracle Berkeley DB 4.2, 4.4,
-        or 4.5.  It is highly recommended to apply the patches
+        4.5, or 4.6.  It is highly recommended to apply the patches
         from Oracle for a given release.
 
-    SLURPD:
-        LTHREAD compatible thread package
-            [POSIX threads, Mach Cthreads, select others]
-
     CLIENTS/CONTRIB ware:
         Depends on package.  See per package README.
 
@@ -78,7 +74,7 @@
     <http://www.openldap.org/its/> to be considered.
 
 ---
-$OpenLDAP: pkg/ldap/README,v 1.38.2.9 2007/10/11 18:52:18 quanah Exp $
+$OpenLDAP: pkg/ldap/README,v 1.40.2.6 2007/10/11 18:55:56 quanah Exp $
 
 This work is part of OpenLDAP Software <http://www.openldap.org/>.
 

Modified: openldap/trunk/build/config.guess
===================================================================
--- openldap/trunk/build/config.guess	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/config.guess	2007-12-15 10:25:31 UTC (rev 892)
@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 timestamp='2003-07-02-OpenLDAP'
-# $OpenLDAP: pkg/ldap/build/config.guess,v 1.14.2.4 2007/01/02 21:43:40 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/config.guess,v 1.19.2.2 2007/08/31 23:13:50 quanah Exp $
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@
 # configuration script generated by Autoconf, and is distributable
 # under the same distributions terms as OpenLDAP itself.
 
-## Copyright 1998-2007 The OpenLDAP Foundation.
+## Portions Copyright 1998-2007 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
 ## Redistribution and use in source and binary forms, with or without

Modified: openldap/trunk/build/config.sub
===================================================================
--- openldap/trunk/build/config.sub	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/config.sub	2007-12-15 10:25:31 UTC (rev 892)
@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 timestamp='2003-07-04-OpenLDAP'
-# $OpenLDAP: pkg/ldap/build/config.sub,v 1.14.2.4 2007/01/02 21:43:40 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/config.sub,v 1.19.2.2 2007/08/31 23:13:50 quanah Exp $
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -34,7 +34,7 @@
 # configuration script generated by Autoconf, and is distributable
 # under the same distributions terms as OpenLDAP itself.
 
-## Copyright 1998-2007 The OpenLDAP Foundation.
+## Portions Copyright 1998-2007 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
 ## Redistribution and use in source and binary forms, with or without

Modified: openldap/trunk/build/crupdate
===================================================================
--- openldap/trunk/build/crupdate	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/crupdate	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# $OpenLDAP: pkg/ldap/build/crupdate,v 1.5.2.3 2007/01/02 21:43:40 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/crupdate,v 1.7.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Copied: openldap/trunk/build/db.4.2.52.patch (from rev 891, openldap/vendor/openldap-2.4.7/build/db.4.2.52.patch)
===================================================================
--- openldap/trunk/build/db.4.2.52.patch	                        (rev 0)
+++ openldap/trunk/build/db.4.2.52.patch	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,55 @@
+As posted to http://www.openldap.org/lists/openldap-devel/200610/msg00027.html
+
+This is Sleepycat bug #14908. The provided patch is for 4.2.52. The
+same bug is present in all versions up to 4.5.20 where it is fixed.
+
+-------- Original Message --------
+Subject: region size bug Re: [BDB-Alpha] Berkeley DB 4.5.8 ALPHA
+Date: Mon, 10 Jul 2006 13:37:33 -0700
+From: Howard Chu <hyc at symas.com>
+To: support at sleepycat.com
+CC: support at symas.com
+References: <45A742B5-7DD5-4512-A204-A10FE8FC5DFC at oracle.com>
+
+
+I just ran into this in 4.2.52 but the same calculation occurs in 4.4
+and 4.5.8 alpha:
+
+This computation gives the wrong results when the number of cache
+regions is greater than the number of gigabytes (which we encounter on
+Linux using shared memory regions, which are constrained to much smaller
+than a gigabyte each).
+
+
+in mp/mp_region.c:
+
+
+   roff_t reg_size;
+
+
+   /* Figure out how big each cache region is. */
+   reg_size = (roff_t)(dbenv->mp_gbytes / dbenv->mp_ncache) * GIGABYTE;
+   reg_size += ((roff_t)(dbenv->mp_gbytes %
+       dbenv->mp_ncache) * GIGABYTE) / dbenv->mp_ncache;
+   reg_size += dbenv->mp_bytes / dbenv->mp_ncache;
+   *reg_sizep = reg_size;
+
+
+The first reg_size calculation always goes to zero when mp_ncache >
+mp_gbytes.
+This should have been, instead:
+   reg_size = GIGABYTE / dbenv->mp_ncache * dbenv->mp_gbytes;
+
+--- mp/mp_region.c.O	2003-06-30 10:20:19.000000000 -0700
++++ mp/mp_region.c	2006-10-27 23:25:05.000000000 -0700
+@@ -43,9 +43,7 @@
+ 	int htab_buckets, ret;
+ 
+ 	/* Figure out how big each cache region is. */
+-	reg_size = (dbenv->mp_gbytes / dbenv->mp_ncache) * GIGABYTE;
+-	reg_size += ((dbenv->mp_gbytes %
+-	    dbenv->mp_ncache) * GIGABYTE) / dbenv->mp_ncache;
++	reg_size = GIGABYTE / dbenv->mp_ncache * dbenv->mp_gbytes;
+ 	reg_size += dbenv->mp_bytes / dbenv->mp_ncache;
+ 
+ 	/*

Modified: openldap/trunk/build/dir.mk
===================================================================
--- openldap/trunk/build/dir.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/dir.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/dir.mk,v 1.14.2.4 2007/01/02 21:43:40 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/dir.mk,v 1.17.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/info.mk
===================================================================
--- openldap/trunk/build/info.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/info.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/info.mk,v 1.9.2.4 2007/01/02 21:43:40 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/info.mk,v 1.12.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/lib-shared.mk
===================================================================
--- openldap/trunk/build/lib-shared.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/lib-shared.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/lib-shared.mk,v 1.19.2.4 2007/01/02 21:43:40 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/lib-shared.mk,v 1.22.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/lib-static.mk
===================================================================
--- openldap/trunk/build/lib-static.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/lib-static.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/lib-static.mk,v 1.10.2.4 2007/01/02 21:43:40 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/lib-static.mk,v 1.13.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/lib.mk
===================================================================
--- openldap/trunk/build/lib.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/lib.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/lib.mk,v 1.20.2.4 2007/01/02 21:43:40 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/lib.mk,v 1.23.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/ltmain.sh
===================================================================
--- openldap/trunk/build/ltmain.sh	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/ltmain.sh	2007-12-15 10:25:31 UTC (rev 892)
@@ -26,9 +26,9 @@
 
 # This file is distributed with OpenLDAP Software, which contains a
 # configuration script generated by Autoconf, and is distributable
-# under the same distributions terms as OpenLDAP inself.
+# under the same distributions terms as OpenLDAP itself.
 
-## Copyright 1998-2007 The OpenLDAP Foundation.
+## Portions Copyright 1998-2007 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
 ## Redistribution and use in source and binary forms, with or without

Modified: openldap/trunk/build/man.mk
===================================================================
--- openldap/trunk/build/man.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/man.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/man.mk,v 1.27.2.8 2007/01/02 23:42:47 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/man.mk,v 1.32.2.3 2007/11/09 02:55:50 hyc Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -23,7 +23,7 @@
 	PAGES=`cd $(srcdir); echo *.$(MANSECT)`; \
 	for page in $$PAGES; do \
 		$(SED) -e "s%LDVERSION%$(VERSION)%" \
-			-e 's%ETCDIR%$(sysconfdir)%' \
+			-e 's%ETCDIR%$(sysconfdir)%g' \
 			-e 's%LOCALSTATEDIR%$(localstatedir)%' \
 			-e 's%SYSCONFDIR%$(sysconfdir)%' \
 			-e 's%DATADIR%$(datadir)%' \
@@ -32,7 +32,8 @@
 			-e 's%LIBDIR%$(libdir)%' \
 			-e 's%LIBEXECDIR%$(libexecdir)%' \
 			-e 's%RELEASEDATE%$(RELEASEDATE)%' \
-				$(srcdir)/$$page > $$page.$(TMP_SUFFIX); \
+				$(srcdir)/$$page \
+			| (cd $(srcdir); $(SOELIM) -) > $$page.$(TMP_SUFFIX); \
 	done
 
 install-common:

Modified: openldap/trunk/build/mkdep
===================================================================
--- openldap/trunk/build/mkdep	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/mkdep	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 #! /bin/sh -
-# $OpenLDAP: pkg/ldap/build/mkdep,v 1.29.2.4 2007/01/02 21:43:41 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/mkdep,v 1.32.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/mkrelease
===================================================================
--- openldap/trunk/build/mkrelease	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/mkrelease	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# $OpenLDAP: pkg/ldap/build/mkrelease,v 1.18.2.5 2007/01/02 21:43:41 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/mkrelease,v 1.23.2.3 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -58,6 +58,11 @@
 	echo "No guide"
 fi
 
+if test -e $RELNAME/libraries/liblunicode/ucdata/uctable.h ; then
+	echo "touching uctable.h..."
+	touch $RELNAME/libraries/liblunicode/ucdata/uctable.h
+fi
+
 if test ! -e $RELNAME/build/version.sh ; then
 	echo "No build version"
 	OL_STRING="something"

Modified: openldap/trunk/build/mkvers.bat
===================================================================
--- openldap/trunk/build/mkvers.bat	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/mkvers.bat	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-:: $OpenLDAP: pkg/ldap/build/mkvers.bat,v 1.5.2.3 2007/01/02 21:43:41 kurt Exp $
+:: $OpenLDAP: pkg/ldap/build/mkvers.bat,v 1.7.2.2 2007/08/31 23:13:50 quanah Exp $
 :: This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ::
 :: Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/mkversion
===================================================================
--- openldap/trunk/build/mkversion	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/mkversion	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Create a version.c file
-# $OpenLDAP: pkg/ldap/build/mkversion,v 1.12.2.3 2007/01/02 21:43:41 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/mkversion,v 1.14.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/mod.mk
===================================================================
--- openldap/trunk/build/mod.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/mod.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/mod.mk,v 1.22.2.4 2007/01/02 21:43:41 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/mod.mk,v 1.25.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/openldap.m4
===================================================================
--- openldap/trunk/build/openldap.m4	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/openldap.m4	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 dnl OpenLDAP Autoconf Macros
-dnl $OpenLDAP: pkg/ldap/build/openldap.m4,v 1.140.2.14 2007/10/05 15:33:02 hyc Exp $
+dnl $OpenLDAP: pkg/ldap/build/openldap.m4,v 1.157.2.4 2007/09/01 00:38:35 hyc Exp $
 dnl This work is part of OpenLDAP Software <http://www.openldap.org/>.
 dnl
 dnl Copyright 1998-2007 The OpenLDAP Foundation.
@@ -91,6 +91,7 @@
 			done
 			rm -f conftest*
 		])
+		test "$ol_cv_mkdep" = no && OL_MKDEP=":"
 	else
 		cc_cv_mkdep=yes
 		OL_MKDEP_FLAGS="${MKDEP_FLAGS}"
@@ -486,31 +487,31 @@
 ])
 
 if test $ol_cv_bdb_major = 4 ; then
-	if test $ol_cv_bdb_minor = 5 ; then
+	if test $ol_cv_bdb_minor = 6 ; then
+		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_6,[-ldb-4.6])
+		OL_BERKELEY_DB_TRY(ol_cv_db_db46,[-ldb46])
+		OL_BERKELEY_DB_TRY(ol_cv_db_db_46,[-ldb-46])
+		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_6,[-ldb-4-6])
+	elif test $ol_cv_bdb_minor = 5 ; then
+		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_5,[-ldb-4.5])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db45,[-ldb45])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db_45,[-ldb-45])
-		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_5,[-ldb-4.5])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_5,[-ldb-4-5])
 	elif test $ol_cv_bdb_minor = 4 ; then
+		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_4,[-ldb-4.4])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db44,[-ldb44])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db_44,[-ldb-44])
-		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_4,[-ldb-4.4])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_4,[-ldb-4-4])
 	elif test $ol_cv_bdb_minor = 3 ; then
+		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_3,[-ldb-4.3])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db43,[-ldb43])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db_43,[-ldb-43])
-		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_3,[-ldb-4.3])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_3,[-ldb-4-3])
 	elif test $ol_cv_bdb_minor = 2 ; then
+		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_2,[-ldb-4.2])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db42,[-ldb42])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db_42,[-ldb-42])
-		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_2,[-ldb-4.2])
 		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_2,[-ldb-4-2])
-	elif test $ol_cv_bdb_minor = 1 ; then
-		OL_BERKELEY_DB_TRY(ol_cv_db_db41,[-ldb41])
-		OL_BERKELEY_DB_TRY(ol_cv_db_db_41,[-ldb-41])
-		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_1,[-ldb-4.1])
-		OL_BERKELEY_DB_TRY(ol_cv_db_db_4_1,[-ldb-4-1])
 	fi
 	OL_BERKELEY_DB_TRY(ol_cv_db_db_4,[-ldb-4])
 	OL_BERKELEY_DB_TRY(ol_cv_db_db4,[-ldb4])
@@ -696,8 +697,8 @@
 #	define DB_VERSION_MINOR 0
 #endif
 
-/* require 4.2-4.5 */
-#if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 2) && (DB_VERSION_MINOR < 6)
+/* require 4.2 or later, but exclude 4.3 */
+#if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 2) && (DB_VERSION_MINOR !=3)
 	__db_version_compat
 #endif
 	], [ol_cv_bdb_compat=yes], [ol_cv_bdb_compat=no])])
@@ -736,152 +737,6 @@
 ])
 dnl
 dnl ====================================================================
-dnl Check if GDBM library exists
-dnl Check for gdbm_open in standard libraries or -lgdbm
-dnl
-dnl defines ol_cv_lib_gdbm to 'yes' or '-lgdbm' or 'no'
-dnl		'yes' implies gdbm_open is in $LIBS
-dnl
-dnl uses:
-dnl		AC_CHECK_FUNC(gdbm_open)
-dnl		AC_CHECK_LIB(gdbm,gdbm_open)
-dnl
-AC_DEFUN([OL_LIB_GDBM],
-[AC_CACHE_CHECK(for GDBM library, [ol_cv_lib_gdbm],
-[	ol_LIBS="$LIBS"
-	AC_CHECK_FUNC(gdbm_open,[ol_cv_lib_gdbm=yes], [
-		AC_CHECK_LIB(gdbm,gdbm_open,[ol_cv_lib_gdbm=-lgdbm],[ol_cv_lib_gdbm=no])
-	])
-	LIBS="$ol_LIBS"
-])
-])dnl
-dnl
-dnl --------------------------------------------------------------------
-dnl Check if GDBM exists
-dnl
-dnl defines ol_cv_gdbm to 'yes' or 'no'
-dnl 
-dnl uses:
-dnl		OL_LIB_GDBM
-dnl		AC_CHECK_HEADERS(gdbm.h)
-dnl
-AC_DEFUN([OL_GDBM],
-[AC_REQUIRE([OL_LIB_GDBM])
- AC_CHECK_HEADERS(gdbm.h)
- AC_CACHE_CHECK(for db, [ol_cv_gdbm], [
-	if test $ol_cv_lib_gdbm = no || test $ac_cv_header_gdbm_h = no ; then
-		ol_cv_gdbm=no
-	else
-		ol_cv_gdbm=yes
-	fi
-])
- if test $ol_cv_gdbm = yes ; then
-	AC_DEFINE(HAVE_GDBM,1, [define if GNU DBM is available])
- fi
-])dnl
-dnl
-dnl ====================================================================
-dnl Check if MDBM library exists
-dnl Check for mdbm_open in standard libraries or -lmdbm
-dnl
-dnl defines ol_cv_lib_mdbm to 'yes' or '-lmdbm' or 'no'
-dnl		'yes' implies mdbm_open is in $LIBS
-dnl
-dnl uses:
-dnl		AC_CHECK_FUNC(mdbm_set_chain)
-dnl		AC_CHECK_LIB(mdbm,mdbm_set_chain)
-dnl
-AC_DEFUN([OL_LIB_MDBM],
-[AC_CACHE_CHECK(for MDBM library, [ol_cv_lib_mdbm],
-[	ol_LIBS="$LIBS"
-	AC_CHECK_FUNC(mdbm_set_chain,[ol_cv_lib_mdbm=yes], [
-		AC_CHECK_LIB(mdbm,mdbm_set_chain,[ol_cv_lib_mdbm=-lmdbm],[ol_cv_lib_mdbm=no])
-	])
-	LIBS="$ol_LIBS"
-])
-])dnl
-dnl
-dnl --------------------------------------------------------------------
-dnl Check if MDBM exists
-dnl
-dnl defines ol_cv_mdbm to 'yes' or 'no'
-dnl 
-dnl uses:
-dnl		OL_LIB_MDBM
-dnl		AC_CHECK_HEADERS(mdbm.h)
-dnl
-AC_DEFUN([OL_MDBM],
-[AC_REQUIRE([OL_LIB_MDBM])
- AC_CHECK_HEADERS(mdbm.h)
- AC_CACHE_CHECK(for db, [ol_cv_mdbm], [
-	if test $ol_cv_lib_mdbm = no || test $ac_cv_header_mdbm_h = no ; then
-		ol_cv_mdbm=no
-	else
-		ol_cv_mdbm=yes
-	fi
-])
- if test $ol_cv_mdbm = yes ; then
-	AC_DEFINE(HAVE_MDBM,1, [define if MDBM is available])
- fi
-])dnl
-dnl
-dnl ====================================================================
-dnl Check if NDBM library exists
-dnl Check for dbm_open in standard libraries or -lndbm or -ldbm
-dnl
-dnl defines ol_cv_lib_ndbm to 'yes' or '-lndbm' or -ldbm or 'no'
-dnl		'yes' implies ndbm_open is in $LIBS
-dnl
-dnl uses:
-dnl		AC_CHECK_FUNC(dbm_open)
-dnl		AC_CHECK_LIB(ndbm,dbm_open)
-dnl		AC_CHECK_LIB(dbm,dbm_open)
-dnl
-dnl restrictions:
-dnl		should also check SVR4 case: dbm_open() in -lucb but that
-dnl		would requiring dealing with -L/usr/ucblib
-dnl
-AC_DEFUN([OL_LIB_NDBM],
-[AC_CACHE_CHECK(for NDBM library, [ol_cv_lib_ndbm],
-[	ol_LIBS="$LIBS"
-	AC_CHECK_FUNC(dbm_open,[ol_cv_lib_ndbm=yes], [
-		AC_CHECK_LIB(ndbm,dbm_open,[ol_cv_lib_ndbm=-lndbm], [
-			AC_CHECK_LIB(dbm,dbm_open,[ol_cv_lib_ndbm=-ldbm],
-				[ol_cv_lib_ndbm=no])dnl
-		])
-	])
-	LIBS="$ol_LIBS"
-])
-])dnl
-dnl
-dnl --------------------------------------------------------------------
-dnl Check if NDBM exists
-dnl
-dnl defines ol_cv_ndbm to 'yes' or 'no'
-dnl 
-dnl uses:
-dnl		OL_LIB_NDBM
-dnl		AC_CHECK_HEADERS(ndbm.h)
-dnl
-dnl restrictions:
-dnl		Doesn't handle SVR4 case (see above)
-dnl
-AC_DEFUN([OL_NDBM],
-[AC_REQUIRE([OL_LIB_NDBM])
- AC_CHECK_HEADERS(ndbm.h)
- AC_CACHE_CHECK(for db, [ol_cv_ndbm], [
-	if test $ol_cv_lib_ndbm = no || test $ac_cv_header_ndbm_h = no ; then
-		ol_cv_ndbm=no
-	else
-		ol_cv_ndbm=yes
-	fi
-])
- if test $ol_cv_ndbm = yes ; then
-	AC_DEFINE(HAVE_NDBM,1, [define if NDBM is available])
- fi
-])dnl
-dnl
-dnl ====================================================================
 dnl Check POSIX Thread version 
 dnl
 dnl defines ol_cv_pthread_version to 4, 5, 6, 7, 8, 10, depending on the
@@ -1172,7 +1027,7 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include <errno.h>
-#ifdef WINNT
+#ifdef _WIN32
 #include <stdlib.h>
 #endif ]], [[char *c = (char *) *sys_errlist]])],[ol_cv_dcl_sys_errlist=yes
 	ol_cv_have_sys_errlist=yes],[ol_cv_dcl_sys_errlist=no])])
@@ -1444,17 +1299,16 @@
 dnl ====================================================================
 dnl check for SSL compatibility
 AC_DEFUN([OL_SSL_COMPAT],
-[AC_CACHE_CHECK([OpenSSL library version (CRL checking capability)], [ol_cv_ssl_crl_compat],[
-	AC_EGREP_CPP(__ssl_compat,[
+[AC_CACHE_CHECK([OpenSSL library version (CRL checking capability)],
+	[ol_cv_ssl_crl_compat],[
+		AC_EGREP_CPP(__ssl_compat,[
 #ifdef HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
-#else
-#include <ssl.h>
 #endif
 
 /* Require 0.9.7d+ */
 #if OPENSSL_VERSION_NUMBER >= 0x0090704fL
 	char *__ssl_compat = "0.9.7d";
 #endif
-	],	[ol_cv_ssl_crl_compat=yes], [ol_cv_ssl_crl_compat=no])])
+	], [ol_cv_ssl_crl_compat=yes], [ol_cv_ssl_crl_compat=no])])
 ])

Modified: openldap/trunk/build/rules.mk
===================================================================
--- openldap/trunk/build/rules.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/rules.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/rules.mk,v 1.12.2.4 2007/01/02 21:43:41 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/rules.mk,v 1.15.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/srv.mk
===================================================================
--- openldap/trunk/build/srv.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/srv.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/srv.mk,v 1.15.2.4 2007/01/02 21:43:41 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/srv.mk,v 1.18.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/top.mk
===================================================================
--- openldap/trunk/build/top.mk	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/top.mk	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/build/top.mk,v 1.93.2.11 2007/01/02 23:42:47 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/top.mk,v 1.103.2.4 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -149,14 +149,17 @@
 MANCOMPRESS=$(CAT)
 MANCOMPRESSSUFFIX=
 
+SOELIM=soelim
+
 INCLUDEDIR= $(top_srcdir)/include
 LDAP_INCPATH= -I$(LDAP_INCDIR) -I$(INCLUDEDIR)
 LDAP_LIBDIR= $(top_builddir)/libraries
 
 LUTIL_LIBS = @LUTIL_LIBS@
-LDBM_LIBS = @LDBM_LIBS@
 LTHREAD_LIBS = @LTHREAD_LIBS@
 
+BDB_LIBS = @BDB_LIBS@
+
 LDAP_LIBLBER_LA = $(LDAP_LIBDIR)/liblber/liblber.la
 LDAP_LIBLDAP_LA = $(LDAP_LIBDIR)/libldap/libldap.la
 LDAP_LIBLDAP_R_LA = $(LDAP_LIBDIR)/libldap_r/libldap_r.la
@@ -167,10 +170,8 @@
 
 LDAP_L = $(LDAP_LIBLUTIL_A) \
 	$(LDAP_LIBLDAP_LA) $(LDAP_LIBLBER_LA)
-SLURPD_L = $(LDAP_LIBLUTIL_A) \
-	$(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA)
 SLAPD_L = $(LDAP_LIBLUNICODE_A) $(LDAP_LIBREWRITE_A) \
-	$(SLURPD_L)
+	$(LDAP_LIBLUTIL_A) $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA)
 
 WRAP_LIBS = @WRAP_LIBS@
 # AutoConfig generated 
@@ -187,6 +188,7 @@
 TLS_LIBS = @TLS_LIBS@
 AUTH_LIBS = @AUTH_LIBS@
 SECURITY_LIBS = $(SASL_LIBS) $(KRB_LIBS) $(TLS_LIBS) $(AUTH_LIBS)
+ICU_LIBS = @ICU_LIBS@
 
 MODULES_CPPFLAGS = @SLAPD_MODULES_CPPFLAGS@
 MODULES_LDFLAGS = @SLAPD_MODULES_LDFLAGS@
@@ -197,8 +199,7 @@
 SLAPD_SQL_INCLUDES = @SLAPD_SQL_INCLUDES@
 SLAPD_SQL_LIBS = @SLAPD_SQL_LIBS@
 
-SLAPD_LIBS = @SLAPD_LIBS@ @SLAPD_PERL_LDFLAGS@ @SLAPD_SQL_LDFLAGS@ @SLAPD_SQL_LIBS@ @SLAPD_SLP_LIBS@ @SLAPD_GMP_LIBS@
-SLURPD_LIBS = @SLURPD_LIBS@
+SLAPD_LIBS = @SLAPD_LIBS@ @SLAPD_PERL_LDFLAGS@ @SLAPD_SQL_LDFLAGS@ @SLAPD_SQL_LIBS@ @SLAPD_SLP_LIBS@ @SLAPD_GMP_LIBS@ $(ICU_LIBS)
 
 # Our Defaults
 CC = $(AC_CC)

Modified: openldap/trunk/build/version.sh
===================================================================
--- openldap/trunk/build/version.sh	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/version.sh	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# $OpenLDAP: pkg/ldap/build/version.sh,v 1.14.2.3 2007/01/02 21:43:41 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/version.sh,v 1.16.2.2 2007/08/31 23:13:50 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/build/version.var
===================================================================
--- openldap/trunk/build/version.var	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/build/version.var	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# $OpenLDAP: pkg/ldap/build/version.var,v 1.7.2.94 2007/08/20 17:43:48 kurt Exp $
+# $OpenLDAP: pkg/ldap/build/version.var,v 1.9.2.19 2007/12/13 20:56:24 kurt Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -14,10 +14,10 @@
 ## <http://www.OpenLDAP.org/license.html>.
 ol_package=OpenLDAP
 ol_major=2
-ol_minor=3
-ol_patch=38
-ol_api_inc=20338
+ol_minor=4
+ol_patch=7
+ol_api_inc=20407
 ol_api_current=2
-ol_api_revision=26
-ol_api_age=2
-ol_release_date="2007/08/20"
+ol_api_revision=3
+ol_api_age=0
+ol_release_date="2007/12/14"

Modified: openldap/trunk/clients/Makefile.in
===================================================================
--- openldap/trunk/clients/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,7 @@
 # Clients Makefile.in for OpenLDAP
-# $OpenLDAP: pkg/ldap/clients/Makefile.in,v 1.14.2.4 2007/01/02 21:43:41 kurt Exp $
+# $OpenLDAP: pkg/ldap/clients/Makefile.in,v 1.17.2.2 2007/08/31 23:13:50 quanah Exp $
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
 ## All rights reserved.
 ##

Modified: openldap/trunk/clients/tools/Makefile.in
===================================================================
--- openldap/trunk/clients/tools/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,7 @@
 # Makefile for LDAP tools
-# $OpenLDAP: pkg/ldap/clients/tools/Makefile.in,v 1.39.2.5 2007/01/02 21:43:41 kurt Exp $
+# $OpenLDAP: pkg/ldap/clients/tools/Makefile.in,v 1.45.2.2 2007/08/31 23:13:50 quanah Exp $
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
@@ -12,9 +14,11 @@
 ## <http://www.OpenLDAP.org/license.html>.
 
 SRCS	= ldapsearch.c ldapmodify.c ldapdelete.c ldapmodrdn.c \
-		ldappasswd.c ldapwhoami.c ldapcompare.c common.c
+		ldappasswd.c ldapwhoami.c ldapcompare.c \
+		ldapexop.c common.c
 OBJS	= ldapsearch.o ldapmodify.o ldapdelete.o ldapmodrdn.o \
-		ldappasswd.o ldapwhoami.o ldapcompare.o common.o
+		ldappasswd.o ldapwhoami.o ldapcompare.o \
+		ldapexop.o common.o
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
@@ -25,10 +29,10 @@
 XXLIBS	= $(SECURITY_LIBS) $(LUTIL_LIBS)
 
 XSRCS	= ldsversion.c ldmversion.c lddversion.c ldrversion.c \
-	ldpversion.c ldwversion.c ldcversion.c
+	ldpversion.c ldwversion.c ldcversion.c ldeversion.c
 
 PROGRAMS = ldapsearch ldapmodify ldapdelete ldapmodrdn \
-	ldappasswd ldapwhoami ldapcompare
+	ldappasswd ldapwhoami ldapcompare ldapexop
 
 
 ldapsearch:	ldsversion.o
@@ -52,6 +56,9 @@
 ldapcompare: ldcversion.o
 	$(LTLINK) -o $@ ldapcompare.o common.o ldcversion.o $(LIBS)
 
+ldapexop: ldeversion.o
+	$(LTLINK) -o $@ ldapexop.o common.o ldeversion.o $(LIBS)
+
 ldsversion.c: Makefile
 	@-$(RM) $@
 	$(MKVERSION) $(MKVOPTS) ldapsearch > $@
@@ -94,6 +101,12 @@
 
 ldcversion.o: ldapcompare.o common.o $(XLIBS)
 
+ldeversion.c: Makefile
+	@-$(RM) $@
+	$(MKVERSION) $(MKVOPTS) ldapexop > $@
+
+ldeversion.o: ldapexop.o common.o $(XLIBS)
+
 install-local:	FORCE
 	-$(MKDIR) $(DESTDIR)$(bindir)
 	@(								\

Modified: openldap/trunk/clients/tools/common.c
===================================================================
--- openldap/trunk/clients/tools/common.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/common.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* common.c - common routines for the ldap client tools */
-/* $OpenLDAP: pkg/ldap/clients/tools/common.c,v 1.39.2.13 2007/08/13 20:03:51 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/clients/tools/common.c,v 1.78.2.4 2007/08/31 23:13:50 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -29,8 +29,11 @@
 #include <ac/stdlib.h>
 #include <ac/signal.h>
 #include <ac/string.h>
+#include <ac/ctype.h>
 #include <ac/unistd.h>
 #include <ac/errno.h>
+#include <ac/time.h>
+#include <ac/socket.h>
 
 #ifdef HAVE_CYRUS_SASL
 #ifdef HAVE_SASL_SASL_H
@@ -42,77 +45,170 @@
 
 #include <ldap.h>
 
+#include "ldif.h"
+#include "lutil.h"
 #include "lutil_ldap.h"
 #include "ldap_defaults.h"
 #include "ldap_pvt.h"
 #include "lber_pvt.h"
-#include "lutil.h"
-#include "ldif.h"
 
 #include "common.h"
 
+/* input-related vars */
 
-int   authmethod = -1;
-char *binddn = NULL;
-int   contoper = 0;
-int   debug = 0;
-char *infile = NULL;
-char *ldapuri = NULL;
-char *ldaphost = NULL;
-int   ldapport = 0;
+/* misc. parameters */
+tool_type_t	tool_type;
+int		contoper = 0;
+int		debug = 0;
+char		*infile = NULL;
+int		dont = 0;
+int		referrals = 0;
+int		verbose = 0;
+int		ldif = 0;
+char		*prog = NULL;
+
+/* connection */
+char		*ldapuri = NULL;
+char		*ldaphost = NULL;
+int  		ldapport = 0;
+int		use_tls = 0;
+int		protocol = -1;
+int		version = 0;
+
+/* authc/authz */
+int		authmethod = -1;
+char		*binddn = NULL;
+int		want_bindpw = 0;
+struct berval	passwd = { 0, NULL };
+char		*pw_file = NULL;
 #ifdef HAVE_CYRUS_SASL
-unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
-char	*sasl_realm = NULL;
-char	*sasl_authc_id = NULL;
-char	*sasl_authz_id = NULL;
-char	*sasl_mech = NULL;
-char	*sasl_secprops = NULL;
+unsigned	sasl_flags = LDAP_SASL_AUTOMATIC;
+char		*sasl_realm = NULL;
+char		*sasl_authc_id = NULL;
+char		*sasl_authz_id = NULL;
+char		*sasl_mech = NULL;
+char		*sasl_secprops = NULL;
 #endif
-int   use_tls = 0;
 
-int	  assertctl;
-char *assertion = NULL;
-char *authzid = NULL;
-int   manageDIT = 0;
-int   manageDSAit = 0;
-int   noop = 0;
-int   ppolicy = 0;
-int   preread = 0;
-char *preread_attrs = NULL;
-int   postread = 0;
-char *postread_attrs = NULL;
-
-int   not = 0;
-int   want_bindpw = 0;
-struct berval passwd = { 0, NULL };
-char *pw_file = NULL;
-int   referrals = 0;
-int   protocol = -1;
-int   verbose = 0;
-int   ldif = 0;
-int   version = 0;
-
+/* controls */
+int		assertctl;
+char		*assertion = NULL;
+char		*authzid = NULL;
+/* support deprecated early version of proxyAuthz */
+#define LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ	"2.16.840.1.113730.3.4.12"
+#ifdef LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ
+char		*proxydn = NULL;
+#endif /* LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ */
+int		manageDIT = 0;
+int		manageDSAit = 0;
+int		noop = 0;
+int		ppolicy = 0;
+int		preread = 0;
+static char	*preread_attrs = NULL;
+int		postread = 0;
+static char	*postread_attrs = NULL;
+ber_int_t	pr_morePagedResults = 1;
+struct berval	pr_cookie = { 0, NULL };
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-int chaining = 0;
-static int chainingResolve = -1;
-static int chainingContinuation = -1;
+int		chaining = 0;
+static int	chainingResolve = -1;
+static int	chainingContinuation = -1;
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+static int	sessionTracking = 0;
+struct berval	stValue;
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
 
-static int gotintr;
-static int abcan;
+LDAPControl	*unknown_ctrls = NULL;
+int		unknown_ctrls_num = 0;
 
+/* options */
+struct timeval	nettimeout = { -1 , 0 };
+
+typedef int (*print_ctrl_fn)( LDAP *ld, LDAPControl *ctrl );
+
+static int print_preread( LDAP *ld, LDAPControl *ctrl );
+static int print_postread( LDAP *ld, LDAPControl *ctrl );
+static int print_paged_results( LDAP *ld, LDAPControl *ctrl );
+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
+static int print_ppolicy( LDAP *ld, LDAPControl *ctrl );
+#endif
+
+static struct tool_ctrls_t {
+	const char	*oid;
+	unsigned	mask;
+	print_ctrl_fn	func;
+} tool_ctrl_response[] = {
+	{ LDAP_CONTROL_PRE_READ,			TOOL_ALL,	print_preread },
+	{ LDAP_CONTROL_POST_READ,			TOOL_ALL,	print_postread },
+	{ LDAP_CONTROL_PAGEDRESULTS,			TOOL_SEARCH,	print_paged_results },
+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
+	{ LDAP_CONTROL_PASSWORDPOLICYRESPONSE,		TOOL_ALL,	print_ppolicy },
+#endif
+	{ NULL,						0,		NULL }
+};
+
+/* "features" */
+static int	gotintr;
+static int	abcan;
+
+
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+static int
+st_value( LDAP *ld, struct berval *value )
+{
+	char		*ip = NULL, *name = NULL;
+	struct berval	id = { 0 };
+	char		namebuf[ MAXHOSTNAMELEN ];
+
+	if ( gethostname( namebuf, sizeof( namebuf ) ) == 0 ) {
+		struct hostent	*h;
+		struct in_addr	addr;
+
+		name = namebuf;
+
+		h = gethostbyname( name );
+		if ( h != NULL ) {
+			AC_MEMCPY( &addr, h->h_addr, sizeof( addr ) );
+			ip = inet_ntoa( addr );
+		}
+	}
+
+#ifdef HAVE_CYRUS_SASL
+	if ( sasl_authz_id != NULL ) {
+		ber_str2bv( sasl_authz_id, 0, 0, &id );
+
+	} else if ( sasl_authc_id != NULL ) {
+		ber_str2bv( sasl_authc_id, 0, 0, &id );
+
+	} else 
+#endif /* HAVE_CYRUS_SASL */
+	if ( binddn != NULL ) {
+		ber_str2bv( binddn, 0, 0, &id );
+	}
+
+	if ( ldap_create_session_tracking_value( ld,
+		ip, name, LDAP_CONTROL_X_SESSION_TRACKING_USERNAME,
+		&id, &stValue ) )
+	{
+		fprintf( stderr, _("Session tracking control encoding error!\n") );
+		return -1;
+	}
+
+	return 0;
+}
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
+
 RETSIGTYPE
 do_sig( int sig )
 {
 	gotintr = abcan;
 }
 
-/* Set in main() */
-char *prog = NULL;
-
 void
-tool_init( void )
+tool_init( tool_type_t type )
 {
+	tool_type = type;
 	ldap_pvt_setlocale(LC_MESSAGES, "");
 	ldap_pvt_bindtextdomain(OPENLDAP_PACKAGE, LDAP_LOCALEDIR);
 	ldap_pvt_textdomain(OPENLDAP_PACKAGE);
@@ -134,37 +230,45 @@
 {
 	static const char *const descriptions[] = {
 N_("  -c         continuous operation mode (do not stop on errors)\n"),
-N_("  -C         chase referrals (anonymously)\n"),
 N_("  -d level   set LDAP debugging level to `level'\n"),
 N_("  -D binddn  bind DN\n"),
 N_("  -e [!]<ext>[=<extparam>] general extensions (! indicates criticality)\n")
-N_("             [!]assert=<filter>     (an RFC 2254 Filter)\n")
+N_("             [!]assert=<filter>     (a RFC 4515 Filter string)\n")
 N_("             [!]authzid=<authzid>   (\"dn:<dn>\" or \"u:<user>\")\n")
+#ifdef LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ
+#if 0
+                 /* non-advertized support for proxyDN */
+N_("             [!]proxydn=<dn>        (a RFC 4514 DN string)\n")
+#endif
+#endif
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 N_("             [!]chaining[=<resolveBehavior>[/<continuationBehavior>]]\n")
 N_("                     one of \"chainingPreferred\", \"chainingRequired\",\n")
 N_("                     \"referralsPreferred\", \"referralsRequired\"\n")
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
-#ifdef LDAP_DEVEL
-N_("             [!]manageDIT\n")
-#endif
 N_("             [!]manageDSAit\n")
 N_("             [!]noop\n")
 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
 N_("             ppolicy\n")
 #endif
 N_("             [!]postread[=<attrs>]  (a comma-separated attribute list)\n")
-N_("             [!]preread[=<attrs>]   (a comma-separated attribute list)\n"),
-N_("             abandon, cancel (SIGINT sends abandon/cancel; not really controls)\n")
+N_("             [!]preread[=<attrs>]   (a comma-separated attribute list)\n")
+N_("             [!]relax\n")
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+N_("             [!]sessiontracking\n")
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
+N_("             abandon, cancel, ignore (SIGINT sends abandon/cancel,\n"
+   "             or ignores response; if critical, doesn't wait for SIGINT.\n"
+   "             not really controls)\n")
 N_("  -f file    read operations from `file'\n"),
 N_("  -h host    LDAP server\n"),
 N_("  -H URI     LDAP Uniform Resource Identifier(s)\n"),
 N_("  -I         use SASL Interactive mode\n"),
-N_("  -k         use Kerberos authentication\n"),
-N_("  -K         like -k, but do only step 1 of the Kerberos bind\n"),
 N_("  -M         enable Manage DSA IT control (-MM to make critical)\n"),
 N_("  -n         show what would be done but don't actually do it\n"),
 N_("  -O props   SASL security properties\n"),
+N_("  -o <opt>[=<optparam] general options\n"),
+N_("             nettimeout=<timeout> (in seconds, or \"none\" or \"max\")\n"),
 N_("  -p port    port on LDAP server\n"),
 N_("  -P version protocol version (default: 3)\n"),
 N_("  -Q         use SASL Quiet mode\n"),
@@ -192,11 +296,11 @@
 }
 
 void tool_perror(
-	char *func,
+	const char *func,
 	int err,
-	char *extra,
-	char *matched,
-	char *info,
+	const char *extra,
+	const char *matched,
+	const char *info,
 	char **refs )
 {
 	fprintf( stderr, "%s: %s (%d)%s\n",
@@ -250,7 +354,7 @@
 			}
 			binddn = ber_strdup( optarg );
 			break;
-		case 'e': /* general extensions (controls and such) */
+		case 'e':	/* general extensions (controls and such) */
 			/* should be extended to support comma separated list of
 			 *	[!]key[=value] parameters, e.g.  -e !foo,bar=567
 			 */
@@ -287,6 +391,12 @@
 					fprintf( stderr, "authzid control previously specified\n");
 					exit( EXIT_FAILURE );
 				}
+#ifdef LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ
+				if( proxydn != NULL ) {
+					fprintf( stderr, "authzid control incompatible with proxydn\n");
+					exit( EXIT_FAILURE );
+				}
+#endif /* LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ */
 				if( cvalue == NULL ) {
 					fprintf( stderr, "authzid: control value expected\n" );
 					usage();
@@ -299,15 +409,40 @@
 				assert( authzid == NULL );
 				authzid = cvalue;
 
-			} else if ( strcasecmp( control, "manageDIT" ) == 0 ) {
+#ifdef LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ
+			} else if ( strcasecmp( control, "proxydn" ) == 0 ) {
+				if( proxydn != NULL ) {
+					fprintf( stderr, "proxydn control previously specified\n");
+					exit( EXIT_FAILURE );
+				}
+				if( authzid != NULL ) {
+					fprintf( stderr, "proxydn control incompatible with authzid\n");
+					exit( EXIT_FAILURE );
+				}
+				if( cvalue == NULL ) {
+					fprintf( stderr, "proxydn: control value expected\n" );
+					usage();
+				}
+				if( !crit ) {
+					fprintf( stderr, "proxydn: must be marked critical\n" );
+					usage();
+				}
+
+				assert( proxydn == NULL );
+				proxydn = cvalue;
+#endif /* LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ */
+
+			} else if ( ( strcasecmp( control, "relax" ) == 0 ) ||
+				( strcasecmp( control, "manageDIT" ) == 0 ) )
+			{
 				if( manageDIT ) {
 					fprintf( stderr,
-						"manageDIT control previously specified\n");
+						"relax control previously specified\n");
 					exit( EXIT_FAILURE );
 				}
 				if( cvalue != NULL ) {
 					fprintf( stderr,
-						"manageDIT: no control value expected\n" );
+						"relax: no control value expected\n" );
 					usage();
 				}
 
@@ -424,10 +559,71 @@
 			/* this shouldn't go here, really; but it's a feature... */
 			} else if ( strcasecmp( control, "abandon" ) == 0 ) {
 				abcan = LDAP_REQ_ABANDON;
+				if ( crit ) {
+					gotintr = abcan;
+				}
 
 			} else if ( strcasecmp( control, "cancel" ) == 0 ) {
 				abcan = LDAP_REQ_EXTENDED;
+				if ( crit ) {
+					gotintr = abcan;
+				}
 
+			} else if ( strcasecmp( control, "ignore" ) == 0 ) {
+				abcan = -1;
+				if ( crit ) {
+					gotintr = abcan;
+				}
+
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+			} else if ( strcasecmp( control, "sessiontracking" ) == 0 ) {
+				if ( sessionTracking ) {
+					fprintf( stderr, "%s: session tracking can be only specified once\n", prog );
+					exit( EXIT_FAILURE );
+				}
+				sessionTracking = 1;
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
+
+			} else if ( tool_is_oid( control ) ) {
+				LDAPControl	*tmpctrls, ctrl;
+
+				tmpctrls = (LDAPControl *)realloc( unknown_ctrls,
+					(unknown_ctrls_num + 1)*sizeof( LDAPControl ) );
+				if ( tmpctrls == NULL ) {
+					fprintf( stderr, "%s: no memory?\n", prog );
+					exit( EXIT_FAILURE );
+				}
+				unknown_ctrls = tmpctrls;
+				ctrl.ldctl_oid = control;
+				ctrl.ldctl_value.bv_val = NULL;
+				ctrl.ldctl_value.bv_len = 0;
+				ctrl.ldctl_iscritical = crit;
+
+				if ( cvalue != NULL ) {
+					struct berval	bv;
+					size_t		len = strlen( cvalue );
+					int		retcode;
+
+					bv.bv_len = LUTIL_BASE64_DECODE_LEN( len );
+					bv.bv_val = ber_memalloc( bv.bv_len + 1 );
+
+					retcode = lutil_b64_pton( cvalue,
+						(unsigned char *)bv.bv_val,
+						bv.bv_len );
+
+					if ( retcode == -1 || retcode > bv.bv_len ) {
+						fprintf( stderr, "Unable to parse value of general control %s\n",
+							control );
+						usage();
+					}
+
+					bv.bv_len = retcode;
+					ctrl.ldctl_value = bv;
+				}
+
+				unknown_ctrls[ unknown_ctrls_num ] = ctrl;
+				unknown_ctrls_num++;
+
 			} else {
 				fprintf( stderr, "Invalid general control name: %s\n",
 					control );
@@ -471,39 +667,52 @@
 				prog );
 			exit( EXIT_FAILURE );
 #endif
-		case 'k':	/* kerberos bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-			if( authmethod != -1 ) {
-				fprintf( stderr, "%s: -k incompatible with previous "
-					"authentication choice\n", prog );
-				exit( EXIT_FAILURE );
-			}
-			authmethod = LDAP_AUTH_KRBV4;
-#else
-			fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-			exit( EXIT_FAILURE );
-#endif
-			break;
-		case 'K':	/* kerberos bind, part one only */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-			if( authmethod != -1 ) {
-				fprintf( stderr, "%s: incompatible with previous "
-					"authentication choice\n", prog );
-				exit( EXIT_FAILURE );
-			}
-			authmethod = LDAP_AUTH_KRBV41;
-#else
-			fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
-			exit( EXIT_FAILURE );
-#endif
-			break;
 		case 'M':
 			/* enable Manage DSA IT */
 			manageDSAit++;
 			break;
 		case 'n':	/* print operations, don't actually do them */
-			not++;
+			dont++;
 			break;
+		case 'o':
+			control = ber_strdup( optarg );
+			if ( (cvalue = strchr( control, '=' )) != NULL ) {
+				*cvalue++ = '\0';
+			}
+
+			if ( strcasecmp( control, "nettimeout" ) == 0 ) {
+				if( nettimeout.tv_sec != -1 ) {
+					fprintf( stderr, "nettimeout option previously specified\n");
+					exit( EXIT_FAILURE );
+				}
+				if( cvalue == NULL || cvalue[0] == '\0' ) {
+					fprintf( stderr, "nettimeout: option value expected\n" );
+					usage();
+				}
+		 		if ( strcasecmp( cvalue, "none" ) == 0 ) {
+		 			nettimeout.tv_sec = 0;
+		 		} else if ( strcasecmp( cvalue, "max" ) == 0 ) {
+		 			nettimeout.tv_sec = LDAP_MAXINT;
+		 		} else {
+		 			ival = strtol( cvalue, &next, 10 );
+		 			if ( next == NULL || next[0] != '\0' ) {
+		 				fprintf( stderr,
+		 					_("Unable to parse network timeout \"%s\"\n"), cvalue );
+		 				exit( EXIT_FAILURE );
+		 			}
+		 			nettimeout.tv_sec = ival;
+		 		}
+		 		if( nettimeout.tv_sec < 0 || nettimeout.tv_sec > LDAP_MAXINT ) {
+		 			fprintf( stderr, _("%s: invalid network timeout (%ld) specified\n"),
+		 				prog, (long)nettimeout.tv_sec );
+	 				exit( EXIT_FAILURE );
+ 				}
+			} else {
+				fprintf( stderr, "Invalid general option name: %s\n",
+					control );
+				usage();
+			}
+			break;
 		case 'O':
 #ifdef HAVE_CYRUS_SASL
 			if( sasl_secprops != NULL ) {
@@ -779,11 +988,18 @@
 			exit( EXIT_FAILURE );
 		}
 	}
+
 	if( protocol == LDAP_VERSION2 ) {
 		if( assertctl || authzid || manageDIT || manageDSAit ||
+#ifdef LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ
+			proxydn ||
+#endif /* LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ */
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 			chaining ||
 #endif
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+			sessionTracking ||
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
 			noop || ppolicy || preread || postread )
 		{
 			fprintf( stderr, "%s: -e/-M incompatible with LDAPv2\n", prog );
@@ -802,20 +1018,12 @@
 			exit( EXIT_FAILURE );
 		}
 #endif
-	} else {
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-		if ( authmethod == LDAP_AUTH_KRBV4 || authmethod == LDAP_AUTH_KRBV41 ) {
-			fprintf( stderr, "%s: -k/-K incompatible with LDAPv%d\n",
-				prog, protocol );
-			exit( EXIT_FAILURE );
-		}
-#endif
 	}
 }
 
 
 LDAP *
-tool_conn_setup( int not, void (*private_setup)( LDAP * ) )
+tool_conn_setup( int dont, void (*private_setup)( LDAP * ) )
 {
 	LDAP *ld = NULL;
 
@@ -842,7 +1050,7 @@
 		SIGNAL( SIGINT, do_sig );
 	}
 
-	if ( !not ) {
+	if ( !dont ) {
 		int rc;
 
 		if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
@@ -856,6 +1064,137 @@
 			url.lud_scope = LDAP_SCOPE_DEFAULT;
 
 			ldapuri = ldap_url_desc2str( &url );
+
+		} else if ( ldapuri != NULL ) {
+			LDAPURLDesc	*ludlist, **ludp;
+			char		**urls = NULL;
+			int		nurls = 0;
+
+			rc = ldap_url_parselist( &ludlist, ldapuri );
+			if ( rc != LDAP_URL_SUCCESS ) {
+				fprintf( stderr,
+					"Could not parse LDAP URI(s)=%s (%d)\n",
+					ldapuri, rc );
+				exit( EXIT_FAILURE );
+			}
+
+			for ( ludp = &ludlist; *ludp != NULL; ) {
+				LDAPURLDesc	*lud = *ludp;
+				char		**tmp;
+
+				if ( lud->lud_dn != NULL && lud->lud_dn[ 0 ] != '\0' &&
+					( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) )
+				{
+					/* if no host but a DN is provided,
+					 * use DNS SRV to gather the host list
+					 * and turn it into a list of URIs
+					 * using the scheme provided */
+					char	*domain = NULL,
+						*hostlist = NULL,
+						**hosts = NULL;
+					int	i,
+						len_proto = strlen( lud->lud_scheme );
+
+					if ( ldap_dn2domain( lud->lud_dn, &domain )
+						|| domain == NULL )
+					{
+						fprintf( stderr,
+							"DNS SRV: Could not turn "
+							"DN=\"%s\" into a domain\n",
+							lud->lud_dn );
+						goto dnssrv_free;
+					}
+					
+					rc = ldap_domain2hostlist( domain, &hostlist );
+					if ( rc ) {
+						fprintf( stderr,
+							"DNS SRV: Could not turn "
+							"domain=%s into a hostlist\n",
+							domain );
+						goto dnssrv_free;
+					}
+
+					hosts = ldap_str2charray( hostlist, " " );
+					if ( hosts == NULL ) {
+						fprintf( stderr,
+							"DNS SRV: Could not parse "
+							"hostlist=\"%s\"\n",
+							hostlist );
+						goto dnssrv_free;
+					}
+
+					for ( i = 0; hosts[ i ] != NULL; i++ )
+						/* count'em */ ;
+
+					tmp = (char **)realloc( urls, sizeof( char * ) * ( nurls + i + 1 ) );
+					if ( tmp == NULL ) {
+						fprintf( stderr,
+							"DNS SRV: out of memory?\n" );
+						goto dnssrv_free;
+					}
+					urls = tmp;
+					urls[ nurls ] = NULL;
+
+					for ( i = 0; hosts[ i ] != NULL; i++ ) {
+						size_t	len = len_proto
+							+ STRLENOF( "://" )
+							+ strlen( hosts[ i ] )
+							+ 1;
+
+						urls[ nurls + i + 1 ] = NULL;
+						urls[ nurls + i ] = (char *)malloc( sizeof( char ) * len );
+						if ( urls[ nurls + i ] == NULL ) {
+							fprintf( stderr,
+								"DNS SRV: out of memory?\n" );
+							goto dnssrv_free;
+						}
+
+						snprintf( urls[ nurls + i ], len, "%s://%s",
+							lud->lud_scheme, hosts[ i ] );
+					}
+					nurls += i;
+
+dnssrv_free:;
+					ber_memvfree( (void **)hosts );
+					ber_memfree( hostlist );
+					ber_memfree( domain );
+
+				} else {
+					tmp = (char **)realloc( urls, sizeof( char * ) * ( nurls + 2 ) );
+					if ( tmp == NULL ) {
+						fprintf( stderr,
+							"DNS SRV: out of memory?\n" );
+						break;
+					}
+					urls = tmp;
+					urls[ nurls + 1 ] = NULL;
+
+					urls[ nurls ] = ldap_url_desc2str( lud );
+					if ( urls[ nurls ] == NULL ) {
+						fprintf( stderr,
+							"DNS SRV: out of memory?\n" );
+						break;
+					}
+					nurls++;
+				}
+
+				*ludp = lud->lud_next;
+
+				lud->lud_next = NULL;
+				ldap_free_urldesc( lud );
+			}
+
+			if ( ludlist != NULL ) {
+				ldap_free_urllist( ludlist );
+				exit( EXIT_FAILURE );
+
+			} else if ( urls == NULL ) {
+				exit( EXIT_FAILURE );
+			}
+
+			ldap_memfree( ldapuri );
+			ldapuri = ldap_charray2str( urls, " " );
+			ber_memvfree( (void **)urls );
 		}
 
 		if ( verbose ) {
@@ -889,14 +1228,25 @@
 			exit( EXIT_FAILURE );
 		}
 
-		if ( use_tls &&
-			( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ))
-		{
-			ldap_perror( ld, "ldap_start_tls" );
-			if ( use_tls > 1 ) {
-				exit( EXIT_FAILURE );
+		if ( use_tls ) {
+			rc = ldap_start_tls_s( ld, NULL, NULL );
+			if ( rc != LDAP_SUCCESS ) {
+				tool_perror( "ldap_start_tls", rc, NULL, NULL, NULL, NULL );
+				if ( use_tls > 1 ) {
+					exit( EXIT_FAILURE );
+				}
 			}
 		}
+
+		if ( nettimeout.tv_sec > 0 ) {
+	 		if ( ldap_set_option( ld, LDAP_OPT_NETWORK_TIMEOUT, (void *) &nettimeout )
+				!= LDAP_OPT_SUCCESS )
+			{
+		 		fprintf( stderr, "Could not set LDAP_OPT_NETWORK_TIMEOUT %ld\n",
+					(long)nettimeout.tv_sec );
+	 			exit( EXIT_FAILURE );
+			}
+		}
 	}
 
 	return ld;
@@ -906,19 +1256,48 @@
 void
 tool_bind( LDAP *ld )
 {
+	LDAPControl	**sctrlsp = NULL;
+	LDAPControl	*sctrls[3];
+	LDAPControl	sctrl[3];
+	int		nsctrls = 0;
+
 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
 	if ( ppolicy ) {
-		LDAPControl *ctrls[2], c;
+		LDAPControl c;
 		c.ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYREQUEST;
 		c.ldctl_value.bv_val = NULL;
 		c.ldctl_value.bv_len = 0;
 		c.ldctl_iscritical = 0;
-		ctrls[0] = &c;
-		ctrls[1] = NULL;
-		ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
+		sctrl[nsctrls] = c;
+		sctrls[nsctrls] = &sctrl[nsctrls];
+		sctrls[++nsctrls] = NULL;
 	}
 #endif
 
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+	if ( sessionTracking ) {
+		LDAPControl c;
+
+		if (stValue.bv_val == NULL && st_value( ld, &stValue ) ) {
+			exit( EXIT_FAILURE );
+		}
+
+		c.ldctl_oid = LDAP_CONTROL_X_SESSION_TRACKING;
+		c.ldctl_iscritical = 0;
+		ber_dupbv( &c.ldctl_value, &stValue );
+
+		sctrl[nsctrls] = c;
+		sctrls[nsctrls] = &sctrl[nsctrls];
+		sctrls[++nsctrls] = NULL;
+	}
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
+
+	if ( nsctrls ) {
+		sctrlsp = sctrls;
+	}
+
+	assert( nsctrls < sizeof(sctrls)/sizeof(sctrls[0]) );
+
 	if ( authmethod == LDAP_AUTH_SASL ) {
 #ifdef HAVE_CYRUS_SASL
 		void *defaults;
@@ -932,7 +1311,7 @@
 				fprintf( stderr,
 					"Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
 					sasl_secprops );
-				exit( EXIT_FAILURE );
+				exit( LDAP_LOCAL_ERROR );
 			}
 		}
 
@@ -943,22 +1322,22 @@
 			passwd.bv_val,
 			sasl_authz_id );
 
-		rc = ldap_sasl_interactive_bind_s( ld, binddn,
-			sasl_mech, NULL, NULL,
-			sasl_flags, lutil_sasl_interact, defaults );
+		rc = ldap_sasl_interactive_bind_s( ld, binddn, sasl_mech,
+			sctrlsp,
+			NULL, sasl_flags, lutil_sasl_interact, defaults );
 
 		lutil_sasl_freedefs( defaults );
 		if( rc != LDAP_SUCCESS ) {
-			ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
-			exit( EXIT_FAILURE );
+			tool_perror( "ldap_sasl_interactive_bind_s",
+				rc, NULL, NULL, NULL, NULL );
+			exit( rc );
 		}
 #else
-		fprintf( stderr, "%s: not compiled with SASL support\n",
-			prog );
-		exit( EXIT_FAILURE );
+		fprintf( stderr, "%s: not compiled with SASL support\n", prog );
+		exit( LDAP_NOT_SUPPORTED );
 #endif
 	} else {
-		int msgid, err;
+		int msgid, err, rc;
 		LDAPMessage *result;
 		LDAPControl **ctrls;
 		char msgbuf[256];
@@ -968,22 +1347,27 @@
 
 		msgbuf[0] = 0;
 
-		msgid = ldap_bind( ld, binddn, passwd.bv_val, authmethod );
-		if ( msgid == -1 ) {
-			ldap_perror( ld, "ldap_bind" );
-			exit( EXIT_FAILURE );
+		{
+			/* simple bind */
+			rc = ldap_sasl_bind( ld, binddn, LDAP_SASL_SIMPLE, &passwd,
+				sctrlsp, NULL, &msgid );
+			if ( msgid == -1 ) {
+				tool_perror( "ldap_sasl_bind(SIMPLE)", rc,
+					NULL, NULL, NULL, NULL );
+				exit( rc );
+			}
 		}
 
-		if ( ldap_result( ld, msgid, 1, NULL, &result ) == -1 ) {
-			ldap_perror( ld, "ldap_result" );
-			exit( EXIT_FAILURE );
+		if ( ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1 ) {
+			tool_perror( "ldap_result", -1, NULL, NULL, NULL, NULL );
+			exit( LDAP_LOCAL_ERROR );
 		}
 
-		if ( ldap_parse_result( ld, result, &err, &matched, &info, &refs,
-			&ctrls, 1 ) != LDAP_SUCCESS )
-		{
-			ldap_perror( ld, "ldap_bind parse result" );
-			exit( EXIT_FAILURE );
+		rc = ldap_parse_result( ld, result, &err, &matched, &info, &refs,
+			&ctrls, 1 );
+		if ( rc != LDAP_SUCCESS ) {
+			tool_perror( "ldap_bind parse result", rc, NULL, matched, info, refs );
+			exit( LDAP_LOCAL_ERROR );
 		}
 
 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
@@ -992,8 +1376,8 @@
 			int expire, grace, len = 0;
 			LDAPPasswordPolicyError pErr = -1;
 			
-			ctrl = ldap_find_control( LDAP_CONTROL_PASSWORDPOLICYRESPONSE,
-				ctrls );
+			ctrl = ldap_control_find( LDAP_CONTROL_PASSWORDPOLICYRESPONSE,
+				ctrls, NULL );
 
 			if ( ctrl && ldap_parse_passwordpolicy_control( ld, ctrl,
 				&expire, &grace, &pErr ) == LDAP_SUCCESS )
@@ -1033,7 +1417,7 @@
 			if( info ) ber_memfree( info );
 			if( refs ) ber_memvfree( (void **)refs );
 
-			if ( err != LDAP_SUCCESS ) exit( EXIT_FAILURE );
+			if ( err != LDAP_SUCCESS ) exit( err );
 		}
 	}
 }
@@ -1056,9 +1440,34 @@
 tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
 {
 	int i = 0, j, crit = 0, err;
-	LDAPControl c[10], **ctrls;
+	LDAPControl c[16], **ctrls;
 
-	ctrls = (LDAPControl**) malloc(sizeof(c) + (count+1)*sizeof(LDAPControl*));
+	if ( ! ( assertctl
+		|| authzid
+#ifdef LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ
+		|| proxydn
+#endif /* LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ */
+		|| manageDIT
+		|| manageDSAit
+		|| noop
+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
+		|| ppolicy
+#endif
+		|| preread
+		|| postread
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
+		|| chaining
+#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+		|| sessionTracking
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
+		|| count
+		|| unknown_ctrls_num ) )
+	{
+		return;
+	}
+
+	ctrls = (LDAPControl**) malloc(sizeof(c) + (count + unknown_ctrls_num + 1)*sizeof(LDAPControl*));
 	if ( ctrls == NULL ) {
 		fprintf( stderr, "No memory\n" );
 		exit( EXIT_FAILURE );
@@ -1094,14 +1503,38 @@
 	}
 
 	if ( authzid ) {
-		c[i].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
 		c[i].ldctl_value.bv_val = authzid;
 		c[i].ldctl_value.bv_len = strlen( authzid );
+		c[i].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
 		c[i].ldctl_iscritical = 1;
 		ctrls[i] = &c[i];
 		i++;
 	}
 
+#ifdef LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ
+	/* NOTE: doesn't need an extra count because it's incompatible
+	 * with authzid */
+	if ( proxydn ) {
+		BerElementBuffer berbuf;
+		BerElement *ber = (BerElement *)&berbuf;
+		
+		ber_init2( ber, NULL, LBER_USE_DER );
+
+		if ( ber_printf( ber, "s", proxydn ) == LBER_ERROR ) {
+			exit( EXIT_FAILURE );
+		}
+
+		if ( ber_flatten2( ber, &c[i].ldctl_value, 0 ) == -1 ) {
+			exit( EXIT_FAILURE );
+		}
+
+		c[i].ldctl_oid = LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ;
+		c[i].ldctl_iscritical = 1;
+		ctrls[i] = &c[i];
+		i++;
+	}
+#endif /* LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ */
+
 	if ( manageDIT ) {
 		c[i].ldctl_oid = LDAP_CONTROL_MANAGEDIT;
 		BER_BVZERO( &c[i].ldctl_value );
@@ -1126,6 +1559,16 @@
 		i++;
 	}
 
+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
+	if ( ppolicy ) {
+		c[i].ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYREQUEST;
+		BER_BVZERO( &c[i].ldctl_value );
+		c[i].ldctl_iscritical = 0;
+		ctrls[i] = &c[i];
+		i++;
+	}
+#endif
+
 	if ( preread ) {
 		char berbuf[LBER_ELEMENT_SIZEOF];
 		BerElement *ber = (BerElement *)berbuf;
@@ -1232,9 +1675,27 @@
 	}
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+	if ( sessionTracking ) {
+		if ( stValue.bv_val == NULL && st_value( ld, &stValue ) ) {
+			exit( EXIT_FAILURE );
+		}
+
+		c[i].ldctl_oid = LDAP_CONTROL_X_SESSION_TRACKING;
+		c[i].ldctl_iscritical = 0;
+		ber_dupbv( &c[i].ldctl_value, &stValue );
+
+		ctrls[i] = &c[i];
+		i++;
+	}
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
+
 	while ( count-- ) {
 		ctrls[i++] = extra_c++;
 	}
+	for ( count = 0; count < unknown_ctrls_num; count++ ) {
+		ctrls[i++] = &unknown_ctrls[count];
+	}
 	ctrls[i] = NULL;
 
 	err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
@@ -1266,15 +1727,142 @@
 		return -1;
 
 	case LDAP_REQ_ABANDON:
-		rc = ldap_abandon( ld, msgid );
+		rc = ldap_abandon_ext( ld, msgid, NULL, NULL );
 		fprintf( stderr, "got interrupt, abandon got %d: %s\n",
 				rc, ldap_err2string( rc ) );
 		return -1;
+
+	case -1:
+		/* just unbind, ignoring the request */
+		return -1;
 	}
 
 	return 0;
 }
 
+static int
+print_prepostread( LDAP *ld, LDAPControl *ctrl, struct berval *what)
+{
+	BerElement	*ber;
+	struct berval	bv;
+
+	tool_write_ldif( LDIF_PUT_COMMENT, "==> ",
+		what->bv_val, what->bv_len );
+	ber = ber_init( &ctrl->ldctl_value );
+	if ( ber == NULL ) {
+		/* error? */
+		return 1;
+
+	} else if ( ber_scanf( ber, "{m{" /*}}*/, &bv ) == LBER_ERROR ) {
+		/* error? */
+		return 1;
+
+	} else {
+		tool_write_ldif( LDIF_PUT_VALUE, "dn", bv.bv_val, bv.bv_len );
+
+		while ( ber_scanf( ber, "{m" /*}*/, &bv ) != LBER_ERROR ) {
+			int		i;
+			BerVarray	vals = NULL;
+
+			if ( ber_scanf( ber, "[W]", &vals ) == LBER_ERROR ||
+				vals == NULL )
+			{
+				/* error? */
+				return 1;
+			}
+		
+			for ( i = 0; vals[ i ].bv_val != NULL; i++ ) {
+				tool_write_ldif(
+					ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
+					bv.bv_val, vals[ i ].bv_val, vals[ i ].bv_len );
+			}
+
+			ber_bvarray_free( vals );
+		}
+	}
+
+	if ( ber != NULL ) {
+		ber_free( ber, 1 );
+	}
+
+	tool_write_ldif( LDIF_PUT_COMMENT, "<== ",
+		what->bv_val, what->bv_len );
+
+	return 0;
+}
+
+static int
+print_preread( LDAP *ld, LDAPControl *ctrl )
+{
+	static struct berval what = BER_BVC( "preread" );
+
+	return print_prepostread( ld, ctrl, &what );
+}
+
+static int
+print_postread( LDAP *ld, LDAPControl *ctrl )
+{
+	static struct berval what = BER_BVC( "postread" );
+
+	return print_prepostread( ld, ctrl, &what );
+}
+
+static int
+print_paged_results( LDAP *ld, LDAPControl *ctrl )
+{
+	ber_int_t estimate;
+
+	/* note: pr_cookie is being malloced; it's freed
+	 * the next time the control is sent, but the last
+	 * time it's not; we don't care too much, because
+	 * the last time an empty value is returned... */
+	if ( ldap_parse_pageresponse_control( ld, ctrl, &estimate, &pr_cookie )
+		!= LDAP_SUCCESS )
+	{
+		/* error? */
+		return 1;
+
+	} else {
+		/* FIXME: check buffer overflow */
+		char	buf[ BUFSIZ ], *ptr = buf;
+
+		if ( estimate > 0 ) {
+			ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ),
+				"estimate=%d", estimate );
+		}
+
+		if ( pr_cookie.bv_len > 0 ) {
+			struct berval	bv;
+
+			bv.bv_len = LUTIL_BASE64_ENCODE_LEN(
+				pr_cookie.bv_len ) + 1;
+			bv.bv_val = ber_memalloc( bv.bv_len + 1 );
+
+			bv.bv_len = lutil_b64_ntop(
+				(unsigned char *) pr_cookie.bv_val,
+				pr_cookie.bv_len,
+				bv.bv_val, bv.bv_len );
+
+			ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ),
+				"%scookie=%s", ptr == buf ? "" : " ",
+				bv.bv_val );
+
+			ber_memfree( bv.bv_val );
+
+			pr_morePagedResults = 1;
+
+		} else {
+			ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ),
+				"%scookie=", ptr == buf ? "" : " " );
+		}
+
+		tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
+			"pagedresults", buf, ptr - buf );
+	}
+
+	return 0;
+}
+
 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
 static int
 print_ppolicy( LDAP *ld, LDAPControl *ctrl )
@@ -1326,6 +1914,13 @@
 		char *str;
 		int j;
 
+		/* FIXME: there might be cases where a control has NULL OID;
+		 * this makes little sense, especially when returned by the
+		 * server, but libldap happily allows it */
+		if ( ctrls[i]->ldctl_oid == NULL ) {
+			continue;
+		}
+
 		len = ldif ? 2 : 0;
 		len += strlen( ctrls[i]->ldctl_oid );
 
@@ -1334,7 +1929,7 @@
 			? sizeof("true") : sizeof("false");
 
 		/* convert to base64 */
-		if ( ctrls[i]->ldctl_value.bv_len ) {
+		if ( !BER_BVISNULL( &ctrls[i]->ldctl_value ) ) {
 			b64.bv_len = LUTIL_BASE64_ENCODE_LEN(
 				ctrls[i]->ldctl_value.bv_len ) + 1;
 			b64.bv_val = ber_memalloc( b64.bv_len + 1 );
@@ -1373,13 +1968,19 @@
 		}
 
 		/* known controls */
-		if ( 0 ) {
-			/* dummy */ ;
-#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
-		} else if ( strcmp( LDAP_CONTROL_PASSWORDPOLICYRESPONSE, ctrls[i]->ldctl_oid ) == 0 ) {
-			(void)print_ppolicy( ld, ctrls[i] );
-#endif
+		for ( j = 0; tool_ctrl_response[j].oid != NULL; j++ ) {
+			if ( strcmp( tool_ctrl_response[j].oid, ctrls[i]->ldctl_oid ) == 0 ) {
+				if ( !tool_ctrl_response[j].mask & tool_type ) {
+					/* this control should not appear
+					 * with this tool; warning? */
+				}
+				break;
+			}
 		}
+
+		if ( tool_ctrl_response[j].oid != NULL && tool_ctrl_response[j].func ) {
+			(void)tool_ctrl_response[j].func( ld, ctrls[i] );
+		}
 	}
 }
 
@@ -1398,3 +1999,34 @@
 	return( 0 );
 }
 
+int
+tool_is_oid( const char *s )
+{
+	int		first = 1;
+
+	if ( !isdigit( (unsigned char) s[ 0 ] ) ) {
+		return 0;
+	}
+
+	for ( ; s[ 0 ]; s++ ) {
+		if ( s[ 0 ] == '.' ) {
+			if ( s[ 1 ] == '\0' ) {
+				return 0;
+			}
+			first = 1;
+			continue;
+		}
+
+		if ( !isdigit( (unsigned char) s[ 0 ] ) ) {
+			return 0;
+		}
+
+		if ( first == 1 && s[ 0 ] == '0' && s[ 1 ] != '.' ) {
+			return 0;
+		}
+		first = 0;
+	}
+
+	return 1;
+}
+

Modified: openldap/trunk/clients/tools/common.h
===================================================================
--- openldap/trunk/clients/tools/common.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/common.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* common.h - common definitions for the ldap client tools */
-/* $OpenLDAP: pkg/ldap/clients/tools/common.h,v 1.11.2.8 2007/08/13 20:03:51 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/clients/tools/common.h,v 1.24.2.2 2007/08/31 23:13:50 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -24,57 +24,90 @@
 
 LDAP_BEGIN_DECL
 
-/* Defined and set in common.c */
-extern int   authmethod;
-extern char *binddn;
-extern int   contoper;
-extern int   debug;
-extern char *infile;
-extern char *ldapuri;
-extern char *ldaphost;
-extern int   ldapport;
+typedef enum tool_type_t {
+	TOOL_SEARCH	= 0x01U,
+	TOOL_COMPARE	= 0x02U,
+	TOOL_ADD	= 0x04U,
+	TOOL_DELETE	= 0x08U,
+	TOOL_MODIFY	= 0x10U,
+	TOOL_MODRDN	= 0x20U,
+
+	TOOL_EXOP	= 0x40U,
+
+	TOOL_WHOAMI	= TOOL_EXOP | 0x100U,
+	TOOL_PASSWD	= TOOL_EXOP | 0x200U,
+
+	TOOL_WRITE	= (TOOL_ADD|TOOL_DELETE|TOOL_MODIFY|TOOL_MODRDN),
+	TOOL_READ	= (TOOL_SEARCH|TOOL_COMPARE),
+
+	TOOL_ALL	= 0xFFU
+} tool_type_t;
+
+
+/* input-related vars */
+
+/* misc. parameters */
+extern tool_type_t	tool_type;
+extern int		contoper;
+extern int		debug;
+extern char		*infile;
+extern int		dont;
+extern int		referrals;
+extern int		verbose;
+extern int		ldif;
+extern char		*prog;
+
+/* connection */
+extern char		*ldapuri;
+extern char		*ldaphost;
+extern int		ldapport;
+extern int		use_tls;
+extern int		protocol;
+extern int		version;
+
+/* authc/authz */
+extern int		authmethod;
+extern char		*binddn;
+extern int		want_bindpw;
+extern struct berval	passwd;
+extern char		*pw_file;
 #ifdef HAVE_CYRUS_SASL
-extern unsigned sasl_flags;
-extern char	*sasl_realm;
-extern char	*sasl_authc_id;
-extern char	*sasl_authz_id;
-extern char	*sasl_mech;
-extern char	*sasl_secprops;
+extern unsigned		sasl_flags;
+extern char		*sasl_realm;
+extern char		*sasl_authc_id;
+extern char		*sasl_authz_id;
+extern char		*sasl_mech;
+extern char		*sasl_secprops;
 #endif
-extern int   use_tls;
 
-extern char *assertion;
-extern char *authzid;
-extern int   manageDIT;
-extern int   manageDSAit;
-extern int   noop;
-extern int   ppolicy;
-extern int	preread, postread;
+/* controls */
+extern char		*assertion;
+extern char		*authzid;
+extern int		manageDIT;
+extern int		manageDSAit;
+extern int		noop;
+extern int		ppolicy;
+extern int		preread, postread;
+extern ber_int_t	pr_morePagedResults;
+extern struct berval	pr_cookie;
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-extern int	chaining;
+extern int		chaining;
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
-extern int   not;
-extern int   want_bindpw;
-extern struct berval passwd;
-extern char *pw_file;
-extern int   referrals;
-extern int   protocol;
-extern int   verbose;
-extern int   ldif;
-extern int   version;
+/* options */
+extern struct timeval	nettimeout;
 
 /* Defined in common.c, set in main() */
-extern char *prog;
-extern const char __Version[];
+extern const char	__Version[];
 
 /* Defined in main program */
-extern const char options[];
+extern const char	options[];
+
 void usage LDAP_P(( void )) LDAP_GCCATTR((noreturn));
 int handle_private_option LDAP_P(( int i ));
 
 /* Defined in common.c */
-void tool_init LDAP_P(( void ));
+void tool_init LDAP_P(( tool_type_t type ));
 void tool_common_usage LDAP_P(( void ));
 void tool_args LDAP_P(( int, char ** ));
 LDAP *tool_conn_setup LDAP_P(( int dont, void (*private_setup)( LDAP * ) ));
@@ -84,15 +117,17 @@
 void tool_server_controls LDAP_P(( LDAP *, LDAPControl *, int ));
 int tool_check_abandon LDAP_P(( LDAP *ld, int msgid ));
 void tool_perror LDAP_P((
-	char *func,
+	const char *func,
 	int err,
-	char *extra,
-	char *matched,
-	char *info,
+	const char *extra,
+	const char *matched,
+	const char *info,
 	char **refs ));
 void tool_print_ctrls LDAP_P(( LDAP *ld, LDAPControl **ctrls ));
 int tool_write_ldif LDAP_P(( int type, char *name, char *value, ber_len_t vallen ));
+int tool_is_oid LDAP_P(( const char *s ));
 
+
 LDAP_END_DECL
 
 #endif /* _CLIENT_TOOLS_COMMON_H_ */

Modified: openldap/trunk/clients/tools/ldapcompare.c
===================================================================
--- openldap/trunk/clients/tools/ldapcompare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/ldapcompare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldapcompare.c -- LDAP compare tool */
-/* $OpenLDAP: pkg/ldap/clients/tools/ldapcompare.c,v 1.34.2.6 2007/08/13 18:04:39 quanah Exp $ */
+/* $OpenLDAP: pkg/ldap/clients/tools/ldapcompare.c,v 1.43.2.3 2007/08/31 23:13:50 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -46,6 +46,7 @@
 #include <ac/string.h>
 #include <ac/unistd.h>
 #include <ac/errno.h>
+#include <ac/socket.h>
 #include <ac/time.h>
 #include <sys/stat.h>
 
@@ -82,6 +83,8 @@
 	fprintf( stderr, _("  b64value\tbase64 encoding of assertion value\n"));
 
 	fprintf( stderr, _("Compare options:\n"));
+	fprintf( stderr, _("  -E [!]<ext>[=<extparam>] compare extensions (! indicates criticality)\n"));
+	fprintf( stderr, _("             !dontUseCopy                (Don't Use Copy)\n"));
 	fprintf( stderr, _("  -z         Quiet mode,"
 		" don't print anything, use return values\n"));
 	tool_common_usage();
@@ -99,15 +102,19 @@
 
 
 const char options[] = "z"
-	"Cd:D:e:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
+	"Cd:D:e:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
+#ifdef LDAP_CONTROL_DONTUSECOPY
+int dontUseCopy = 0;
+#endif
+
 int
 handle_private_option( int i )
 {
+	char	*control, *cvalue;
+	int		crit;
+
 	switch ( i ) {
-#if 0
-		char	*control, *cvalue;
-		int		crit;
 	case 'E': /* compare extensions */
 		if( protocol == LDAP_VERSION2 ) {
 			fprintf( stderr, _("%s: -E incompatible with LDAPv%d\n"),
@@ -126,13 +133,38 @@
 			optarg++;
 		}
 
-		control = strdup( optarg );
+		control = ber_strdup( optarg );
 		if ( (cvalue = strchr( control, '=' )) != NULL ) {
 			*cvalue++ = '\0';
 		}
-		fprintf( stderr, _("Invalid compare extension name: %s\n"), control );
-		usage();
+
+#ifdef LDAP_CONTROL_DONTUSECOPY
+		if ( strcasecmp( control, "dontUseCopy" ) == 0 ) {
+			if( dontUseCopy ) {
+				fprintf( stderr,
+					_("dontUseCopy control previously specified\n"));
+				exit( EXIT_FAILURE );
+			}
+			if( cvalue != NULL ) {
+				fprintf( stderr,
+					_("dontUseCopy: no control value expected\n") );
+				usage();
+			}
+			if( !crit ) {
+				fprintf( stderr,
+					_("dontUseCopy: critical flag required\n") );
+				usage();
+			}
+
+			dontUseCopy = 1 + crit;
+		} else
 #endif
+		{
+			fprintf( stderr,
+				_("Invalid compare extension name: %s\n"), control );
+			usage();
+		}
+		break;
 
 	case 'z':
 		quiet = 1;
@@ -148,13 +180,16 @@
 int
 main( int argc, char **argv )
 {
-	char	*compdn = NULL, *attrs = NULL;
-	char	*sep;
+	char		*compdn = NULL, *attrs = NULL;
+	char		*sep;
 	int		rc;
-	LDAP	*ld = NULL;
-	struct berval bvalue = { 0, NULL };
+	LDAP		*ld = NULL;
+	struct berval	bvalue = { 0, NULL };
+	int		i = 0; 
+	LDAPControl	c[1];
 
-	tool_init();
+
+	tool_init( TOOL_COMPARE );
 	prog = lutil_progname( "ldapcompare", argc, argv );
 
 	tool_args( argc, argv );
@@ -205,10 +240,25 @@
 
 	tool_bind( ld );
 
-	if ( assertion || authzid || manageDSAit || noop ) {
-		tool_server_controls( ld, NULL, 0 );
+	if ( 0
+#ifdef LDAP_CONTROL_DONTUSECOPY
+		|| dontUseCopy
+#endif
+		)
+	{
+#ifdef LDAP_CONTROL_DONTUSECOPY
+		if ( dontUseCopy ) {  
+			c[i].ldctl_oid = LDAP_CONTROL_DONTUSECOPY;
+			c[i].ldctl_value.bv_val = NULL;
+			c[i].ldctl_value.bv_len = 0;
+			c[i].ldctl_iscritical = dontUseCopy > 1;
+			i++;    
+		}
+#endif
 	}
 
+	tool_server_controls( ld, c, i );
+
 	if ( verbose ) {
 		fprintf( stderr, _("DN:%s, attr:%s, value:%s\n"),
 			compdn, attrs, sep );
@@ -240,7 +290,7 @@
 	char		**refs;
 	LDAPControl **ctrls = NULL;
 
-	if ( not ) {
+	if ( dont ) {
 		return LDAP_SUCCESS;
 	}
 
@@ -262,7 +312,7 @@
 
 		rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
 		if ( rc < 0 ) {
-			ldap_perror( ld, "ldapcompare: ldap_result" );
+			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 			return rc;
 		}
 

Modified: openldap/trunk/clients/tools/ldapdelete.c
===================================================================
--- openldap/trunk/clients/tools/ldapdelete.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/ldapdelete.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldapdelete.c - simple program to delete an entry using LDAP */
-/* $OpenLDAP: pkg/ldap/clients/tools/ldapdelete.c,v 1.109.2.7 2007/08/13 18:04:39 quanah Exp $ */
+/* $OpenLDAP: pkg/ldap/clients/tools/ldapdelete.c,v 1.118.2.4 2007/08/31 23:13:50 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -39,6 +39,7 @@
 #include <ac/ctype.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
+#include <ac/socket.h>
 #include <ac/time.h>
 
 #include <ldap.h>
@@ -75,7 +76,7 @@
 
 
 const char options[] = "r"
-	"cd:D:e:f:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
+	"cd:D:e:f:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
@@ -140,7 +141,7 @@
 
     fp = NULL;
 
-	tool_init();
+	tool_init( TOOL_DELETE );
     prog = lutil_progname( "ldapdelete", argc, argv );
 
 	tool_args( argc, argv );
@@ -170,13 +171,11 @@
 
 	tool_bind( ld );
 
-	if ( assertion || authzid || manageDIT || manageDSAit || noop ) {
-		tool_server_controls( ld, NULL, 0 );
-	}
+	tool_server_controls( ld, NULL, 0 );
 
 	retval = rc = 0;
 
-    if ( fp == NULL ) {
+	if ( fp == NULL ) {
 		for ( ; optind < argc; ++optind ) {
 			rc = dodelete( ld, argv[ optind ] );
 
@@ -216,10 +215,10 @@
 
 	if ( verbose ) {
 		printf( _("%sdeleting entry \"%s\"\n"),
-			(not ? "!" : ""), dn );
+			(dont ? "!" : ""), dn );
 	}
 
-	if ( not ) {
+	if ( dont ) {
 		return LDAP_SUCCESS;
 	}
 
@@ -247,7 +246,7 @@
 
 		rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
 		if ( rc < 0 ) {
-			ldap_perror( ld, "ldapdelete: ldap_result" );
+			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 			return rc;
 		}
 
@@ -324,7 +323,7 @@
 	rc = ldap_search_ext_s( ld, dn, LDAP_SCOPE_ONELEVEL, NULL, attrs, 1,
 		NULL, NULL, NULL, -1, &res );
 	if ( rc != LDAP_SUCCESS ) {
-		ldap_perror( ld, "ldap_search" );
+		tool_perror( "ldap_search", rc, NULL, NULL, NULL, NULL );
 		return( rc );
 	}
 
@@ -339,15 +338,15 @@
 			char *dn = ldap_get_dn( ld, e );
 
 			if( dn == NULL ) {
-				ldap_perror( ld, "ldap_prune" );
-				ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc );
+				ldap_get_option( ld, LDAP_OPT_RESULT_CODE, &rc );
+				tool_perror( "ldap_prune", rc, NULL, NULL, NULL, NULL );
 				ber_memfree( dn );
 				return rc;
 			}
 
 			rc = deletechildren( ld, dn );
 			if ( rc == -1 ) {
-				ldap_perror( ld, "ldap_prune" );
+				tool_perror( "ldap_prune", rc, NULL, NULL, NULL, NULL );
 				ber_memfree( dn );
 				return rc;
 			}
@@ -356,9 +355,9 @@
 				printf( _("\tremoving %s\n"), dn );
 			}
 
-			rc = ldap_delete_s( ld, dn );
+			rc = ldap_delete_ext_s( ld, dn, NULL, NULL );
 			if ( rc == -1 ) {
-				ldap_perror( ld, "ldap_delete" );
+				tool_perror( "ldap_delete", rc, NULL, NULL, NULL, NULL );
 				ber_memfree( dn );
 				return rc;
 
@@ -398,7 +397,7 @@
 	rc = ldap_search_ext_s( ld, dn, LDAP_SCOPE_ONELEVEL, NULL, attrs, 1,
 		ctrls, NULL, NULL, -1, &res_se );
 	if ( rc != LDAP_SUCCESS ) {
-		ldap_perror( ld, "ldap_search" );
+		tool_perror( "ldap_search", rc, NULL, NULL, NULL, NULL );
 		return( rc );
 	}
 	ber_free( ber, 1 );
@@ -414,8 +413,8 @@
 			char *dn = ldap_get_dn( ld, e );
 
 			if( dn == NULL ) {
-				ldap_perror( ld, "ldap_prune" );
-				ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc );
+				ldap_get_option( ld, LDAP_OPT_RESULT_CODE, &rc );
+				tool_perror( "ldap_prune", rc, NULL, NULL, NULL, NULL );
 				ber_memfree( dn );
 				return rc;
 			}
@@ -424,9 +423,9 @@
 				printf( _("\tremoving %s\n"), dn );
 			}
 
-			rc = ldap_delete_s( ld, dn );
+			rc = ldap_delete_ext_s( ld, dn, NULL, NULL );
 			if ( rc == -1 ) {
-				ldap_perror( ld, "ldap_delete" );
+				tool_perror( "ldap_delete", rc, NULL, NULL, NULL, NULL );
 				ber_memfree( dn );
 				return rc;
 

Copied: openldap/trunk/clients/tools/ldapexop.c (from rev 891, openldap/vendor/openldap-2.4.7/clients/tools/ldapexop.c)
===================================================================
--- openldap/trunk/clients/tools/ldapexop.c	                        (rev 0)
+++ openldap/trunk/clients/tools/ldapexop.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,364 @@
+/* ldapexop.c -- a tool for performing well-known extended operations */
+/* $OpenLDAP: pkg/ldap/clients/tools/ldapexop.c,v 1.9.2.2 2007/08/31 23:13:50 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2005-2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was originally developed by Pierangelo Masarati for inclusion
+ * in OpenLDAP Software based, in part, on other client tools.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/ctype.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+#include <ac/unistd.h>
+
+#include <ldap.h>
+#include "ldif.h"
+#include "lutil.h"
+#include "lutil_ldap.h"
+#include "ldap_defaults.h"
+
+#include "common.h"
+
+void
+usage( void )
+{
+	fprintf( stderr, _("Issue LDAP extended operations\n\n"));
+	fprintf( stderr, _("usage: %s [options] <oid|oid:data|oid::b64data>\n"), prog);
+	tool_common_usage();
+	exit( EXIT_FAILURE );
+}
+
+
+const char options[] = ""
+	"d:D:e:h:H:InO:o:p:QR:U:vVw:WxX:y:Y:Z";
+
+int
+handle_private_option( int i )
+{
+	switch ( i ) {
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+
+int
+main( int argc, char *argv[] )
+{
+	int		rc;
+
+	LDAP		*ld = NULL;
+
+	char		*matcheddn = NULL, *text = NULL, **refs = NULL;
+	LDAPControl **ctrls = NULL;
+	int		id, code;
+	LDAPMessage	*res;
+
+	tool_init( TOOL_EXOP );
+	prog = lutil_progname( "ldapexop", argc, argv );
+
+	/* LDAPv3 only */
+	protocol = LDAP_VERSION3;
+
+	tool_args( argc, argv );
+
+	if ( argc - optind < 1 ) {
+		usage();
+	}
+
+	if ( pw_file || want_bindpw ) {
+		if ( pw_file ) {
+			rc = lutil_get_filed_password( pw_file, &passwd );
+			if( rc ) return EXIT_FAILURE;
+		} else {
+			passwd.bv_val = getpassphrase( _("Enter LDAP Password: ") );
+			passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
+		}
+	}
+
+	ld = tool_conn_setup( 0, 0 );
+
+	tool_bind( ld );
+
+	argv += optind;
+	argc -= optind;
+
+	if ( strcasecmp( argv[ 0 ], "whoami" ) == 0 ) {
+		tool_server_controls( ld, NULL, 0 );
+
+		rc = ldap_whoami( ld, NULL, NULL, &id ); 
+		if ( rc != LDAP_SUCCESS ) {
+			tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
+			rc = EXIT_FAILURE;
+			goto skip;
+		}
+
+	} else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
+		int		cancelid;
+
+		switch ( argc ) {
+		case 2:
+			 if ( lutil_atoi( &cancelid, argv[ 1 ] ) != 0 || cancelid < 0 ) {
+				fprintf( stderr, "invalid cancelid=%s\n\n", argv[ 1 ] );
+				usage();
+			}
+			break;
+
+		default:
+			fprintf( stderr, "need cancelid\n\n" );
+			usage();
+		}
+
+		rc = ldap_cancel( ld, cancelid, NULL, NULL, &id );
+		if ( rc != LDAP_SUCCESS ) {
+			tool_perror( "ldap_cancel", rc, NULL, NULL, NULL, NULL );
+			rc = EXIT_FAILURE;
+			goto skip;
+		}
+
+	} else if ( strcasecmp( argv[ 0 ], "passwd" ) == 0 ) {
+		fprintf( stderr, "use ldappasswd(1) instead.\n\n", argv[ 0 ] );
+		usage();
+		/* TODO? */
+
+	} else if ( strcasecmp( argv[ 0 ], "refresh" ) == 0 ) {
+		int		ttl = 3600;
+		struct berval	dn;
+
+		switch ( argc ) {
+		case 3:
+			ttl = atoi( argv[ 2 ] );
+
+		case 2:
+			dn.bv_val = argv[ 1 ];
+			dn.bv_len = strlen( dn.bv_val );
+
+		case 1:
+			break;
+
+		default:
+			fprintf( stderr, _("need DN [ttl]\n\n") );
+			usage();
+		}
+		
+		tool_server_controls( ld, NULL, 0 );
+
+		rc = ldap_refresh( ld, &dn, ttl, NULL, NULL, &id ); 
+		if ( rc != LDAP_SUCCESS ) {
+			tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
+			rc = EXIT_FAILURE;
+			goto skip;
+		}
+
+	} else {
+		char *p;
+
+		if ( argc != 1 ) {
+			usage();
+		}
+
+		p = strchr( argv[ 0 ], ':' );
+		if ( p == argv[ 0 ] ) {
+			usage();
+		}
+
+		if ( p != NULL )
+			*p++ = '\0';
+
+		if ( tool_is_oid( argv[ 0 ] ) ) {
+			struct berval	reqdata;
+			struct berval	type;
+			struct berval	value;
+			int		freeval;
+
+			if ( p != NULL ) {
+				p[ -1 ] = ':';
+				ldif_parse_line2( argv[ 0 ], &type, &value, &freeval );
+				p[ -1 ] = '\0';
+
+				if ( freeval ) {
+					reqdata = value;
+				} else {
+					ber_dupbv( &reqdata, &value );
+				}
+			}
+
+
+			tool_server_controls( ld, NULL, 0 );
+
+			rc = ldap_extended_operation( ld, argv[ 0 ], p ? &reqdata : NULL, NULL, NULL, &id );
+			if ( rc != LDAP_SUCCESS ) {
+				tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
+				rc = EXIT_FAILURE;
+				goto skip;
+			}
+		} else {
+			fprintf( stderr, "unknown exop \"%s\"\n\n", argv[ 0 ] );
+			usage();
+		}
+	}
+
+	for ( ; ; ) {
+		struct timeval	tv;
+
+		if ( tool_check_abandon( ld, id ) ) {
+			return LDAP_CANCELLED;
+		}
+
+		tv.tv_sec = 0;
+		tv.tv_usec = 100000;
+
+		rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
+		if ( rc < 0 ) {
+			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
+			rc = EXIT_FAILURE;
+			goto skip;
+		}
+
+		if ( rc != 0 ) {
+			break;
+		}
+	}
+
+	rc = ldap_parse_result( ld, res,
+		&code, &matcheddn, &text, &refs, &ctrls, 0 );
+	if ( rc == LDAP_SUCCESS ) {
+		rc = code;
+	}
+
+	if ( rc != LDAP_SUCCESS ) {
+		tool_perror( "ldap_parse_result", rc, NULL, matcheddn, text, refs );
+		rc = EXIT_FAILURE;
+		goto skip;
+	}
+
+	if ( strcasecmp( argv[ 0 ], "whoami" ) == 0 ) {
+		char		*retoid = NULL;
+		struct berval	*retdata = NULL;
+
+		rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
+
+		if ( rc != LDAP_SUCCESS ) {
+			tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
+			rc = EXIT_FAILURE;
+			goto skip;
+		}
+
+		if ( retdata != NULL ) {
+			if ( retdata->bv_len == 0 ) {
+				printf(_("anonymous\n") );
+			} else {
+				printf("%s\n", retdata->bv_val );
+			}
+		}
+
+		ber_memfree( retoid );
+		ber_bvfree( retdata );
+
+	} else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
+		/* no extended response; returns specific errors */
+		assert( 0 );
+
+	} else if ( strcasecmp( argv[ 0 ], "passwd" ) == 0 ) {
+		/* TODO */
+
+	} else if ( strcasecmp( argv[ 0 ], "refresh" ) == 0 ) {
+		int	newttl;
+
+		rc = ldap_parse_refresh( ld, res, &newttl );
+
+		if ( rc != LDAP_SUCCESS ) {
+			tool_perror( "ldap_parse_refresh", rc, NULL, NULL, NULL, NULL );
+			rc = EXIT_FAILURE;
+			goto skip;
+		}
+
+		printf( "newttl=%d\n", newttl );
+
+	} else if ( tool_is_oid( argv[ 0 ] ) ) {
+		char		*retoid = NULL;
+		struct berval	*retdata = NULL;
+
+		if( ldif < 2 ) {
+			printf(_("# extended operation response\n"));
+		}
+
+		rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
+		if ( rc != LDAP_SUCCESS ) {
+			tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
+			rc = EXIT_FAILURE;
+			goto skip;
+		}
+
+		if ( ldif < 2 && retoid != NULL ) {
+			tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
+				"oid", retoid, strlen(retoid) );
+		}
+
+		ber_memfree( retoid );
+
+		if( retdata != NULL ) {
+			if ( ldif < 2 ) {
+				tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
+					"data", retdata->bv_val, retdata->bv_len );
+			}
+
+			ber_bvfree( retdata );
+		}
+	}
+
+	if( verbose || ( code != LDAP_SUCCESS ) || matcheddn || text || refs ) {
+		printf( _("Result: %s (%d)\n"), ldap_err2string( code ), code );
+
+		if( text && *text ) {
+			printf( _("Additional info: %s\n"), text );
+		}
+
+		if( matcheddn && *matcheddn ) {
+			printf( _("Matched DN: %s\n"), matcheddn );
+		}
+
+		if( refs ) {
+			int i;
+			for( i=0; refs[i]; i++ ) {
+				printf(_("Referral: %s\n"), refs[i] );
+			}
+		}
+	}
+
+    if (ctrls) {
+		tool_print_ctrls( ld, ctrls );
+		ldap_controls_free( ctrls );
+	}
+
+	ber_memfree( text );
+	ber_memfree( matcheddn );
+	ber_memvfree( (void **) refs );
+
+skip:
+	/* disconnect from server */
+	tool_unbind( ld );
+	tool_destroy();
+
+	return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
+}

Modified: openldap/trunk/clients/tools/ldapmodify.c
===================================================================
--- openldap/trunk/clients/tools/ldapmodify.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/ldapmodify.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,8 +1,9 @@
 /* ldapmodify.c - generic program to modify or add entries using LDAP */
-/* $OpenLDAP: pkg/ldap/clients/tools/ldapmodify.c,v 1.158.2.13 2007/08/13 20:03:51 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/clients/tools/ldapmodify.c,v 1.186.2.3 2007/08/31 23:13:50 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
+ * Portions Copyright 2006 Howard Chu.
  * Portions Copyright 1998-2003 Kurt D. Zeilenga.
  * Portions Copyright 1998-2001 Net Boolean Incorporated.
  * Portions Copyright 2001-2003 IBM Corporation.
@@ -32,6 +33,7 @@
  * include:
  *   Kurt D. Zeilenga
  *   Norbert Klasen
+ *   Howard Chu
  */
 
 #include "portable.h"
@@ -42,6 +44,7 @@
 #include <ac/ctype.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
+#include <ac/socket.h>
 #include <ac/time.h>
 
 #ifdef HAVE_SYS_STAT_H
@@ -63,44 +66,41 @@
 #include "ldap_defaults.h"
 #include "ldap_log.h"
 #include "ldap_pvt.h"
+#include "lber_pvt.h"
 
 #include "common.h"
 
-
 static int	ldapadd, force = 0;
 static char *rejfile = NULL;
 static LDAP	*ld = NULL;
 
-#define LDAPMOD_MAXLINE		4096
+#define	M_SEP	0x7f
 
 /* strings found in replog/LDIF entries (mostly lifted from slurpd/slurp.h) */
-#define T_VERSION_STR		"version"
-#define T_REPLICA_STR		"replica"
-#define T_DN_STR			"dn"
-#define T_CONTROL_STR		"control"
-#define T_CHANGETYPESTR		"changetype"
-#define T_ADDCTSTR			"add"
-#define T_MODIFYCTSTR		"modify"
-#define T_DELETECTSTR		"delete"
-#define T_MODRDNCTSTR		"modrdn"
-#define T_MODDNCTSTR		"moddn"
-#define T_RENAMECTSTR		"rename"
-#define T_MODOPADDSTR		"add"
-#define T_MODOPREPLACESTR	"replace"
-#define T_MODOPDELETESTR	"delete"
-#define T_MODOPINCREMENTSTR	"increment"
-#define T_MODSEPSTR			"-"
-#define T_NEWRDNSTR			"newrdn"
-#define T_DELETEOLDRDNSTR	"deleteoldrdn"
-#define T_NEWSUPSTR			"newsuperior"
+static struct berval BV_VERSION = BER_BVC("version");
+static struct berval BV_REPLICA = BER_BVC("replica");
+static struct berval BV_DN = BER_BVC("dn");
+static struct berval BV_CONTROL = BER_BVC("control");
+static struct berval BV_CHANGETYPE = BER_BVC("changetype");
+static struct berval BV_ADDCT = BER_BVC("add");
+static struct berval BV_MODIFYCT = BER_BVC("modify");
+static struct berval BV_DELETECT = BER_BVC("delete");
+static struct berval BV_MODRDNCT = BER_BVC("modrdn");
+static struct berval BV_MODDNCT = BER_BVC("moddn");
+static struct berval BV_RENAMECT = BER_BVC("rename");
+static struct berval BV_MODOPADD = BER_BVC("add");
+static struct berval BV_MODOPREPLACE = BER_BVC("replace");
+static struct berval BV_MODOPDELETE = BER_BVC("delete");
+static struct berval BV_MODOPINCREMENT = BER_BVC("increment");
+static struct berval BV_NEWRDN = BER_BVC("newrdn");
+static struct berval BV_DELETEOLDRDN = BER_BVC("deleteoldrdn");
+static struct berval BV_NEWSUP = BER_BVC("newsuperior");
 
+#define	BVICMP(a,b)	((a)->bv_len != (b)->bv_len ? \
+	(a)->bv_len - (b)->bv_len : strcasecmp((a)->bv_val, (b)->bv_val))
 
-static int process_ldif_rec LDAP_P(( char *rbuf, int count ));
-static int parse_ldif_control LDAP_P(( char *line, LDAPControl ***pctrls ));
-static void addmodifyop LDAP_P((
-	LDAPMod ***pmodsp, int modop,
-	const char *attr,
-	struct berval *value ));
+static int process_ldif_rec LDAP_P(( char *rbuf, int lineno ));
+static int parse_ldif_control LDAP_P(( struct berval *val, LDAPControl ***pctrls ));
 static int domodify LDAP_P((
 	const char *dn,
 	LDAPMod **pmods,
@@ -118,13 +118,13 @@
 static int process_response(
 	LDAP *ld,
 	int msgid,
-	const char *opstr,
+	int res,
 	const char *dn );
-static char *read_one_record LDAP_P(( FILE *fp ));
 
-#ifdef LDAP_GROUP_TRANSACTION
+#ifdef LDAP_X_TXN
 static int txn = 0;
 static int txnabort = 0;
+struct berval *txn_id = NULL;
 #endif
 
 void
@@ -140,9 +140,9 @@
 		(ldapadd ? _("default") : _("default is to replace")));
 	fprintf( stderr, _("  -E [!]ext=extparam	modify extensions"
 		" (! indicate s criticality)\n"));
-#ifdef LDAP_GROUP_TRANSACTION
+#ifdef LDAP_X_TXN
  	fprintf( stderr,
-		_("             [!]txn                      (transaction)\n"));
+		_("             [!]txn=<commit|abort>         (transaction)\n"));
 #endif
 	fprintf( stderr, _("  -F         force all changes records to be used\n"));
 	fprintf( stderr, _("  -S file    write skipped modifications to `file'\n"));
@@ -153,7 +153,7 @@
 
 
 const char options[] = "aE:FrS:"
-	"cd:D:e:f:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
+	"cd:D:e:f:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
@@ -185,7 +185,7 @@
 			*cvalue++ = '\0';
 		}
 
-#ifdef LDAP_GROUP_TRANSACTION
+#ifdef LDAP_X_TXN
 		if( strcasecmp( control, "txn" ) == 0 ) {
 			/* Transaction */
 			if( txn ) {
@@ -211,6 +211,7 @@
 				control );
 			usage();
 		}
+		break;
 
 	case 'a':	/* add */
 		ldapadd = 1;
@@ -241,22 +242,23 @@
 int
 main( int argc, char **argv )
 {
-#ifdef LDAP_GROUP_TRANSACTION
-	BerElement *txnber;
-	struct berval txnCookie = { 0, NULL };
-#endif
-	char		*rbuf, *start, *rejbuf = NULL;
-	FILE		*fp, *rejfp;
+	char		*rbuf = NULL, *rejbuf = NULL;
+	FILE		*rejfp;
+	struct LDIFFP *ldiffp, ldifdummy = {0};
 	char		*matched_msg, *error_msg;
 	int		rc, retval;
-	int count, len;
+	int		len;
+	int		i = 0;
+	int		lineno, nextline = 0, lmax = 0;
+	LDAPControl	c[1];
 
-	tool_init();
 	prog = lutil_progname( "ldapmodify", argc, argv );
 
 	/* strncmp instead of strcmp since NT binaries carry .exe extension */
 	ldapadd = ( strncasecmp( prog, "ldapadd", sizeof("ldapadd")-1 ) == 0 );
 
+	tool_init( ldapadd ? TOOL_ADD : TOOL_MODIFY );
+
 	tool_args( argc, argv );
 
 	if ( argc != optind ) usage();
@@ -271,19 +273,20 @@
 	}
 
 	if ( infile != NULL ) {
-		if (( fp = fopen( infile, "r" )) == NULL ) {
+		if (( ldiffp = ldif_open( infile, "r" )) == NULL ) {
 			perror( infile );
 			return( EXIT_FAILURE );
 		}
 	} else {
-		fp = stdin;
+		ldifdummy.fp = stdin;
+		ldiffp = &ldifdummy;
 	}
 
 	if ( debug ) ldif_debug = debug;
 
-	ld = tool_conn_setup( not, 0 );
+	ld = tool_conn_setup( dont, 0 );
 
-	if ( !not ) {
+	if ( !dont ) {
 		if ( pw_file || want_bindpw ) {
 			if ( pw_file ) {
 				rc = lutil_get_filed_password( pw_file, &passwd );
@@ -296,64 +299,42 @@
 		tool_bind( ld );
 	}
 
-#ifdef LDAP_GROUP_TRANSACTION
+#ifdef LDAP_X_TXN
 	if( txn ) {
-		struct berval *txnCookiep = &txnCookie;
-
-		/* create transaction */
-		rc = ldap_txn_create_s( ld, &txnCookiep, NULL, NULL );
+		/* start transaction */
+		rc = ldap_txn_start_s( ld, NULL, NULL, &txn_id );
 		if( rc != LDAP_SUCCESS ) {
-			ldap_perror( ld, "ldap_txn_create_s" );
-			if( txn > 2 ) return EXIT_FAILURE;
+			tool_perror( "ldap_txn_start_s", rc, NULL, NULL, NULL, NULL );
+			if( txn > 1 ) return EXIT_FAILURE;
 			txn = 0;
 		}
 	}
 #endif
 
-	if ( assertion || authzid || manageDIT || manageDSAit || noop
-#ifdef LDAP_GROUP_TRANSACTION
+	if ( 0
+#ifdef LDAP_X_TXN
 		|| txn
 #endif
-		|| preread || postread )
+		)
 	{
-		int i = 0;
-		LDAPControl c[1];
-
-#ifdef LDAP_GROUP_TRANSACTION
+#ifdef LDAP_X_TXN
 		if( txn ) {
-			int err;
-			txnber = ber_alloc_t( LBER_USE_DER );
-			if( txnber == NULL ) return EXIT_FAILURE;
-
-			err = ber_printf( txnber, "{o}", &txnCookie );
-			if( err == -1 ) {
-				ber_free( txnber, 1 );
-				fprintf( stderr, _("txn grouping control encoding error!\n") );
-				return EXIT_FAILURE;
-			}
-
-			err = ber_flatten2( txnber, &c[i].ldctl_value, 0 );
-			if( err == -1 ) return EXIT_FAILURE;
-
-			c[i].ldctl_oid = LDAP_CONTROL_GROUPING;
+			c[i].ldctl_oid = LDAP_CONTROL_X_TXN_SPEC;
+			c[i].ldctl_value = *txn_id;
 			c[i].ldctl_iscritical = 1;
 			i++;
 		}
 #endif
-
-		tool_server_controls( ld, c, i );
 	}
 
+	tool_server_controls( ld, c, i );
+
 	rc = 0;
-	count = 0;
 	retval = 0;
-	while (( rc == 0 || contoper ) &&
-		( rbuf = read_one_record( fp )) != NULL )
+	lineno = 1;
+	while (( rc == 0 || contoper ) && ldif_read_record( ldiffp, &nextline,
+		&rbuf, &lmax ))
 	{
-		count++;
-
-		start = rbuf;
-
 		if ( rejfp ) {
 			len = strlen( rbuf );
 			if (( rejbuf = (char *)ber_memalloc( len+1 )) == NULL ) {
@@ -363,7 +344,8 @@
 			memcpy( rejbuf, rbuf, len+1 );
 		}
 
-		rc = process_ldif_rec( start, count );
+		rc = process_ldif_rec( rbuf, lineno );
+		lineno = nextline+1;
 
 		if ( rc ) retval = rc;
 		if ( rc && rejfp ) {
@@ -379,7 +361,7 @@
 			}
 
 			error_msg = NULL;
-			ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &error_msg);
+			ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, &error_msg);
 			if ( error_msg != NULL ) {
 				if ( *error_msg != '\0' ) {
 					fprintf( rejfp, _(", additional info: %s"), error_msg );
@@ -390,22 +372,26 @@
 		}
 
 		if (rejfp) ber_memfree( rejbuf );
-		ber_memfree( rbuf );
 	}
+	ber_memfree( rbuf );
 
-#ifdef LDAP_GROUP_TRANSACTION
-	if( txn ) {
+#ifdef LDAP_X_TXN
+	if( retval == 0 && txn ) {
+		rc = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, NULL );
+		if ( rc != LDAP_OPT_SUCCESS ) {
+			fprintf( stderr, "Could not unset controls for ldap_txn_end\n");
+		}
+
 		/* create transaction */
-		rc = ldap_txn_end_s( ld, &txnCookie, !txnabort, NULL, NULL );
+		rc = ldap_txn_end_s( ld, !txnabort, txn_id, NULL, NULL, NULL );
 		if( rc != LDAP_SUCCESS ) {
-			ldap_perror( ld, "ldap_txn_create_s" );
-			if( txn > 2 ) return EXIT_FAILURE;
-			txn = 0;
+			tool_perror( "ldap_txn_end_s", rc, NULL, NULL, NULL, NULL );
+			retval = rc;
 		}
 	}
 #endif
 
-	if ( !not ) {
+	if ( !dont ) {
 		tool_unbind( ld );
 	}
 
@@ -419,24 +405,25 @@
 
 
 static int
-process_ldif_rec( char *rbuf, int count )
+process_ldif_rec( char *rbuf, int linenum )
 {
-	char	*line, *dn, *type, *newrdn, *newsup, *p;
-	int		rc, linenum, modop, replicaport;
-	int		expect_modop, expect_sep, expect_ct, expect_newrdn, expect_newsup;
-	int		expect_deleteoldrdn, deleteoldrdn;
+	char	*line, *dn, *newrdn, *newsup;
+	int		rc, modop, replicaport;
+	int		expect_modop, expect_sep;
+	int		deleteoldrdn;
 	int		saw_replica, use_record, new_entry, delete_entry, got_all;
-	LDAPMod	**pmods;
+	LDAPMod	**pmods, *lm = NULL;
 	int version;
-	struct berval val;
 	LDAPControl **pctrls;
+	int i, j, k, lines, idn, nmods;
+	struct berval *btype, *vals, **bvl, bv;
+	char *freeval;
+	unsigned char *mops = NULL;
 
 	new_entry = ldapadd;
 
 	rc = got_all = saw_replica = delete_entry = modop = expect_modop = 0;
-	expect_deleteoldrdn = expect_newrdn = expect_newsup = 0;
-	expect_sep = expect_ct = 0;
-	linenum = 0;
+	expect_sep = 0;
 	version = 0;
 	deleteoldrdn = 1;
 	use_record = force;
@@ -444,237 +431,430 @@
 	pctrls = NULL;
 	dn = newrdn = newsup = NULL;
 
+	lines = ldif_countlines( rbuf );
+	btype = ber_memcalloc( 1, (lines+1)*2*sizeof(struct berval)+lines );
+	if ( !btype )
+		return LDAP_NO_MEMORY;
+
+	vals = btype+lines+1;
+	freeval = (char *)(vals+lines+1);
+	i = -1;
+
 	while ( rc == 0 && ( line = ldif_getline( &rbuf )) != NULL ) {
-		++linenum;
+		int freev;
 
-		if ( expect_sep && strcasecmp( line, T_MODSEPSTR ) == 0 ) {
-			expect_sep = 0;
-			expect_ct = 1;
+		if ( *line == '\n' || *line == '\0' ) {
+			break;
+		}
+
+		++i;
+
+		if ( line[0] == '-' && !line[1] ) {
+			BER_BVZERO( btype+i );
+			freeval[i] = 0;
 			continue;
 		}
 	
-		if ( ldif_parse_line( line, &type, &val.bv_val, &val.bv_len ) < 0 ) {
+		if ( ( rc = ldif_parse_line2( line, btype+i, vals+i, &freev ) ) < 0 ) {
 			fprintf( stderr, _("%s: invalid format (line %d) entry: \"%s\"\n"),
-				prog, linenum, dn == NULL ? "" : dn );
+				prog, linenum+i, dn == NULL ? "" : dn );
 			rc = LDAP_PARAM_ERROR;
 			break;
 		}
+		freeval[i] = freev;
 
 		if ( dn == NULL ) {
-			if ( !use_record && strcasecmp( type, T_REPLICA_STR ) == 0 ) {
+			if ( !use_record && !BVICMP( btype+i, &BV_REPLICA )) {
+				char *p;
 				++saw_replica;
-				if (( p = strchr( val.bv_val, ':' )) == NULL ) {
+				if (( p = strchr( vals[i].bv_val, ':' )) == NULL ) {
 					replicaport = 0;
 				} else {
 					*p++ = '\0';
 					if ( lutil_atoi( &replicaport, p ) != 0 ) {
 						fprintf( stderr, _("%s: unable to parse replica port \"%s\" (line %d) entry: \"%s\"\n"),
-							prog, p, linenum, dn == NULL ? "" : dn );
+							prog, p, linenum+i, dn == NULL ? "" : dn );
 						rc = LDAP_PARAM_ERROR;
 						break;
 					}
 				}
 				if ( ldaphost != NULL &&
-					strcasecmp( val.bv_val, ldaphost ) == 0 &&
+					strcasecmp( vals[i].bv_val, ldaphost ) == 0 &&
 					replicaport == ldapport )
 				{
 					use_record = 1;
 				}
-	    		} else if ( count == 1 && linenum == 1 && 
-				strcasecmp( type, T_VERSION_STR ) == 0 )
-			{
+			} else if ( linenum+i == 1 && !BVICMP( btype+i, &BV_VERSION )) {
 				int	v;
-				if( val.bv_len == 0 || lutil_atoi( &v, val.bv_val) != 0 || v != 1 ) {
+				if( vals[i].bv_len == 0 || lutil_atoi( &v, vals[i].bv_val) != 0 || v != 1 ) {
 					fprintf( stderr,
 						_("%s: invalid version %s, line %d (ignored)\n"),
-						prog, val.bv_val, linenum );
+						prog, vals[i].bv_val, linenum );
 				}
 				version++;
 
-			} else if ( strcasecmp( type, T_DN_STR ) == 0 ) {
-				if (( dn = ber_strdup( val.bv_val )) == NULL ) {
-					perror( "strdup" );
-					exit( EXIT_FAILURE );
+			} else if ( !BVICMP( btype+i, &BV_DN )) {
+				dn = vals[i].bv_val;
+				idn = i;
+				if ( !use_record && saw_replica ) {
+					printf(_("%s: skipping change record for entry: %s at line %d\n"),
+						prog, dn, linenum+i);
+					printf(_("\t(LDAP host/port does not match replica: lines)\n"));
+					rc = 0;
+					goto leave;
 				}
-				expect_ct = 1;
 			}
-			goto end_line;	/* skip all lines until we see "dn:" */
+			/* skip all lines until we see "dn:" */
 		}
+	}
 
-		if ( expect_ct ) {
-			/* Check for "control" tag after dn and before changetype. */
-			if (strcasecmp(type, T_CONTROL_STR) == 0) {
-				/* Parse and add it to the list of controls */
-				rc = parse_ldif_control( line, &pctrls );
-				if (rc != 0) {
-					fprintf( stderr,
-						_("%s: Error processing %s line, line %d: %s\n"),
-						prog, T_CONTROL_STR, linenum, ldap_err2string(rc) );
-				}
-				goto end_line;
-			}
+	/* check to make sure there was a dn: line */
+	if ( !dn ) {
+		rc = 0;
+		goto leave;
+	}
 
-			expect_ct = 0;
-			if ( !use_record && saw_replica ) {
-				printf(_("%s: skipping change record for entry: %s\n"),
-					prog, dn);
-				printf(_("\t(LDAP host/port does not match replica: lines)\n"));
-				ber_memfree( dn );
-				ber_memfree( type );
-				ber_memfree( val.bv_val );
-				return( 0 );
-			}
+	lines = i+1;
 
-			if ( strcasecmp( type, T_CHANGETYPESTR ) == 0 ) {
+	if( lines == 0 ) {
+		rc = 0;
+		goto leave;
+	}
+
+	if( version && lines == 1 ) {
+		rc = 0;
+		goto leave;
+	}
+
+	i = idn+1;
+	/* Check for "control" tag after dn and before changetype. */
+	if (!BVICMP( btype+i, &BV_CONTROL)) {
+		/* Parse and add it to the list of controls */
+		rc = parse_ldif_control( vals+i, &pctrls );
+		if (rc != 0) {
+			fprintf( stderr,
+				_("%s: Error processing %s line, line %d: %s\n"),
+				prog, BV_CONTROL.bv_val, linenum+i, ldap_err2string(rc) );
+		}
+		i++;
+		if ( i>= lines ) {
+short_input:
+			fprintf( stderr,
+				_("%s: Expecting more input after %s line, line %d\n"),
+				prog, btype[i-1].bv_val, linenum+i );
+			
+			rc = LDAP_PARAM_ERROR;
+			goto leave;
+		}
+	}
+
+	/* Check for changetype */
+	if ( !BVICMP( btype+i, &BV_CHANGETYPE )) {
 #ifdef LIBERAL_CHANGETYPE_MODOP
-				/* trim trailing spaces (and log warning ...) */
-				int icnt;
-				for ( icnt = val.bv_len; --icnt > 0; ) {
-					if ( !isspace( (unsigned char) val.bv_val[icnt] ) ) {
-						break;
-					}
-				}
+		/* trim trailing spaces (and log warning ...) */
+		int icnt;
+		for ( icnt = vals[i].bv_len; --icnt > 0; ) {
+			if ( !isspace( (unsigned char) vals[i].bv_val[icnt] ) ) {
+				break;
+			}
+		}
 
-				if ( ++icnt != val.bv_len ) {
-					fprintf( stderr, _("%s: illegal trailing space after"
-						" \"%s: %s\" trimmed (line %d of entry \"%s\")\n"),
-						prog, T_CHANGETYPESTR, val.bv_val, linenum, dn );
-					val.bv_val[icnt] = '\0';
-				}
+		if ( ++icnt != vals[i].bv_len ) {
+			fprintf( stderr, _("%s: illegal trailing space after"
+				" \"%s: %s\" trimmed (line %d, entry \"%s\")\n"),
+				prog, BV_CHANGETYPE.bv_val, vals[i].bv_val, linenum+i, dn );
+			vals[i].bv_val[icnt] = '\0';
+		}
 #endif /* LIBERAL_CHANGETYPE_MODOP */
 
-				if ( strcasecmp( val.bv_val, T_MODIFYCTSTR ) == 0 ) {
-					new_entry = 0;
-					expect_modop = 1;
-				} else if ( strcasecmp( val.bv_val, T_ADDCTSTR ) == 0 ) {
-					new_entry = 1;
-				} else if ( strcasecmp( val.bv_val, T_MODRDNCTSTR ) == 0
-					|| strcasecmp( val.bv_val, T_MODDNCTSTR ) == 0
-					|| strcasecmp( val.bv_val, T_RENAMECTSTR ) == 0)
-				{
-					expect_newrdn = 1;
-				} else if ( strcasecmp( val.bv_val, T_DELETECTSTR ) == 0 ) {
-					got_all = delete_entry = 1;
-				} else {
-					fprintf( stderr,
-						_("%s:  unknown %s \"%s\" (line %d of entry \"%s\")\n"),
-						prog, T_CHANGETYPESTR, val.bv_val, linenum, dn );
+		if ( BVICMP( vals+i, &BV_MODIFYCT ) == 0 ) {
+			new_entry = 0;
+			expect_modop = 1;
+		} else if ( BVICMP( vals+i, &BV_ADDCT ) == 0 ) {
+			new_entry = 1;
+			modop = LDAP_MOD_ADD;
+		} else if ( BVICMP( vals+i, &BV_MODRDNCT ) == 0
+			|| BVICMP( vals+i, &BV_MODDNCT ) == 0
+			|| BVICMP( vals+i, &BV_RENAMECT ) == 0)
+		{
+			i++;
+			if ( i >= lines )
+				goto short_input;
+			if ( BVICMP( btype+i, &BV_NEWRDN )) {
+				fprintf( stderr, _("%s: expecting \"%s:\" but saw"
+					" \"%s:\" (line %d, entry \"%s\")\n"),
+					prog, BV_NEWRDN.bv_val, btype[i].bv_val, linenum+i, dn );
+				rc = LDAP_PARAM_ERROR;
+				goto leave;
+			}
+			newrdn = vals[i].bv_val;
+			i++;
+			if ( i >= lines )
+				goto short_input;
+			if ( BVICMP( btype+i, &BV_DELETEOLDRDN )) {
+				fprintf( stderr, _("%s: expecting \"%s:\" but saw"
+					" \"%s:\" (line %d, entry \"%s\")\n"),
+					prog, BV_DELETEOLDRDN.bv_val, btype[i].bv_val, linenum+i, dn );
+				rc = LDAP_PARAM_ERROR;
+				goto leave;
+			}
+			deleteoldrdn = ( vals[i].bv_val[0] == '0' ) ? 0 : 1;
+			i++;
+			if ( i < lines ) {
+				if ( BVICMP( btype+i, &BV_NEWSUP )) {
+					fprintf( stderr, _("%s: expecting \"%s:\" but saw"
+						" \"%s:\" (line %d, entry \"%s\")\n"),
+						prog, BV_NEWSUP.bv_val, btype[i].bv_val, linenum+i, dn );
 					rc = LDAP_PARAM_ERROR;
+					goto leave;
 				}
-				goto end_line;
-			} else if ( ldapadd ) {		/*  missing changetype => add */
-				new_entry = 1;
-				modop = LDAP_MOD_ADD;
-			} else {
-				expect_modop = 1;	/* missing changetype => modify */
+				newsup = vals[i].bv_val;
+				i++;
 			}
+			got_all = 1;
+		} else if ( BVICMP( vals+i, &BV_DELETECT ) == 0 ) {
+			got_all = delete_entry = 1;
+		} else {
+			fprintf( stderr,
+				_("%s:  unknown %s \"%s\" (line %d, entry \"%s\")\n"),
+				prog, BV_CHANGETYPE.bv_val, vals[i].bv_val, linenum+i, dn );
+			rc = LDAP_PARAM_ERROR;
+			goto leave;
 		}
+		i++;
+	} else if ( ldapadd ) {		/*  missing changetype => add */
+		new_entry = 1;
+		modop = LDAP_MOD_ADD;
+	} else {
+		expect_modop = 1;	/* missing changetype => modify */
+	}
 
+	if ( got_all ) {
+		if ( i < lines ) {
+			fprintf( stderr,
+				_("%s: extra lines at end (line %d, entry \"%s\")\n"),
+				prog, linenum+i, dn );
+			rc = LDAP_PARAM_ERROR;
+			goto leave;
+		}
+		goto doit;
+	}
+
+	nmods = lines - i;
+	idn = i;
+
+	if ( new_entry ) {
+		int fv;
+
+		/* Make sure all attributes with multiple values are contiguous */
+		for (; i<lines; i++) {
+			for (j=i+1; j<lines; j++) {
+				if ( !BVICMP( btype+i, btype+j )) {
+					nmods--;
+					/* out of order, move intervening attributes down */
+					if ( j != i+1 ) {
+						bv = vals[j];
+						fv = freeval[j];
+						for (k=j; k>i; k--) {
+							btype[k] = btype[k-1];
+							vals[k] = vals[k-1];
+							freeval[k] = freeval[k-1];
+						}
+						k++;
+						btype[k] = btype[i];
+						vals[k] = bv;
+						freeval[k] = fv;
+					}
+					i++;
+				}
+			}
+		}
+		/* Allocate space for array of mods, array of pointers to mods,
+		 * and array of pointers to values, allowing for NULL terminators
+		 * for the pointer arrays...
+		 */
+		lm = ber_memalloc( nmods * sizeof(LDAPMod) +
+			(nmods+1) * sizeof(LDAPMod*) +
+			(lines + nmods - idn) * sizeof(struct berval *));
+		pmods = (LDAPMod **)(lm+nmods);
+		bvl = (struct berval **)(pmods+nmods+1);
+
+		j = 0;
+		k = -1;
+		BER_BVZERO(&bv);
+		for (i=idn; i<lines; i++) {
+			if ( !BVICMP( btype+i, &BV_DN )) {
+				fprintf( stderr, _("%s: attributeDescription \"%s\":"
+					" (possible missing newline"
+						" after line %d, entry \"%s\"?)\n"),
+					prog, btype[i].bv_val, linenum+i - 1, dn );
+			}
+			if ( BVICMP(btype+i,&bv)) {
+				bvl[k++] = NULL;
+				bv = btype[i];
+				lm[j].mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
+				lm[j].mod_type = bv.bv_val;
+				lm[j].mod_bvalues = bvl+k;
+				pmods[j] = lm+j;
+				j++;
+			}
+			bvl[k++] = vals+i;
+		}
+		bvl[k] = NULL;
+		pmods[j] = NULL;
+		goto doit;
+	}
+
+	mops = ber_memalloc( lines+1 );
+	mops[lines] = M_SEP;
+	mops[i-1] = M_SEP;
+
+	for ( ; i<lines; i++ ) {
 		if ( expect_modop ) {
 #ifdef LIBERAL_CHANGETYPE_MODOP
 			/* trim trailing spaces (and log warning ...) */
 		    int icnt;
-		    for ( icnt = val.bv_len; --icnt > 0; ) {
-				if ( !isspace( (unsigned char) val.bv_val[icnt] ) ) break;
+		    for ( icnt = vals[i].bv_len; --icnt > 0; ) {
+				if ( !isspace( (unsigned char) vals[i].bv_val[icnt] ) ) break;
 			}
     
-			if ( ++icnt != val.bv_len ) {
+			if ( ++icnt != vals[i].bv_len ) {
 				fprintf( stderr, _("%s: illegal trailing space after"
-					" \"%s: %s\" trimmed (line %d of entry \"%s\")\n"),
-					prog, type, val.bv_val, linenum, dn );
-				val.bv_val[icnt] = '\0';
+					" \"%s: %s\" trimmed (line %d, entry \"%s\")\n"),
+					prog, type, vals[i].bv_val, linenum+i, dn );
+				vals[i].bv_val[icnt] = '\0';
 			}
 #endif /* LIBERAL_CHANGETYPE_MODOP */
 
 			expect_modop = 0;
 			expect_sep = 1;
-			if ( strcasecmp( type, T_MODOPADDSTR ) == 0 ) {
+			if ( BVICMP( btype+i, &BV_MODOPADD ) == 0 ) {
 				modop = LDAP_MOD_ADD;
-				goto end_line;
-			} else if ( strcasecmp( type, T_MODOPREPLACESTR ) == 0 ) {
+				mops[i] = M_SEP;
+				nmods--;
+			} else if ( BVICMP( btype+i, &BV_MODOPREPLACE ) == 0 ) {
+			/* defer handling these since they might have no values.
+			 * Use the BVALUES flag to signal that these were
+			 * deferred. If values are provided later, this
+			 * flag will be switched off.
+			 */
 				modop = LDAP_MOD_REPLACE;
-				addmodifyop( &pmods, modop, val.bv_val, NULL );
-				goto end_line;
-			} else if ( strcasecmp( type, T_MODOPDELETESTR ) == 0 ) {
+				mops[i] = modop | LDAP_MOD_BVALUES;
+				btype[i] = vals[i];
+			} else if ( BVICMP( btype+i, &BV_MODOPDELETE ) == 0 ) {
 				modop = LDAP_MOD_DELETE;
-				addmodifyop( &pmods, modop, val.bv_val, NULL );
-				goto end_line;
-			} else if ( strcasecmp( type, T_MODOPINCREMENTSTR ) == 0 ) {
+				mops[i] = modop | LDAP_MOD_BVALUES;
+				btype[i] = vals[i];
+			} else if ( BVICMP( btype+i, &BV_MODOPINCREMENT ) == 0 ) {
 				modop = LDAP_MOD_INCREMENT;
-				addmodifyop( &pmods, modop, val.bv_val, NULL );
-				goto end_line;
-			} else {	/* no modify op:  use default */
-				modop = ldapadd ? LDAP_MOD_ADD : LDAP_MOD_REPLACE;
-			}
-		}
-
-		if ( expect_newrdn ) {
-			if ( strcasecmp( type, T_NEWRDNSTR ) == 0 ) {
-				if (( newrdn = ber_strdup( val.bv_val )) == NULL ) {
-					perror( "strdup" );
-					exit( EXIT_FAILURE );
-				}
-				expect_deleteoldrdn = 1;
-				expect_newrdn = 0;
-			} else {
-				fprintf( stderr, _("%s: expecting \"%s:\" but saw"
-					" \"%s:\" (line %d of entry \"%s\")\n"),
-					prog, T_NEWRDNSTR, type, linenum, dn );
+				mops[i] = M_SEP;
+				nmods--;
+			} else {	/* no modify op: invalid LDIF */
+				fprintf( stderr, _("%s: modify operation type is missing at"
+					" line %d, entry \"%s\"\n"),
+					prog, linenum+i, dn );
 				rc = LDAP_PARAM_ERROR;
+				goto leave;
 			}
-		} else if ( expect_deleteoldrdn ) {
-			if ( strcasecmp( type, T_DELETEOLDRDNSTR ) == 0 ) {
-				deleteoldrdn = ( *val.bv_val == '0' ) ? 0 : 1;
-				expect_deleteoldrdn = 0;
-				expect_newsup = 1;
-				got_all = 1;
-			} else {
-				fprintf( stderr, _("%s: expecting \"%s:\" but saw"
-					" \"%s:\" (line %d of entry \"%s\")\n"),
-					prog, T_DELETEOLDRDNSTR, type, linenum, dn );
+			bv = vals[i];
+		} else if ( expect_sep && BER_BVISEMPTY( btype+i )) {
+			mops[i] = M_SEP;
+			expect_sep = 0;
+			expect_modop = 1;
+			nmods--;
+		} else {
+			if ( BVICMP( btype+i, &bv )) {
+				fprintf( stderr, _("%s: wrong attributeType at"
+					" line %d, entry \"%s\"\n"),
+					prog, linenum+i, dn );
 				rc = LDAP_PARAM_ERROR;
+				goto leave;
 			}
-		} else if ( expect_newsup ) {
-			if ( strcasecmp( type, T_NEWSUPSTR ) == 0 ) {
-				if (( newsup = ber_strdup( val.bv_val )) == NULL ) {
-					perror( "strdup" );
-					exit( EXIT_FAILURE );
-				}
-				expect_newsup = 0;
-			} else {
-				fprintf( stderr, _("%s: expecting \"%s:\" but saw"
-					" \"%s:\" (line %d of entry \"%s\")\n"),
-					prog, T_NEWSUPSTR, type, linenum, dn );
-				rc = LDAP_PARAM_ERROR;
+			mops[i] = modop;
+			/* If prev op was deferred and matches this type,
+			 * clear the flag
+			 */
+			if ( (mops[i-1]&LDAP_MOD_BVALUES) && !BVICMP(btype+i,
+				btype+i-1)) {
+				mops[i-1] = M_SEP;
+				nmods--;
 			}
-		} else if ( got_all ) {
-			fprintf( stderr,
-				_("%s: extra lines at end (line %d of entry \"%s\")\n"),
-				prog, linenum, dn );
-			rc = LDAP_PARAM_ERROR;
-		} else {
-			if ( new_entry && strcasecmp( type, T_DN_STR ) == 0 ) {
-				fprintf( stderr, _("%s: attributeDescription \"%s\":"
-					" (possible missing newline"
-						" after line %d of entry \"%s\"?)\n"),
-					prog, type, linenum - 1, dn );
-			}
-			addmodifyop( &pmods, modop, type, &val );
 		}
-
-end_line:
-		ber_memfree( type );
-		ber_memfree( val.bv_val );
 	}
 
-	if( linenum == 0 ) {
-		return 0;
+#if 0	/* we should faithfully encode the LDIF, not combine */
+	/* Make sure all modops with multiple values are contiguous */
+	for (i=idn; i<lines; i++) {
+		if ( mops[i] == M_SEP )
+			continue;
+		for (j=i+1; j<lines; j++) {
+			if ( mops[j] == M_SEP || mops[i] != mops[j] )
+				continue;
+			if ( !BVICMP( btype+i, btype+j )) {
+				nmods--;
+				/* out of order, move intervening attributes down */
+				if ( j != i+1 ) {
+					int c;
+					struct berval bv;
+					char fv;
+
+					c = mops[j];
+					bv = vals[j];
+					fv = freeval[j];
+					for (k=j; k>i; k--) {
+						btype[k] = btype[k-1];
+						vals[k] = vals[k-1];
+						freeval[k] = freeval[k-1];
+						mops[k] = mops[k-1];
+					}
+					k++;
+					btype[k] = btype[i];
+					vals[k] = bv;
+					freeval[k] = fv;
+					mops[k] = c;
+				}
+				i++;
+			}
+		}
 	}
+#endif
 
-	if( version && linenum == 1 ) {
-		return 0;
+	/* Allocate space for array of mods, array of pointers to mods,
+	 * and array of pointers to values, allowing for NULL terminators
+	 * for the pointer arrays...
+	 */
+	lm = ber_memalloc( nmods * sizeof(LDAPMod) +
+		(nmods+1) * sizeof(LDAPMod*) +
+		(lines + nmods - idn) * sizeof(struct berval *));
+	pmods = (LDAPMod **)(lm+nmods);
+	bvl = (struct berval **)(pmods+nmods+1);
+
+	j = 0;
+	k = -1;
+	BER_BVZERO(&bv);
+	mops[idn-1] = M_SEP;
+	for (i=idn; i<lines; i++) {
+		if ( mops[i] == M_SEP )
+			continue;
+		if ( mops[i] != mops[i-1] || BVICMP(btype+i,&bv)) {
+			bvl[k++] = NULL;
+			bv = btype[i];
+			lm[j].mod_op = mops[i] | LDAP_MOD_BVALUES;
+			lm[j].mod_type = bv.bv_val;
+			if ( mops[i] & LDAP_MOD_BVALUES ) {
+				lm[j].mod_bvalues = NULL;
+			} else {
+				lm[j].mod_bvalues = bvl+k;
+			}
+			pmods[j] = lm+j;
+			j++;
+		}
+		bvl[k++] = vals+i;
 	}
+	bvl[k] = NULL;
+	pmods[j] = NULL;
 
+doit:
 	/* If default controls are set (as with -M option) and controls are
 	   specified in the LDIF file, we must add the default controls to
 	   the list of controls sent with the ldap operation.
@@ -711,7 +891,6 @@
 		}
 	}
 
-
 	if ( rc == 0 ) {
 		if ( delete_entry ) {
 			rc = dodelete( dn, pctrls );
@@ -726,21 +905,19 @@
 		}
 	}
 
-	if ( dn != NULL ) {
-		ber_memfree( dn );
+leave:
+    if (pctrls != NULL) {
+    	ldap_controls_free( pctrls );
 	}
-	if ( newrdn != NULL ) {
-		ber_memfree( newrdn );
+	if ( lm != NULL ) {
+		ber_memfree( lm );
 	}
-	if ( newsup != NULL ) {
-		ber_memfree( newsup );
+	if ( mops != NULL ) {
+		ber_memfree( mops );
 	}
-	if ( pmods != NULL ) {
-		ldap_mods_free( pmods, 1 );
-	}
-    if (pctrls != NULL) {
-    	ldap_controls_free( pctrls );
-	}
+	for (i=lines-1; i>=0; i--)
+		if ( freeval[i] ) ber_memfree( vals[i].bv_val );
+	ber_memfree( btype );
 
 	return( rc );
 }
@@ -753,30 +930,21 @@
 */      
 static int
 parse_ldif_control(
-	char *line, 
+	struct berval *bval,
 	LDAPControl ***ppctrls )
 {
 	char *oid = NULL;
 	int criticality = 0;   /* Default is false if not present */
-	char *type=NULL;
-	char *val = NULL;
-	ber_len_t value_len = 0;
 	int i, rc=0;
-	char *s, *oidStart, *pcolon;
+	char *s, *oidStart;
 	LDAPControl *newctrl = NULL;
 	LDAPControl **pctrls = NULL;
+	struct berval type, bv;
+	int freeval;
 
 	if (ppctrls) pctrls = *ppctrls;
-	s = line + strlen(T_CONTROL_STR);  /* Skip over "control" */
-	pcolon = s;                        /* Save this position for later */
-	if (*s++ != ':') {                 /* Make sure colon follows */
-		return ( LDAP_PARAM_ERROR );
-	}
-	while (*s && isspace((unsigned char)*s)) {
-		s++;                           /* Skip white space before OID */
-	}
-
-	/* OID should come next. Validate and extract it. */
+	/* OID should come first. Validate and extract it. */
+	s = bval->bv_val;
 	if (*s == 0) return ( LDAP_PARAM_ERROR );
 	oidStart = s;
 	while (isdigit((unsigned char)*s) || *s == '.') {
@@ -818,17 +986,16 @@
 			goto cleanup;
 		}
 
-		/* Shift value down over OID and criticality so it's in the form
-		     control: value
-		     control:: base64-value
-		     control:< url
-		   Then we can use ldif_parse_line to extract and decode the value
+		/* Back up so value is in the form
+		     a: value
+		     a:: base64-value
+		     a:< url
+		   Then we can use ldif_parse_line2 to extract and decode the value
 		*/
-		while ( (*pcolon++ = *s++) != 0) {   /* Shift value */
-			/* EMPTY */;
-		}
-		rc = ldif_parse_line(line, &type, &val, &value_len);
-		if (type)  ber_memfree(type);   /* Don't need this field*/
+		s--;
+		*s = 'a';
+
+		rc = ldif_parse_line2(s, &type, &bv, &freeval);
 		if (rc < 0) {
 			rc = LDAP_PARAM_ERROR;
 			goto cleanup;
@@ -844,9 +1011,10 @@
 	newctrl->ldctl_oid = oid;
 	oid = NULL;
 	newctrl->ldctl_iscritical = criticality;
-	newctrl->ldctl_value.bv_len = value_len;
-	newctrl->ldctl_value.bv_val = val;
-	val = NULL;
+	if ( freeval )
+		newctrl->ldctl_value = bv;
+	else
+		ber_dupbv( &newctrl->ldctl_value, &bv );
 
 	/* Add the new control to the passed-in list of controls. */
 	i = 0;
@@ -875,87 +1043,12 @@
 		}
 		ber_memfree(newctrl);
 	}
-	if (val) ber_memfree(val);
 	if (oid) ber_memfree(oid);
 
 	return( rc );
 }
 
 
-static void
-addmodifyop(
-	LDAPMod ***pmodsp,
-	int modop,
-	const char *attr,
-	struct berval *val )
-{
-	LDAPMod		**pmods;
-	int			i, j;
-
-	pmods = *pmodsp;
-	modop |= LDAP_MOD_BVALUES;
-
-	i = 0;
-	if ( pmods != NULL ) {
-		for ( ; pmods[ i ] != NULL; ++i ) {
-			if ( strcasecmp( pmods[ i ]->mod_type, attr ) == 0 &&
-				pmods[ i ]->mod_op == modop )
-			{
-				break;
-			}
-		}
-	}
-
-	if ( pmods == NULL || pmods[ i ] == NULL ) {
-		if (( pmods = (LDAPMod **)ber_memrealloc( pmods, (i + 2) *
-			sizeof( LDAPMod * ))) == NULL )
-		{
-			perror( "realloc" );
-			exit( EXIT_FAILURE );
-		}
-
-		*pmodsp = pmods;
-		pmods[ i + 1 ] = NULL;
-
-		pmods[ i ] = (LDAPMod *)ber_memcalloc( 1, sizeof( LDAPMod ));
-		if ( pmods[ i ] == NULL ) {
-			perror( "calloc" );
-			exit( EXIT_FAILURE );
-		}
-
-		pmods[ i ]->mod_op = modop;
-		pmods[ i ]->mod_type = ber_strdup( attr );
-		if ( pmods[ i ]->mod_type == NULL ) {
-			perror( "strdup" );
-			exit( EXIT_FAILURE );
-		}
-	}
-
-	if ( val != NULL ) {
-		j = 0;
-		if ( pmods[ i ]->mod_bvalues != NULL ) {
-			for ( ; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) {
-				/* Empty */;
-			}
-		}
-
-		pmods[ i ]->mod_bvalues = (struct berval **) ber_memrealloc(
-			pmods[ i ]->mod_bvalues, (j + 2) * sizeof( struct berval * ));
-		if ( pmods[ i ]->mod_bvalues == NULL ) {
-			perror( "ber_realloc" );
-			exit( EXIT_FAILURE );
-		}
-
-		pmods[ i ]->mod_bvalues[ j + 1 ] = NULL;
-		pmods[ i ]->mod_bvalues[ j ] = ber_bvdup( val );
-		if ( pmods[ i ]->mod_bvalues[ j ] == NULL ) {
-			perror( "ber_bvdup" );
-			exit( EXIT_FAILURE );
-		}
-	}
-}
-
-
 static int
 domodify(
 	const char *dn,
@@ -1024,12 +1117,12 @@
 	}
 
 	if ( newentry ) {
-		printf( "%sadding new entry \"%s\"\n", not ? "!" : "", dn );
+		printf( "%sadding new entry \"%s\"\n", dont ? "!" : "", dn );
 	} else {
-		printf( "%smodifying entry \"%s\"\n", not ? "!" : "", dn );
+		printf( "%smodifying entry \"%s\"\n", dont ? "!" : "", dn );
 	}
 
-	if ( !not ) {
+	if ( !dont ) {
 		int	msgid;
 		if ( newentry ) {
 			rc = ldap_add_ext( ld, dn, pmods, pctrls, NULL, &msgid );
@@ -1040,14 +1133,15 @@
 		if ( rc != LDAP_SUCCESS ) {
 			/* print error message about failed update including DN */
 			fprintf( stderr, _("%s: update failed: %s\n"), prog, dn );
-			ldap_perror( ld, newentry ? "ldap_add" : "ldap_modify" );
+			tool_perror( newentry ? "ldap_add" : "ldap_modify",
+				rc, NULL, NULL, NULL, NULL );
 			goto done;
 		} else if ( verbose ) {
 			printf( _("modify complete\n") );
 		}
 
 		rc = process_response( ld, msgid,
-			newentry ? "ldap_add" : "ldap_modify", dn );
+			newentry ? LDAP_RES_ADD : LDAP_RES_MODIFY, dn );
 
 	} else {
 		rc = LDAP_SUCCESS;
@@ -1067,18 +1161,18 @@
 	int	rc;
 	int msgid;
 
-	printf( _("%sdeleting entry \"%s\"\n"), not ? "!" : "", dn );
-	if ( !not ) {
+	printf( _("%sdeleting entry \"%s\"\n"), dont ? "!" : "", dn );
+	if ( !dont ) {
 		rc = ldap_delete_ext( ld, dn, pctrls, NULL, &msgid );
 		if ( rc != LDAP_SUCCESS ) {
 			fprintf( stderr, _("%s: delete failed: %s\n"), prog, dn );
-			ldap_perror( ld, "ldap_delete" );
+			tool_perror( "ldap_delete", rc, NULL, NULL, NULL, NULL );
 			goto done;
 		} else if ( verbose ) {
 			printf( _("delete complete") );
 		}
 
-		rc = process_response( ld, msgid, "ldap_delete", dn );
+		rc = process_response( ld, msgid, LDAP_RES_DELETE, dn );
 
 	} else {
 		rc = LDAP_SUCCESS;
@@ -1101,23 +1195,23 @@
 	int	rc;
 	int msgid;
 
-	printf( _("%smodifying rdn of entry \"%s\"\n"), not ? "!" : "", dn );
+	printf( _("%smodifying rdn of entry \"%s\"\n"), dont ? "!" : "", dn );
 	if ( verbose ) {
 		printf( _("\tnew RDN: \"%s\" (%skeep existing values)\n"),
 			newrdn, deleteoldrdn ? _("do not ") : "" );
 	}
-	if ( !not ) {
+	if ( !dont ) {
 		rc = ldap_rename( ld, dn, newrdn, newsup, deleteoldrdn,
 			pctrls, NULL, &msgid );
 		if ( rc != LDAP_SUCCESS ) {
 			fprintf( stderr, _("%s: rename failed: %s\n"), prog, dn );
-			ldap_perror( ld, "ldap_rename" );
+			tool_perror( "ldap_rename", rc, NULL, NULL, NULL, NULL );
 			goto done;
 		} else {
 			printf( _("rename completed\n") );
 		}
 
-		rc = process_response( ld, msgid, "ldap_rename", dn );
+		rc = process_response( ld, msgid, LDAP_RES_RENAME, dn );
 
 	} else {
 		rc = LDAP_SUCCESS;
@@ -1128,33 +1222,48 @@
 	return( rc );
 }
 
+static const char *
+res2str( int res ) {
+	switch ( res ) {
+	case LDAP_RES_ADD:
+		return "ldap_add";
+	case LDAP_RES_DELETE:
+		return "ldap_delete";
+	case LDAP_RES_MODIFY:
+		return "ldap_modify";
+	case LDAP_RES_MODRDN:
+		return "ldap_rename";
+	default:
+		assert( 0 );
+	}
+
+	return "ldap_unknown";
+}
+
 static int process_response(
 	LDAP *ld,
 	int msgid,
-	const char *opstr,
+	int op,
 	const char *dn )
 {
 	LDAPMessage	*res;
-	int		rc = LDAP_OTHER;
+	int		rc = LDAP_OTHER, msgtype;
 	struct timeval	tv = { 0, 0 };
+	int		err;
+	char		*text = NULL, *matched = NULL, **refs = NULL;
+	LDAPControl	**ctrls = NULL;
 
 	for ( ; ; ) {
 		tv.tv_sec = 0;
 		tv.tv_usec = 100000;
 
-		rc = ldap_result( ld, msgid,
-#ifdef LDAP_GROUP_TRANSACTION
-			txn ? 0 : 1,
-#else
-			1,
-#endif
-			&tv, &res );
+		rc = ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res );
 		if ( tool_check_abandon( ld, msgid ) ) {
 			return LDAP_CANCELLED;
 		}
 
 		if ( rc == -1 ) {
-			ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc );
+			ldap_get_option( ld, LDAP_OPT_RESULT_CODE, &rc );
 			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 			return rc;
 		}
@@ -1164,99 +1273,32 @@
 		}
 	}
 
-	if ( ldap_msgtype( res ) != LDAP_RES_INTERMEDIATE ) {
-		int code;
-		char *matcheddn = NULL, *text = NULL, **refs = NULL;
-		LDAPControl **ctrls = NULL;
-		rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, &ctrls, 1 );
+	msgtype = ldap_msgtype( res );
 
-		if ( rc != LDAP_SUCCESS ) {
-			fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
-				prog, ldap_err2string( rc ), rc );
-			return rc;
-		}
+	rc = ldap_parse_result( ld, res, &err, &matched, &text, &refs, &ctrls, 1 );
+	if ( rc == LDAP_SUCCESS ) rc = err;
 
-		if ( code != LDAP_SUCCESS ) {
-			tool_perror( prog, code, NULL, matcheddn, text, refs );
-		} else if ( verbose && 
-			((matcheddn && *matcheddn) || (text && *text) || (refs && *refs) ))
-		{
-			printf( _("Delete Result: %s (%d)\n"),
-				ldap_err2string( code ), code );
-
-			if ( text && *text ) {
-				printf( _("Additional info: %s\n"), text );
-			}
-
-			if ( matcheddn && *matcheddn ) {
-				printf( _("Matched DN: %s\n"), matcheddn );
-			}
-
-			if ( refs ) {
-				int i;
-				for( i=0; refs[i]; i++ ) {
-					printf(_("Referral: %s\n"), refs[i] );
-				}
-			}
-		}
-
-		if (ctrls) {
-			tool_print_ctrls( ld, ctrls );
-			ldap_controls_free( ctrls );
-		}
-
-		ber_memfree( text );
-		ber_memfree( matcheddn );
-		ber_memvfree( (void **) refs );
-
-		return code;
+#ifdef LDAP_X_TXN
+	if ( rc == LDAP_X_TXN_SPECIFY_OKAY ) {
+		rc = LDAP_SUCCESS;
+	} else
+#endif
+	if ( rc != LDAP_SUCCESS ) {
+		tool_perror( res2str( op ), rc, NULL, matched, text, refs );
+	} else if ( msgtype != op ) {
+		fprintf( stderr, "%s: msgtype: expected %d got %d\n",
+			res2str( op ), op, msgtype );
+		rc = LDAP_OTHER;
 	}
 
-#ifdef LDAP_GROUP_TRANSACTION
-	/* assume (successful) transaction intermediate response */
-	return LDAP_SUCCESS;
+	if ( text ) ldap_memfree( text );
+	if ( matched ) ldap_memfree( matched );
+	if ( text ) ber_memvfree( (void **)refs );
 
-#else
-	/* intermediate response? */
-	return LDAP_DECODING_ERROR;
-#endif
-}
-
-static char *
-read_one_record( FILE *fp )
-{
-	char        *buf, line[ LDAPMOD_MAXLINE ];
-	int		lcur, lmax;
-
-	lcur = lmax = 0;
-	buf = NULL;
-
-	while ( fgets( line, sizeof(line), fp ) != NULL ) {
-		int len = strlen( line );
-
-		if( len < 2 || ( len == 2 && *line == '\r' )) {
-			if( buf == NULL ) {
-				continue;
-			} else {
-				break;
-			}
-		}
-
-		if ( lcur + len + 1 > lmax ) {
-			lmax = LDAPMOD_MAXLINE
-				* (( lcur + len + 1 ) / LDAPMOD_MAXLINE + 1 );
-
-			if (( buf = (char *)ber_memrealloc( buf, lmax )) == NULL ) {
-				perror( "realloc" );
-				exit( EXIT_FAILURE );
-			}
-		}
-
-		strcpy( buf + lcur, line );
-		lcur += len;
+	if ( ctrls ) {
+		tool_print_ctrls( ld, ctrls );
+		ldap_controls_free( ctrls );
 	}
 
-	return( buf );
+	return rc;
 }
-
-

Modified: openldap/trunk/clients/tools/ldapmodrdn.c
===================================================================
--- openldap/trunk/clients/tools/ldapmodrdn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/ldapmodrdn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP */
-/* $OpenLDAP: pkg/ldap/clients/tools/ldapmodrdn.c,v 1.106.2.7 2007/08/13 18:04:39 quanah Exp $ */
+/* $OpenLDAP: pkg/ldap/clients/tools/ldapmodrdn.c,v 1.116.2.3 2007/08/31 23:13:51 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -52,6 +52,7 @@
 #include <ac/ctype.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
+#include <ac/socket.h>
 #include <ac/time.h>
 
 #include <ldap.h>
@@ -90,7 +91,7 @@
 
 
 const char options[] = "rs:"
-	"cd:D:e:f:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
+	"cd:D:e:f:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
@@ -154,7 +155,7 @@
     LDAP		*ld;
 	int		rc, retval, havedn;
 
-    tool_init();
+    tool_init( TOOL_MODRDN );
     prog = lutil_progname( "ldapmodrdn", argc, argv );
 
 	tool_args( argc, argv );
@@ -198,9 +199,7 @@
 
 	tool_bind( ld );
 
-	if ( assertion || authzid || manageDSAit || noop ) {
-		tool_server_controls( ld, NULL, 0 );
-	}
+	tool_server_controls( ld, NULL, 0 );
 
     retval = rc = 0;
     if (havedn)
@@ -254,7 +253,7 @@
 		}
 	}
 
-	if( not ) return LDAP_SUCCESS;
+	if( dont ) return LDAP_SUCCESS;
 
 	rc = ldap_rename( ld, dn, rdn, newSuperior, remove,
 		NULL, NULL, &id );
@@ -277,7 +276,7 @@
 
 		rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
 		if ( rc < 0 ) {
-			ldap_perror( ld, "ldapmodrdn: ldap_result" );
+			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 			return rc;
 		}
 

Modified: openldap/trunk/clients/tools/ldappasswd.c
===================================================================
--- openldap/trunk/clients/tools/ldappasswd.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/ldappasswd.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldappasswd -- a tool for change LDAP passwords */
-/* $OpenLDAP: pkg/ldap/clients/tools/ldappasswd.c,v 1.127.2.7 2007/08/13 18:04:39 quanah Exp $ */
+/* $OpenLDAP: pkg/ldap/clients/tools/ldappasswd.c,v 1.136.2.3 2007/08/31 23:13:51 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -81,7 +81,7 @@
 
 
 const char options[] = "a:As:St:T:"
-	"d:D:e:h:H:InO:p:QR:U:vVw:WxX:y:Y:Z";
+	"d:D:e:h:H:InO:o:p:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
@@ -179,7 +179,7 @@
 	struct berval *retdata = NULL;
 	LDAPControl **ctrls = NULL;
 
-    tool_init();
+    tool_init( TOOL_PASSWD );
 	prog = lutil_progname( "ldappasswd", argc, argv );
 
 	/* LDAPv3 only */
@@ -266,7 +266,7 @@
 	}
 
 	if( user != NULL || oldpw.bv_val != NULL || newpw.bv_val != NULL ) {
-		/* build change password control */
+		/* build the password modify request data */
 		ber = ber_alloc_t( LBER_USE_DER );
 
 		if( ber == NULL ) {
@@ -306,7 +306,7 @@
 		}
 	}
 
-	if ( not ) {
+	if ( dont ) {
 		rc = LDAP_SUCCESS;
 		goto done;
 	}
@@ -320,7 +320,7 @@
 	ber_free( ber, 1 );
 
 	if( rc != LDAP_SUCCESS ) {
-		ldap_perror( ld, "ldap_extended_operation" );
+		tool_perror( "ldap_extended_operation", rc, NULL, NULL, NULL, NULL );
 		rc = EXIT_FAILURE;
 		goto done;
 	}
@@ -337,7 +337,7 @@
 
 		rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
 		if ( rc < 0 ) {
-			ldap_perror( ld, "ldappasswd: ldap_result" );
+			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 			return rc;
 		}
 
@@ -349,14 +349,14 @@
 	rc = ldap_parse_result( ld, res,
 		&code, &matcheddn, &text, &refs, &ctrls, 0 );
 	if( rc != LDAP_SUCCESS ) {
-		ldap_perror( ld, "ldap_parse_result" );
+		tool_perror( "ldap_parse_result", rc, NULL, NULL, NULL, NULL );
 		rc = EXIT_FAILURE;
 		goto done;
 	}
 
 	rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
 	if( rc != LDAP_SUCCESS ) {
-		ldap_perror( ld, "ldap_parse_extended_result" );
+		tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
 		rc = EXIT_FAILURE;
 		goto done;
 	}
@@ -393,7 +393,6 @@
 	if( verbose || code != LDAP_SUCCESS ||
 		matcheddn || text || refs || ctrls )
 	{
-
 		printf( _("Result: %s (%d)\n"), ldap_err2string( code ), code );
 
 		if( text && *text ) {

Modified: openldap/trunk/clients/tools/ldapsearch.c
===================================================================
--- openldap/trunk/clients/tools/ldapsearch.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/ldapsearch.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldapsearch -- a tool for searching LDAP directories */
-/* $OpenLDAP: pkg/ldap/clients/tools/ldapsearch.c,v 1.207.2.12 2007/08/13 20:03:51 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/clients/tools/ldapsearch.c,v 1.234.2.5 2007/08/31 23:13:51 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -71,7 +71,24 @@
 
 #include "common.h"
 
+#if !LDAP_DEPRECATED
+/*
+ * NOTE: we use this deprecated function only because
+ * we want ldapsearch to provide some client-side sorting 
+ * capability.
+ */
+/* from ldap.h */
+typedef int (LDAP_SORT_AD_CMP_PROC) LDAP_P(( /* deprecated */
+	LDAP_CONST char *left,
+	LDAP_CONST char *right ));
 
+LDAP_F( int )	/* deprecated */
+ldap_sort_entries LDAP_P(( LDAP *ld,
+	LDAPMessage **chain,
+	LDAP_CONST char *attr,
+	LDAP_SORT_AD_CMP_PROC *cmp ));
+#endif
+
 static int scope = LDAP_SCOPE_SUBTREE;
 static int deref = -1;
 static int attrsonly;
@@ -92,7 +109,7 @@
 usage( void )
 {
 	fprintf( stderr, _("usage: %s [options] [filter [attributes...]]\nwhere:\n"), prog);
-	fprintf( stderr, _("  filter\tRFC-2254 compliant LDAP search filter\n"));
+	fprintf( stderr, _("  filter\tRFC 4515 compliant LDAP search filter\n"));
 	fprintf( stderr, _("  attributes\twhitespace-separated list of attribute descriptions\n"));
 	fprintf( stderr, _("    which may include:\n"));
 	fprintf( stderr, _("      1.1   no attributes\n"));
@@ -105,29 +122,21 @@
 	fprintf( stderr, _("  -A         retrieve attribute names only (no values)\n"));
 	fprintf( stderr, _("  -b basedn  base dn for search\n"));
 	fprintf( stderr, _("  -E [!]<ext>[=<extparam>] search extensions (! indicates criticality)\n"));
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
 	fprintf( stderr, _("             [!]domainScope              (domain scope)\n"));
-#endif
+	fprintf( stderr, _("             !dontUseCopy                (Don't Use Copy)\n"));
 	fprintf( stderr, _("             [!]mv=<filter>              (matched values filter)\n"));
-#ifdef LDAP_CONTROL_PAGEDRESULTS
 	fprintf( stderr, _("             [!]pr=<size>[/prompt|noprompt]   (paged results/prompt)\n"));
-#endif
-#ifdef LDAP_CONTROL_SUBENTRIES
 	fprintf( stderr, _("             [!]subentries[=true|false]  (subentries)\n"));
-#endif
 	fprintf( stderr, _("             [!]sync=ro[/<cookie>]            (LDAP Sync refreshOnly)\n"));
 	fprintf( stderr, _("                     rp[/<cookie>][/<slimit>] (LDAP Sync refreshAndPersist)\n"));
+	fprintf( stderr, _("             [!]<oid>=:<value>           (generic control; no response handling)\n"));
 	fprintf( stderr, _("  -F prefix  URL prefix for files (default: %s)\n"), def_urlpre);
 	fprintf( stderr, _("  -l limit   time limit (in seconds, or \"none\" or \"max\") for search\n"));
 	fprintf( stderr, _("  -L         print responses in LDIFv1 format\n"));
 	fprintf( stderr, _("  -LL        print responses in LDIF format without comments\n"));
 	fprintf( stderr, _("  -LLL       print responses in LDIF format without comments\n"));
 	fprintf( stderr, _("             and version\n"));
-#ifdef LDAP_SCOPE_SUBORDINATE
 	fprintf( stderr, _("  -s scope   one of base, one, sub or children (search scope)\n"));
-#else /* ! LDAP_SCOPE_SUBORDINATE */
-	fprintf( stderr, _("  -s scope   one of base, one, or sub (search scope)\n"));
-#endif /* ! LDAP_SCOPE_SUBORDINATE */
 	fprintf( stderr, _("  -S attr    sort the results by attribute `attr'\n"));
 	fprintf( stderr, _("  -t         write binary values to files in temporary directory\n"));
 	fprintf( stderr, _("  -tt        write all values to files in temporary directory\n"));
@@ -160,9 +169,6 @@
 	LDAPMessage *result,
 	int search );
 
-static void print_ctrls(
-	LDAPControl **ctrls );
-
 static int dosearch LDAP_P((
 	LDAP	*ld,
 	char	*base,
@@ -185,33 +191,49 @@
 static int subentries = 0, valuesReturnFilter = 0;
 static char	*vrFilter = NULL;
 
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
-static int domainScope = 0;
+#ifdef LDAP_CONTROL_DONTUSECOPY
+static int dontUseCopy = 0;
 #endif
 
+static int domainScope = 0;
+
 static int ldapsync = 0;
 static struct berval sync_cookie = { 0, NULL };
 static int sync_slimit = -1;
 
-#ifdef LDAP_CONTROL_PAGEDRESULTS
+/* cookie and morePagedResults moved to common.c */
 static int pagedResults = 0;
 static int pagePrompt = 1;
 static ber_int_t pageSize = 0;
 static ber_int_t entriesLeft = 0;
-static ber_int_t morePagedResults = 1;
-static struct berval page_cookie = { 0, NULL };
 static int npagedresponses;
 static int npagedentries;
 static int npagedreferences;
 static int npagedextended;
 static int npagedpartial;
 
-static int parse_page_control(
-	LDAP *ld,
-	LDAPMessage *result,
-	struct berval *cookie );
-#endif
+static LDAPControl *c = NULL;
+static int nctrls = 0;
+static int save_nctrls = 0;
 
+static int
+ctrl_add( void )
+{
+	LDAPControl	*tmpc;
+
+	nctrls++;
+	tmpc = realloc( c, sizeof( LDAPControl ) * nctrls );
+	if ( tmpc == NULL ) {
+		nctrls--;
+		fprintf( stderr,
+			_("unable to make room for control; out of memory?\n"));
+		return -1;
+	}
+	c = tmpc;
+
+	return 0;
+}
+
 static void
 urlize(char *url)
 {
@@ -227,7 +249,7 @@
 
 
 const char options[] = "a:Ab:cE:F:l:Ls:S:tT:uz:"
-	"Cd:D:e:f:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
+	"Cd:D:e:f:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
@@ -297,7 +319,6 @@
 			vrFilter = cvalue;
 			protocol = LDAP_VERSION3;
 
-#ifdef LDAP_CONTROL_PAGEDRESULTS
 		} else if ( strcasecmp( control, "pr" ) == 0 ) {
 			int num, tmp;
 			/* PagedResults control */
@@ -338,8 +359,26 @@
 			pageSize = (ber_int_t) tmp;
 			pagedResults = 1 + crit;
 
+#ifdef LDAP_CONTROL_DONTUSECOPY
+		} else if ( strcasecmp( control, "dontUseCopy" ) == 0 ) {
+			if( dontUseCopy ) {
+				fprintf( stderr,
+					_("dontUseCopy control previously specified\n"));
+				exit( EXIT_FAILURE );
+			}
+			if( cvalue != NULL ) {
+				fprintf( stderr,
+			         _("dontUseCopy: no control value expected\n") );
+				usage();
+			}
+			if( !crit ) {
+				fprintf( stderr,
+			         _("dontUseCopy: critical flag required\n") );
+				usage();
+			}
+
+			dontUseCopy = 1 + crit;
 #endif
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
 		} else if ( strcasecmp( control, "domainScope" ) == 0 ) {
 			if( domainScope ) {
 				fprintf( stderr,
@@ -353,9 +392,7 @@
 			}
 
 			domainScope = 1 + crit;
-#endif
 
-#ifdef LDAP_CONTROL_SUBENTRIES
 		} else if ( strcasecmp( control, "subentries" ) == 0 ) {
 			if( subentries ) {
 				fprintf( stderr,
@@ -373,7 +410,6 @@
 				exit( EXIT_FAILURE );
 			}
 			if( crit ) subentries *= -1;
-#endif
 
 		} else if ( strcasecmp( control, "sync" ) == 0 ) {
 			char *cookiep;
@@ -423,6 +459,44 @@
 			}
 			if ( crit ) ldapsync *= -1;
 
+		} else if ( tool_is_oid( control ) ) {
+			if ( ctrl_add() ) {
+				exit( EXIT_FAILURE );
+			}
+
+			/* OID */
+			c[ nctrls - 1 ].ldctl_oid = control;
+
+			/* value */
+			if ( cvalue == NULL ) {
+				c[ nctrls - 1 ].ldctl_value.bv_val = NULL;
+				c[ nctrls - 1 ].ldctl_value.bv_len = 0;
+
+			} else if ( cvalue[ 0 ] == ':' ) {
+				struct berval	type;
+				struct berval	value;
+				int		freeval;
+
+				cvalue++;
+
+				/* dummy type "x"
+				 * to use ldif_parse_line2() */
+				cvalue[ -2 ] = 'x';
+				ldif_parse_line2( &cvalue[ -2 ], &type,
+					&value, &freeval );
+				cvalue[ -2 ] = '\0';
+
+				if ( freeval ) {
+					c[ nctrls - 1 ].ldctl_value = value;
+
+				} else {
+					ber_dupbv( &c[ nctrls - 1 ].ldctl_value, &value );
+				}
+			}
+
+			/* criticality */
+			c[ nctrls - 1 ].ldctl_iscritical = crit;
+
 		} else {
 			fprintf( stderr, _("Invalid search extension name: %s\n"),
 				control );
@@ -463,12 +537,10 @@
 			scope = LDAP_SCOPE_BASE;
 		} else if ( strncasecmp( optarg, "one", sizeof("one")-1 ) == 0 ) {
 			scope = LDAP_SCOPE_ONELEVEL;
-#ifdef LDAP_SCOPE_SUBORDINATE
 		} else if (( strcasecmp( optarg, "subordinate" ) == 0 )
 			|| ( strcasecmp( optarg, "children" ) == 0 ))
 		{
 			scope = LDAP_SCOPE_SUBORDINATE;
-#endif
 		} else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) {
 			scope = LDAP_SCOPE_SUBTREE;
 		} else {
@@ -551,19 +623,18 @@
 {
 	char		*filtpattern, **attrs = NULL, line[BUFSIZ];
 	FILE		*fp = NULL;
-	int			rc, i, first;
+	int		rc, i, first;
 	LDAP		*ld = NULL;
-	BerElement	*seber = NULL, *vrber = NULL, *prber = NULL;
+	BerElement	*seber = NULL, *vrber = NULL;
 
 	BerElement      *syncber = NULL;
 	struct berval   *syncbvalp = NULL;
+	int		err;
 
-	tool_init();
+	tool_init( TOOL_SEARCH );
 
-#ifdef LDAP_CONTROL_PAGEDRESULTS
 	npagedresponses = npagedentries = npagedreferences =
 		npagedextended = npagedpartial = 0;
-#endif
 
 	prog = lutil_progname( "ldapsearch", argc, argv );
 
@@ -672,35 +743,50 @@
 	tool_bind( ld );
 
 getNextPage:
-	if ( assertion || authzid || manageDSAit || noop
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
-		|| domainScope
+	save_nctrls = nctrls;
+	i = nctrls;
+	if ( nctrls > 0
+#ifdef LDAP_CONTROL_DONTUSECOPY
+		|| dontUseCopy
 #endif
-#ifdef LDAP_CONTROL_PAGEDRESULTS
+		|| domainScope
 		|| pagedResults
-#endif
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-		|| chaining
-#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 		|| ldapsync
-		|| subentries || valuesReturnFilter )
+		|| subentries
+		|| valuesReturnFilter )
 	{
-		int err;
-		int i=0;
-		LDAPControl c[10];
 
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
+#ifdef LDAP_CONTROL_DONTUSECOPY
+		if ( dontUseCopy ) {
+			if ( ctrl_add() ) {
+				return EXIT_FAILURE;
+			}
+
+			c[i].ldctl_oid = LDAP_CONTROL_DONTUSECOPY;
+			c[i].ldctl_value.bv_val = NULL;
+			c[i].ldctl_value.bv_len = 0;
+			c[i].ldctl_iscritical = dontUseCopy > 1;
+			i++;
+		}
+#endif
+
 		if ( domainScope ) {
+			if ( ctrl_add() ) {
+				return EXIT_FAILURE;
+			}
+
 			c[i].ldctl_oid = LDAP_CONTROL_X_DOMAIN_SCOPE;
 			c[i].ldctl_value.bv_val = NULL;
 			c[i].ldctl_value.bv_len = 0;
 			c[i].ldctl_iscritical = domainScope > 1;
 			i++;
 		}
-#endif
 
-#ifdef LDAP_CONTROL_SUBENTRIES
 		if ( subentries ) {
+			if ( ctrl_add() ) {
+				return EXIT_FAILURE;
+			}
+
 			if (( seber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
 				return EXIT_FAILURE;
 			}
@@ -720,9 +806,12 @@
 			c[i].ldctl_iscritical = subentries < 1;
 			i++;
 		}
-#endif
 
 		if ( ldapsync ) {
+			if ( ctrl_add() ) {
+				return EXIT_FAILURE;
+			}
+
 			if (( syncber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
 				return EXIT_FAILURE;
 			}
@@ -751,11 +840,15 @@
 		}
 
 		if ( valuesReturnFilter ) {
-	        if (( vrber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+			if ( ctrl_add() ) {
 				return EXIT_FAILURE;
 			}
 
-	    	if ( ( err = ldap_put_vrFilter( vrber, vrFilter ) ) == -1 ) {
+			if (( vrber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+				return EXIT_FAILURE;
+			}
+
+			if ( ( err = ldap_put_vrFilter( vrber, vrFilter ) ) == -1 ) {
 				ber_free( vrber, 1 );
 				fprintf( stderr, _("Bad ValuesReturnFilter: %s\n"), vrFilter );
 				return EXIT_FAILURE;
@@ -770,38 +863,38 @@
 			i++;
 		}
 
-#ifdef LDAP_CONTROL_PAGEDRESULTS
 		if ( pagedResults ) {
-			if (( prber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+			if ( ctrl_add() ) {
 				return EXIT_FAILURE;
 			}
 
-			ber_printf( prber, "{iO}", pageSize, &page_cookie );
-			if ( ber_flatten2( prber, &c[i].ldctl_value, 0 ) == -1 ) {
+			if ( ldap_create_page_control_value( ld,
+				pageSize, &pr_cookie, &c[i].ldctl_value ) )
+			{
 				return EXIT_FAILURE;
 			}
-			if ( page_cookie.bv_val != NULL ) {
-				ber_memfree( page_cookie.bv_val );
-				page_cookie.bv_val = NULL;
+
+			if ( pr_cookie.bv_val != NULL ) {
+				ber_memfree( pr_cookie.bv_val );
+				pr_cookie.bv_val = NULL;
+				pr_cookie.bv_len = 0;
 			}
 			
 			c[i].ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
 			c[i].ldctl_iscritical = pagedResults > 1;
 			i++;
 		}
-#endif
+	}
 
-		tool_server_controls( ld, c, i );
+	tool_server_controls( ld, c, i );
 
-#ifdef LDAP_CONTROL_SUBENTRIES
-		ber_free( seber, 1 );
-#endif
-		ber_free( vrber, 1 );
-#ifdef LDAP_CONTROL_PAGEDRESULTS
-		ber_free( prber, 1 );
-#endif
-	}
-	
+	ber_free( seber, 1 );
+	ber_free( vrber, 1 );
+
+	/* step back to the original number of controls, so that 
+	 * those set while parsing args are preserved */
+	nctrls = save_nctrls;
+
 	if ( verbose ) {
 		fprintf( stderr, _("filter%s: %s\nrequesting: "),
 			infile != NULL ? _(" pattern") : "",
@@ -824,20 +917,21 @@
 	}
 
 	if (ldif < 2 ) {
+		char	*realbase = base;
+
+		if ( realbase == NULL ) {
+			ldap_get_option( ld, LDAP_OPT_DEFBASE, (void **)(char *)&realbase );
+		}
+		
 		printf( "#\n" );
 		printf(_("# LDAPv%d\n"), protocol);
-		printf(_("# base <%s> with scope %s\n"),
-			base ? base : "",
+		printf(_("# base <%s>%s with scope %s\n"),
+			realbase ? realbase : "",
+			( realbase == NULL || realbase != base ) ? " (default)" : "",
 			((scope == LDAP_SCOPE_BASE) ? "baseObject"
 				: ((scope == LDAP_SCOPE_ONELEVEL) ? "oneLevel"
-#ifdef LDAP_SCOPE_SUBORDINATE
 				: ((scope == LDAP_SCOPE_SUBORDINATE) ? "children"
-#endif
-				: "subtree"
-#ifdef LDAP_SCOPE_SUBORDINATE
-				)
-#endif
-				)));
+				: "subtree" ))));
 		printf(_("# filter%s: %s\n"), infile != NULL ? _(" pattern") : "",
 		       filtpattern);
 		printf(_("# requesting: "));
@@ -867,15 +961,17 @@
 			printf(_("\n# with valuesReturnFilter %scontrol: %s"),
 				valuesReturnFilter > 1 ? _("critical ") : "", vrFilter );
 		}
-#ifdef LDAP_CONTROL_PAGEDRESULTS
 		if ( pagedResults ) {
 			printf(_("\n# with pagedResults %scontrol: size=%d"),
 				(pagedResults > 1) ? _("critical ") : "", 
 				pageSize );
 		}
-#endif
 
 		printf( _("\n#\n\n") );
+
+		if ( realbase && realbase != base ) {
+			ldap_memfree( realbase );
+		}
 	}
 
 	if ( infile == NULL ) {
@@ -883,9 +979,8 @@
 			attrs, attrsonly, NULL, NULL, NULL, -1 );
 
 	} else {
-		rc = 0;
 		first = 1;
-		while ( rc == 0 && fgets( line, sizeof( line ), fp ) != NULL ) { 
+		while ( fgets( line, sizeof( line ), fp ) != NULL ) { 
 			line[ strlen( line ) - 1 ] = '\0';
 			if ( !first ) {
 				putchar( '\n' );
@@ -894,14 +989,17 @@
 			}
 			rc = dosearch( ld, base, scope, filtpattern, line,
 				attrs, attrsonly, NULL, NULL, NULL, -1 );
+
+			if ( rc != 0 && !contoper ) {
+				break;
+			}
 		}
 		if ( fp != stdin ) {
 			fclose( fp );
 		}
 	}
 
-#ifdef LDAP_CONTROL_PAGEDRESULTS
-	if ( ( rc == LDAP_SUCCESS ) &&  ( pageSize != 0 ) && ( morePagedResults != 0 ) ) {
+	if (( rc == LDAP_SUCCESS ) && pageSize && pr_morePagedResults ) {
 		char	buf[6];
 		int	i, moreEntries, tmpSize;
 
@@ -928,7 +1026,8 @@
 			if ( i > 0 && isdigit( (unsigned char)buf[0] ) ) {
 				int num = sscanf( buf, "%d", &tmpSize );
 				if ( num != 1 ) {
-					fprintf( stderr, _("Invalid value for PagedResultsControl, %s.\n"), buf);
+					fprintf( stderr,
+						_("Invalid value for PagedResultsControl, %s.\n"), buf);
 					return EXIT_FAILURE;
 	
 				}
@@ -938,10 +1037,18 @@
 
 		goto getNextPage;
 	}
-#endif
 
 	tool_unbind( ld );
 	tool_destroy();
+
+	if ( c ) {
+		for ( ; save_nctrls-- > 0; ) {
+			ber_memfree( c[ save_nctrls ].ldctl_value.bv_val );
+		}
+		free( c );
+		c = NULL;
+	}
+
 	return( rc );
 }
 
@@ -974,13 +1081,18 @@
 	int			cancel_msgid = -1;
 
 	if( filtpatt != NULL ) {
-		filter = malloc( strlen( filtpatt ) + strlen( value ) );
+		size_t max_fsize = strlen( filtpatt ) + strlen( value ) + 1;
+		filter = malloc( max_fsize );
 		if( filter == NULL ) {
 			perror( "malloc" );
 			return EXIT_FAILURE;
 		}
 
-		sprintf( filter, filtpatt, value );
+		if( snprintf( filter, max_fsize, filtpatt, value ) >= max_fsize ) {
+			fprintf( stderr, "Bad filter pattern: \"%s\"\n", filtpatt );
+			free( filter );
+			return EXIT_FAILURE;
+		}
 
 		if ( verbose ) {
 			fprintf( stderr, _("filter: %s\n"), filter );
@@ -994,7 +1106,10 @@
 		filter = value;
 	}
 
-	if ( not ) {
+	if ( dont ) {
+		if ( filtpatt != NULL ) {
+			free( filter );
+		}
 		return LDAP_SUCCESS;
 	}
 
@@ -1052,7 +1167,7 @@
 				nextended++;
 				print_extended( ld, msg );
 
-				if( ldap_msgid( msg ) == 0 ) {
+				if ( ldap_msgid( msg ) == 0 ) {
 					/* unsolicited extended operation */
 					goto done;
 				}
@@ -1066,19 +1181,10 @@
 				break;
 
 			case LDAP_RES_SEARCH_RESULT:
+				/* pagedResults stuff is dealt with
+				 * in tool_print_ctrls(), called by
+				 * print_results(). */
 				rc = print_result( ld, msg, 1 );
-#ifdef LDAP_CONTROL_PAGEDRESULTS
-				if ( pageSize != 0 ) {
-					if ( rc == LDAP_SUCCESS ) {
-						rc = parse_page_control( ld, msg, &page_cookie );
-					} else {
-						morePagedResults = 0;
-					}
-				} else {
-					morePagedResults = 0;
-				}
-#endif
-
 				if ( ldapsync == LDAP_SYNC_REFRESH_AND_PERSIST ) {
 					break;
 				}
@@ -1112,8 +1218,8 @@
 				msgidber = ber_alloc_t(LBER_USE_DER);
 				ber_printf(msgidber, "{i}", msgid);
 				ber_flatten(msgidber, &msgidvalp);
-				ldap_extended_operation(ld, LDAP_EXOP_X_CANCEL,
-						msgidvalp, NULL, NULL, &cancel_msgid);
+				ldap_extended_operation(ld, LDAP_EXOP_CANCEL,
+					msgidvalp, NULL, NULL, &cancel_msgid);
 				nresponses_psearch = -1;
 			}
 		}
@@ -1123,28 +1229,34 @@
 
 done:
 	if ( rc == -1 ) {
-		ldap_perror( ld, "ldap_result" );
+		tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 		return( rc );
 	}
 
 	ldap_msgfree( res );
-#ifdef LDAP_CONTROL_PAGEDRESULTS
+
 	if ( pagedResults ) { 
 		npagedresponses += nresponses;
 		npagedentries += nentries;
 		npagedextended += nextended;
 		npagedpartial += npartial;
 		npagedreferences += nreferences;
-		if ( ( morePagedResults == 0 ) && ( ldif < 2 ) ) {
+		if ( ( pr_morePagedResults == 0 ) && ( ldif < 2 ) ) {
 			printf( _("\n# numResponses: %d\n"), npagedresponses );
-			if( npagedentries ) printf( _("# numEntries: %d\n"), npagedentries );
-			if( npagedextended ) printf( _("# numExtended: %d\n"), npagedextended );
-			if( npagedpartial ) printf( _("# numPartial: %d\n"), npagedpartial );
-			if( npagedreferences ) printf( _("# numReferences: %d\n"), npagedreferences );
+			if( npagedentries ) {
+				printf( _("# numEntries: %d\n"), npagedentries );
+			}
+			if( npagedextended ) {
+				printf( _("# numExtended: %d\n"), npagedextended );
+			}
+			if( npagedpartial ) {
+				printf( _("# numPartial: %d\n"), npagedpartial );
+			}
+			if( npagedreferences ) {
+				printf( _("# numReferences: %d\n"), npagedreferences );
+			}
 		}
-	} else
-#endif
-	if ( ldif < 2 ) {
+	} else if ( ldif < 2 ) {
 		printf( _("\n# numResponses: %d\n"), nresponses );
 		if( nentries ) printf( _("# numEntries: %d\n"), nentries );
 		if( nextended ) printf( _("# numExtended: %d\n"), nextended );
@@ -1184,12 +1296,12 @@
 	rc = ldap_get_entry_controls( ld, entry, &ctrls );
 	if( rc != LDAP_SUCCESS ) {
 		fprintf(stderr, _("print_entry: %d\n"), rc );
-		ldap_perror( ld, "ldap_get_entry_controls" );
+		tool_perror( "ldap_get_entry_controls", rc, NULL, NULL, NULL, NULL );
 		exit( EXIT_FAILURE );
 	}
 
 	if( ctrls ) {
-		print_ctrls( ctrls );
+		tool_print_ctrls( ld, ctrls );
 		ldap_controls_free( ctrls );
 	}
 
@@ -1282,7 +1394,7 @@
 	rc = ldap_parse_reference( ld, reference, &refs, &ctrls, 0 );
 
 	if( rc != LDAP_SUCCESS ) {
-		ldap_perror(ld, "ldap_parse_reference");
+		tool_perror( "ldap_parse_reference", rc, NULL, NULL, NULL, NULL );
 		exit( EXIT_FAILURE );
 	}
 
@@ -1296,7 +1408,7 @@
 	}
 
 	if( ctrls ) {
-		print_ctrls( ctrls );
+		tool_print_ctrls( ld, ctrls );
 		ldap_controls_free( ctrls );
 	}
 }
@@ -1317,7 +1429,7 @@
 		&retoid, &retdata, 0 );
 
 	if( rc != LDAP_SUCCESS ) {
-		ldap_perror(ld, "ldap_parse_extended_result");
+		tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
 		exit( EXIT_FAILURE );
 	}
 
@@ -1355,7 +1467,7 @@
 		&retoid, &retdata, &ctrls, 0 );
 
 	if( rc != LDAP_SUCCESS ) {
-		ldap_perror(ld, "ldap_parse_intermediate");
+		tool_perror( "ldap_parse_intermediate", rc, NULL, NULL, NULL, NULL );
 		exit( EXIT_FAILURE );
 	}
 
@@ -1376,7 +1488,7 @@
 	}
 
 	if( ctrls ) {
-		print_ctrls( ctrls );
+		tool_print_ctrls( ld, ctrls );
 		ldap_controls_free( ctrls );
 	}
 }
@@ -1405,7 +1517,7 @@
 		&err, &matcheddn, &text, &refs, &ctrls, 0 );
 
 	if( rc != LDAP_SUCCESS ) {
-		ldap_perror(ld, "ldap_parse_result");
+		tool_perror( "ldap_parse_result", rc, NULL, NULL, NULL, NULL );
 		exit( EXIT_FAILURE );
 	}
 
@@ -1432,13 +1544,28 @@
 
 	if( text ) {
 		if( *text ) {
-		if( !ldif ) {
-			tool_write_ldif( LDIF_PUT_TEXT, "text",
-				text, strlen(text) );
-		} else {
-			fprintf( stderr, _("Additional information: %s\n"), text );
+			if( !ldif ) {
+				if ( err == LDAP_PARTIAL_RESULTS ) {
+					char	*line;
+
+					for ( line = text; line != NULL; ) {
+						char	*next = strchr( line, '\n' );
+
+						tool_write_ldif( LDIF_PUT_TEXT,
+							"text", line,
+							next ? next - line : strlen( line ) );
+
+						line = next ? next + 1 : NULL;
+					}
+
+				} else {
+					tool_write_ldif( LDIF_PUT_TEXT, "text",
+						text, strlen(text) );
+				}
+			} else {
+				fprintf( stderr, _("Additional information: %s\n"), text );
+			}
 		}
-		}
 
 		ber_memfree( text );
 	}
@@ -1456,145 +1583,13 @@
 		ber_memvfree( (void **) refs );
 	}
 
+	pr_morePagedResults = 0;
+
 	if( ctrls ) {
-		print_ctrls( ctrls );
+		tool_print_ctrls( ld, ctrls );
 		ldap_controls_free( ctrls );
 	}
 
 	return err;
 }
 
-static void print_ctrls(
-	LDAPControl **ctrls )
-{
-	int i;
-	for(i=0; ctrls[i] != NULL; i++ ) {
-		/* control: OID criticality base64value */
-		struct berval *b64 = NULL;
-		ber_len_t len;
-		char *str;
-
-		len = ldif ? 2 : 0;
-		len += strlen( ctrls[i]->ldctl_oid );
-
-		/* add enough for space after OID and the critical value itself */
-		len += ctrls[i]->ldctl_iscritical
-			? sizeof("true") : sizeof("false");
-
-		/* convert to base64 */
-		if( ctrls[i]->ldctl_value.bv_len ) {
-			b64 = ber_memalloc( sizeof(struct berval) );
-			
-			b64->bv_len = LUTIL_BASE64_ENCODE_LEN(
-				ctrls[i]->ldctl_value.bv_len ) + 1;
-			b64->bv_val = ber_memalloc( b64->bv_len + 1 );
-
-			b64->bv_len = lutil_b64_ntop(
-				(unsigned char *) ctrls[i]->ldctl_value.bv_val,
-				ctrls[i]->ldctl_value.bv_len,
-				b64->bv_val, b64->bv_len );
-		}
-
-		if( b64 ) {
-			len += 1 + b64->bv_len;
-		}
-
-		str = malloc( len + 1 );
-		if ( ldif ) {
-			strcpy( str, ": " );
-		} else {
-			str[0] = '\0';
-		}
-		strcat( str, ctrls[i]->ldctl_oid );
-		strcat( str, ctrls[i]->ldctl_iscritical
-			? " true" : " false" );
-
-		if( b64 ) {
-			strcat(str, " ");
-			strcat(str, b64->bv_val );
-		}
-
-		if ( ldif < 2 ) {
-			tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
-				"control", str, len );
-		}
-
-		free( str );
-		ber_bvfree( b64 );
-	}
-}
-
-#ifdef LDAP_CONTROL_PAGEDRESULTS
-static int 
-parse_page_control(
-	LDAP *ld,
-	LDAPMessage *result,
-	struct berval *cookie )
-{
-	int rc;
-	int err;
-	LDAPControl **ctrl = NULL;
-	LDAPControl *ctrlp = NULL;
-	BerElement *ber;
-	ber_tag_t tag;
-
-	rc = ldap_parse_result( ld, result,
-		&err, NULL, NULL, NULL, &ctrl, 0 );
-
-	if( rc != LDAP_SUCCESS ) {
-		ldap_perror(ld, "ldap_parse_result");
-		exit( EXIT_FAILURE );
-	}
-
-	if ( err != LDAP_SUCCESS ) {
-		fprintf( stderr, "%s (%d)\n", ldap_err2string(err), err );
-	}
-
-	if ( ctrl ) {
-		/* There might be others, e.g. ppolicy... */
-		ctrlp = ldap_find_control( LDAP_CONTROL_PAGEDRESULTS, ctrl );
-	}
-
-	if ( ctrlp ) {
-		/* Parse the control value
-		 * searchResult ::= SEQUENCE {
-		 *		size	INTEGER (0..maxInt),
-		 *				-- result set size estimate from server - unused
-		 *		cookie	OCTET STRING
-		 * }
-		 */
-		ctrlp = *ctrl;
-		ber = ber_init( &ctrlp->ldctl_value );
-		if ( ber == NULL ) {
-			fprintf( stderr, _("Internal error.\n") );
-			return EXIT_FAILURE;
-		}
-
-		tag = ber_scanf( ber, "{io}", &entriesLeft, cookie );
-		(void) ber_free( ber, 1 );
-
-		if( tag == LBER_ERROR ) {
-			fprintf( stderr,
-				_("Paged results response control could not be decoded.\n") );
-			return EXIT_FAILURE;
-		}
-
-		if( entriesLeft < 0 ) {
-			fprintf( stderr,
-				_("Invalid entries estimate in paged results response.\n") );
-			return EXIT_FAILURE;
-		}
-
-		if ( cookie->bv_len == 0 ) {
-			morePagedResults = 0;
-		}
-
-		ldap_controls_free( ctrl );
-
-	} else {
-		morePagedResults = 0;
-	}
-
-	return err;
-}
-#endif

Modified: openldap/trunk/clients/tools/ldapwhoami.c
===================================================================
--- openldap/trunk/clients/tools/ldapwhoami.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/clients/tools/ldapwhoami.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldapwhoami.c -- a tool for asking the directory "Who Am I?" */
-/* $OpenLDAP: pkg/ldap/clients/tools/ldapwhoami.c,v 1.33.2.6 2007/08/13 18:04:39 quanah Exp $ */
+/* $OpenLDAP: pkg/ldap/clients/tools/ldapwhoami.c,v 1.42.2.2 2007/08/31 23:13:51 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -62,7 +62,7 @@
 
 
 const char options[] = ""
-	"d:D:e:h:H:InO:p:QR:U:vVw:WxX:y:Y:Z";
+	"d:D:e:h:H:InO:o:p:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
@@ -109,18 +109,15 @@
 main( int argc, char *argv[] )
 {
 	int		rc;
-	char		*user = NULL;
-
 	LDAP		*ld = NULL;
-
 	char		*matcheddn = NULL, *text = NULL, **refs = NULL;
 	char		*retoid = NULL;
 	struct berval	*retdata = NULL;
-	int		id, code=0;
+	int		id, code = 0;
 	LDAPMessage	*res;
 	LDAPControl	**ctrls = NULL;
 
-	tool_init();
+	tool_init( TOOL_WHOAMI );
 	prog = lutil_progname( "ldapwhoami", argc, argv );
 
 	/* LDAPv3 only */
@@ -128,12 +125,8 @@
 
 	tool_args( argc, argv );
 
-	if( argc - optind > 1 ) {
+	if( argc - optind > 0 ) {
 		usage();
-	} else if ( argc - optind == 1 ) {
-		user = strdup( argv[optind] );
-	} else {
-		user = NULL;
 	}
 
 	if ( pw_file || want_bindpw ) {
@@ -150,19 +143,17 @@
 
 	tool_bind( ld );
 
-	if ( not ) {
+	if ( dont ) {
 		rc = LDAP_SUCCESS;
 		goto skip;
 	}
 
-	if ( assertion || authzid || manageDSAit || noop ) {
-		tool_server_controls( ld, NULL, 0 );
-	}
+	tool_server_controls( ld, NULL, 0 );
 
 	rc = ldap_whoami( ld, NULL, NULL, &id ); 
 
 	if( rc != LDAP_SUCCESS ) {
-		ldap_perror( ld, "ldap_whoami" );
+		tool_perror( "ldap_whoami", rc, NULL, NULL, NULL, NULL );
 		rc = EXIT_FAILURE;
 		goto skip;
 	}
@@ -179,7 +170,7 @@
 
 		rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
 		if ( rc < 0 ) {
-			ldap_perror( ld, "ldapwhoami: ldap_result" );
+			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 			return rc;
 		}
 
@@ -191,8 +182,12 @@
 	rc = ldap_parse_result( ld, res,
 		&code, &matcheddn, &text, &refs, &ctrls, 0 );
 
-	if( rc != LDAP_SUCCESS ) {
-		ldap_perror( ld, "ldap_parse_result" );
+	if ( rc == LDAP_SUCCESS ) {
+		rc = code;
+	}
+
+	if ( rc != LDAP_SUCCESS ) {
+		tool_perror( "ldap_parse_result", rc, NULL, matcheddn, text, refs );
 		rc = EXIT_FAILURE;
 		goto skip;
 	}
@@ -200,7 +195,7 @@
 	rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
 
 	if( rc != LDAP_SUCCESS ) {
-		ldap_perror( ld, "ldap_parse_result" );
+		tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
 		rc = EXIT_FAILURE;
 		goto skip;
 	}

Modified: openldap/trunk/configure
===================================================================
--- openldap/trunk/configure	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/configure	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.33 2007/06/10 18:39:53 hallvard Exp .
+# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.631.2.7 2007/10/16 23:43:09 quanah Exp .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -465,7 +465,7 @@
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar OPENLDAP_LIBRELEASE OPENLDAP_LIBVERSION OPENLDAP_RELEASE_DATE top_builddir ldap_subdir CC AR CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB DLLTOOL ac_ct_DLLTOOL AS ac_ct_AS OBJDUMP ac_ct_OBJDUMP CPP LIBTOOL PERLBIN OL_MKDEP OL_MKDEP_FLAGS LTSTATIC LIBOBJS LIBSRCS PLAT WITH_SASL WITH_TLS WITH_MODULES_ENABLED WITH_ACI_ENABLED BUILD_THREAD BUILD_LIBS_DYNAMIC BUILD_SLAPD BUILD_SLAPI SLAPD_SLAPI_DEPEND BUILD_BDB BUILD_DNSSRV BUILD_HDB BUILD_LDAP BUILD_LDBM BUILD_META BUILD_MONITOR BUILD_NULL BUILD_PASSWD BUILD_RELAY BUILD_PERL BUILD_SHELL BUILD_SQL BUILD_ACCESSLOG BUILD_AUDITLOG BUILD_DENYOP BUILD_DYNGROUP BUILD_DYNLIST BUILD_LASTMOD BUILD_PPOLICY BUILD_PROXYCACHE BUILD_REFINT BUILD_RETCODE BUILD_RWM BUILD_SYNCPROV BUILD_TRANSLUCENT BUILD_UNIQUE BUILD_VALSORT BUILD_SLURPD LDAP_LIBS SLAPD_LIBS SLURPD_LIBS LDBM_LIBS LTHREAD_LIBS LUTIL_LIBS WRAP_LIBS SLAPD_MODULES_CPPFLAGS SLAPD_MODULES_LDFLAGS SLAPD_NO_STATIC SLAPD_STATIC_BACKENDS SLAPD_DYNAMIC_BACKENDS SLAPD_STATIC_OVERLAYS SLAPD_DYNAMIC_OVERLAYS PERL_CPPFLAGS SLAPD_PERL_LDFLAGS MOD_PERL_LDFLAGS KRB4_LIBS KRB5_LIBS SASL_LIBS TLS_LIBS MODULES_LIBS SLAPI_LIBS LIBSLAPI LIBSLAPITOOLS AUTH_LIBS SLAPD_SLP_LIBS SLAPD_GMP_LIBS SLAPD_SQL_LDFLAGS SLAPD_SQL_LIBS SLAPD_SQL_INCLUDES LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar OPENLDAP_LIBRELEASE OPENLDAP_LIBVERSION OPENLDAP_RELEASE_DATE top_builddir ldap_subdir CC AR CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB DLLTOOL ac_ct_DLLTOOL AS ac_ct_AS OBJDUMP ac_ct_OBJDUMP CPP LIBTOOL PERLBIN OL_MKDEP OL_MKDEP_FLAGS LTSTATIC LIBOBJS LIBSRCS PLAT WITH_SASL WITH_TLS WITH_MODULES_ENABLED WITH_ACI_ENABLED BUILD_THREAD BUILD_LIBS_DYNAMIC BUILD_SLAPD BUILD_SLAPI SLAPD_SLAPI_DEPEND BUILD_BDB BUILD_DNSSRV BUILD_HDB BUILD_LDAP BUILD_META BUILD_MONITOR BUILD_NULL BUILD_PASSWD BUILD_RELAY BUILD_PERL BUILD_SHELL BUILD_SQL BUILD_ACCESSLOG BUILD_AUDITLOG BUILD_CONSTRAINT BUILD_DDS BUILD_DENYOP BUILD_DYNGROUP BUILD_DYNLIST BUILD_LASTMOD BUILD_MEMBEROF BUILD_PPOLICY BUILD_PROXYCACHE BUILD_REFINT BUILD_RETCODE BUILD_RWM BUILD_SEQMOD BUILD_SYNCPROV BUILD_TRANSLUCENT BUILD_UNIQUE BUILD_VALSORT LDAP_LIBS SLAPD_LIBS BDB_LIBS LTHREAD_LIBS LUTIL_LIBS WRAP_LIBS SLAPD_MODULES_CPPFLAGS SLAPD_MODULES_LDFLAGS SLAPD_NO_STATIC SLAPD_STATIC_BACKENDS SLAPD_DYNAMIC_BACKENDS SLAPD_STATIC_OVERLAYS SLAPD_DYNAMIC_OVERLAYS PERL_CPPFLAGS SLAPD_PERL_LDFLAGS MOD_PERL_LDFLAGS KRB4_LIBS KRB5_LIBS SASL_LIBS TLS_LIBS MODULES_LIBS SLAPI_LIBS LIBSLAPI LIBSLAPITOOLS AUTH_LIBS ICU_LIBS SLAPD_SLP_LIBS SLAPD_GMP_LIBS SLAPD_SQL_LDFLAGS SLAPD_SQL_LIBS SLAPD_SQL_INCLUDES LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -1006,7 +1006,7 @@
 Optional Features:
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --enable-debug 	  enable debugging [yes]
+  --enable-debug 	  enable debugging no|yes|traditional [yes]
   --enable-dynamic	  enable linking built binaries with dynamic libs [no]
   --enable-syslog	  enable syslog support [auto]
   --enable-proctitle	  enable proctitle support [yes]
@@ -1015,7 +1015,8 @@
 
 SLAPD (Standalone LDAP Daemon) Options:
   --enable-slapd	  enable building slapd [yes]
-    --enable-aci	  enable per-object ACIs (experimental) [no]
+    --enable-dynacl	  enable run-time loadable ACL support (experimental) [no]
+    --enable-aci	  enable per-object ACIs (experimental) no|yes|mod [no]
     --enable-cleartext	  enable cleartext passwords [yes]
     --enable-crypt	  enable crypt(3) passwords [no]
     --enable-lmpasswd	  enable LAN Manager passwords [no]
@@ -1033,9 +1034,6 @@
     --enable-dnssrv	  enable dnssrv backend no|yes|mod [no]
     --enable-hdb	  enable Hierarchical DB backend no|yes|mod [yes]
     --enable-ldap	  enable ldap backend no|yes|mod [no]
-    --enable-ldbm	  enable ldbm backend no|yes|mod [no]
-      --enable-ldbm-api   use LDBM API auto|berkeley|bcompat|mdbm|gdbm [auto]
-      --enable-ldbm-type  use LDBM type auto|btree|hash [auto]
     --enable-meta	  enable metadirectory backend no|yes|mod [no]
     --enable-monitor	  enable monitor backend no|yes|mod [yes]
     --enable-null	  enable null backend no|yes|mod [no]
@@ -1049,23 +1047,22 @@
     --enable-overlays	  enable all available overlays no|yes|mod
     --enable-accesslog	  In-Directory Access Logging overlay no|yes|mod [no]
     --enable-auditlog	  Audit Logging overlay no|yes|mod [no]
-    --enable-denyop  	  Deny Operation overlay no|yes|mod [no]
+    --enable-constraint	  Attribute Constraint overlay no|yes|mod [no]
+    --enable-dds  	  Dynamic Directory Services overlay no|yes|mod [no]
     --enable-dyngroup	  Dynamic Group overlay no|yes|mod [no]
     --enable-dynlist	  Dynamic List overlay no|yes|mod [no]
-    --enable-lastmod	  Last Modification overlay no|yes|mod [no]
+    --enable-memberof	  Reverse Group Membership overlay no|yes|mod [no]
     --enable-ppolicy	  Password Policy overlay no|yes|mod [no]
     --enable-proxycache	  Proxy Cache overlay no|yes|mod [no]
     --enable-refint	  Referential Integrity overlay no|yes|mod [no]
     --enable-retcode	  Return Code testing overlay no|yes|mod [no]
     --enable-rwm       	  Rewrite/Remap overlay no|yes|mod [no]
+    --enable-seqmod	  Sequential Modify overlay no|yes|mod [yes]
     --enable-syncprov	  Syncrepl Provider overlay no|yes|mod [yes]
     --enable-translucent  Translucent Proxy overlay no|yes|mod [no]
     --enable-unique       Attribute Uniqueness overlay no|yes|mod [no]
     --enable-valsort      Value Sorting overlay no|yes|mod [no]
 
-SLURPD (Replication Daemon) Options:
-  --enable-slurpd	  enable building slurpd [auto]
-
 Library Generation & Linking Options
   --enable-static[=PKGS]
                           build static libraries [default=yes]
@@ -1084,11 +1081,10 @@
   --with-cyrus-sasl	  with Cyrus SASL support [auto]
   --with-fetch		  with fetch(3) URL support [auto]
   --with-threads	  with threads [auto]
-  --with-tls		  with TLS/SSL support [auto]
+  --with-tls		  with TLS/SSL support auto|openssl|gnutls [auto]
   --with-yielding-select  with implicitly yielding select [auto]
   --with-mp               with multiple precision statistics auto|longlong|long|bignum|gmp [auto]
   --with-odbc             with specific ODBC support iodbc|unixodbc|auto [auto]
-
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-pic              try to use only PIC/non-PIC objects [default=use
                           both]
@@ -1597,8 +1593,11 @@
 
 SHTOOL="$ac_cv_shtool"
 
-TB="`$SHTOOL echo -e '%B' 2>/dev/null`"
-TN="`$SHTOOL echo -e '%b' 2>/dev/null`"
+TB="" TN=""
+if test -t 1; then
+	TB="`$SHTOOL echo -e '%B' 2>/dev/null`"
+	TN="`$SHTOOL echo -e '%b' 2>/dev/null`"
+fi
 
 OPENLDAP_CVS=""
 if test -d $ac_aux_dir/CVS; then
@@ -2177,7 +2176,7 @@
   enableval="$enable_debug"
 
 	ol_arg=invalid
-	for ol_val in auto yes no ; do
+	for ol_val in no yes traditional ; do
 		if test "$enableval" = "$ol_val" ; then
 			ol_arg="$ol_val"
 		fi
@@ -2263,7 +2262,6 @@
 fi;
 # end --enable-proctitle
 ol_enable_referrals=${ol_enable_referrals-no}
-ol_enable_kbind=${ol_enable_kbind-no}
 # OpenLDAP --enable-ipv6
 
 	# Check whether --enable-ipv6 or --disable-ipv6 was given.
@@ -2357,7 +2355,6 @@
   	ol_with_fetch="auto"
 fi; # end --with-fetch
 
-ol_with_kerberos=${ol_with_kerberos-auto}
 # OpenLDAP --with-threads
 
 # Check whether --with-threads or --without-threads was given.
@@ -2388,7 +2385,7 @@
   withval="$with_tls"
 
 	ol_arg=invalid
-	for ol_val in auto openssl yes no  ; do
+	for ol_val in auto openssl gnutls yes no  ; do
 		if test "$withval" = "$ol_val" ; then
 			ol_arg="$ol_val"
 		fi
@@ -2503,6 +2500,29 @@
   	ol_enable_slapd=yes
 fi;
 # end --enable-slapd
+# OpenLDAP --enable-dynacl
+
+	# Check whether --enable-dynacl or --disable-dynacl was given.
+if test "${enable_dynacl+set}" = set; then
+  enableval="$enable_dynacl"
+
+	ol_arg=invalid
+	for ol_val in auto yes no ; do
+		if test "$enableval" = "$ol_val" ; then
+			ol_arg="$ol_val"
+		fi
+	done
+	if test "$ol_arg" = "invalid" ; then
+		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-dynacl" >&5
+echo "$as_me: error: bad value $enableval for --enable-dynacl" >&2;}
+   { (exit 1); exit 1; }; }
+	fi
+	ol_enable_dynacl="$ol_arg"
+
+else
+  	ol_enable_dynacl=no
+fi;
+# end --enable-dynacl
 # OpenLDAP --enable-aci
 
 	# Check whether --enable-aci or --disable-aci was given.
@@ -2510,7 +2530,7 @@
   enableval="$enable_aci"
 
 	ol_arg=invalid
-	for ol_val in auto yes no ; do
+	for ol_val in no yes mod ; do
 		if test "$enableval" = "$ol_val" ; then
 			ol_arg="$ol_val"
 		fi
@@ -2641,7 +2661,6 @@
   	ol_enable_modules=no
 fi;
 # end --enable-modules
-ol_enable_multimaster=${ol_enable_multimaster-no}
 # OpenLDAP --enable-rewrite
 
 	# Check whether --enable-rewrite or --disable-rewrite was given.
@@ -2762,7 +2781,6 @@
 	dnssrv \
 	hdb \
 	ldap \
-	ldbm \
 	meta \
 	monitor \
 	null \
@@ -2891,95 +2909,6 @@
   	ol_enable_ldap=${ol_enable_backends:-no}
 fi;
 # end --enable-ldap
-# OpenLDAP --enable-ldbm
-
-	# Check whether --enable-ldbm or --disable-ldbm was given.
-if test "${enable_ldbm+set}" = set; then
-  enableval="$enable_ldbm"
-
-	ol_arg=invalid
-	for ol_val in no yes mod ; do
-		if test "$enableval" = "$ol_val" ; then
-			ol_arg="$ol_val"
-		fi
-	done
-	if test "$ol_arg" = "invalid" ; then
-		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-ldbm" >&5
-echo "$as_me: error: bad value $enableval for --enable-ldbm" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-	ol_enable_ldbm="$ol_arg"
-
-else
-  	ol_enable_ldbm=${ol_enable_backends:-no}
-fi;
-# end --enable-ldbm
-
-# Check whether --with-ldbm_api or --without-ldbm_api was given.
-if test "${with_ldbm_api+set}" = set; then
-  withval="$with_ldbm_api"
-
-	{ echo "$as_me:$LINENO: WARNING: Please use --enable-ldbm-api instead of --with-ldbm-api" >&5
-echo "$as_me: WARNING: Please use --enable-ldbm-api instead of --with-ldbm-api" >&2;}
-	enable_ldbm_api="$with_ldbm_api"
-fi;
-# OpenLDAP --enable-ldbm_api
-
-	# Check whether --enable-ldbm_api or --disable-ldbm_api was given.
-if test "${enable_ldbm_api+set}" = set; then
-  enableval="$enable_ldbm_api"
-
-	ol_arg=invalid
-	for ol_val in auto berkeley bcompat mdbm gdbm ; do
-		if test "$enableval" = "$ol_val" ; then
-			ol_arg="$ol_val"
-		fi
-	done
-	if test "$ol_arg" = "invalid" ; then
-		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-ldbm_api" >&5
-echo "$as_me: error: bad value $enableval for --enable-ldbm_api" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-	ol_enable_ldbm_api="$ol_arg"
-
-else
-  	ol_enable_ldbm_api=auto
-fi;
-# end --enable-ldbm_api
-
-
-# Check whether --with-ldbm_type or --without-ldbm_type was given.
-if test "${with_ldbm_type+set}" = set; then
-  withval="$with_ldbm_type"
-
-	{ echo "$as_me:$LINENO: WARNING: Please use --enable-ldbm-type instead of --with-ldbm-type" >&5
-echo "$as_me: WARNING: Please use --enable-ldbm-type instead of --with-ldbm-type" >&2;}
-	enable_ldbm_type="$with_ldbm_type"
-fi;
-# OpenLDAP --enable-ldbm_type
-
-	# Check whether --enable-ldbm_type or --disable-ldbm_type was given.
-if test "${enable_ldbm_type+set}" = set; then
-  enableval="$enable_ldbm_type"
-
-	ol_arg=invalid
-	for ol_val in auto btree hash ; do
-		if test "$enableval" = "$ol_val" ; then
-			ol_arg="$ol_val"
-		fi
-	done
-	if test "$ol_arg" = "invalid" ; then
-		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-ldbm_type" >&5
-echo "$as_me: error: bad value $enableval for --enable-ldbm_type" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-	ol_enable_ldbm_type="$ol_arg"
-
-else
-  	ol_enable_ldbm_type=auto
-fi;
-# end --enable-ldbm_type
-
 # OpenLDAP --enable-meta
 
 	# Check whether --enable-meta or --disable-meta was given.
@@ -3167,15 +3096,17 @@
 
 Overlays="accesslog \
 	auditlog \
-	denyop \
+	constraint \
+	dds \
 	dyngroup \
 	dynlist \
-	lastmod \
+	memberof \
 	ppolicy \
 	proxycache \
 	refint \
 	retcode \
 	rwm \
+	seqmod \
 	syncprov \
 	translucent \
 	unique \
@@ -3256,11 +3187,11 @@
 fi;
 # end --enable-auditlog
 
-# OpenLDAP --enable-denyop
+# OpenLDAP --enable-constraint
 
-	# Check whether --enable-denyop or --disable-denyop was given.
-if test "${enable_denyop+set}" = set; then
-  enableval="$enable_denyop"
+	# Check whether --enable-constraint or --disable-constraint was given.
+if test "${enable_constraint+set}" = set; then
+  enableval="$enable_constraint"
 
 	ol_arg=invalid
 	for ol_val in no yes mod ; do
@@ -3269,17 +3200,41 @@
 		fi
 	done
 	if test "$ol_arg" = "invalid" ; then
-		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-denyop" >&5
-echo "$as_me: error: bad value $enableval for --enable-denyop" >&2;}
+		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-constraint" >&5
+echo "$as_me: error: bad value $enableval for --enable-constraint" >&2;}
    { (exit 1); exit 1; }; }
 	fi
-	ol_enable_denyop="$ol_arg"
+	ol_enable_constraint="$ol_arg"
 
 else
-  	ol_enable_denyop=${ol_enable_overlays:-no}
+  	ol_enable_constraint=${ol_enable_overlays:-no}
 fi;
-# end --enable-denyop
+# end --enable-constraint
 
+# OpenLDAP --enable-dds
+
+	# Check whether --enable-dds or --disable-dds was given.
+if test "${enable_dds+set}" = set; then
+  enableval="$enable_dds"
+
+	ol_arg=invalid
+	for ol_val in no yes mod ; do
+		if test "$enableval" = "$ol_val" ; then
+			ol_arg="$ol_val"
+		fi
+	done
+	if test "$ol_arg" = "invalid" ; then
+		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-dds" >&5
+echo "$as_me: error: bad value $enableval for --enable-dds" >&2;}
+   { (exit 1); exit 1; }; }
+	fi
+	ol_enable_dds="$ol_arg"
+
+else
+  	ol_enable_dds=${ol_enable_overlays:-no}
+fi;
+# end --enable-dds
+
 # OpenLDAP --enable-dyngroup
 
 	# Check whether --enable-dyngroup or --disable-dyngroup was given.
@@ -3328,11 +3283,11 @@
 fi;
 # end --enable-dynlist
 
-# OpenLDAP --enable-lastmod
+# OpenLDAP --enable-memberof
 
-	# Check whether --enable-lastmod or --disable-lastmod was given.
-if test "${enable_lastmod+set}" = set; then
-  enableval="$enable_lastmod"
+	# Check whether --enable-memberof or --disable-memberof was given.
+if test "${enable_memberof+set}" = set; then
+  enableval="$enable_memberof"
 
 	ol_arg=invalid
 	for ol_val in no yes mod ; do
@@ -3341,16 +3296,16 @@
 		fi
 	done
 	if test "$ol_arg" = "invalid" ; then
-		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-lastmod" >&5
-echo "$as_me: error: bad value $enableval for --enable-lastmod" >&2;}
+		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-memberof" >&5
+echo "$as_me: error: bad value $enableval for --enable-memberof" >&2;}
    { (exit 1); exit 1; }; }
 	fi
-	ol_enable_lastmod="$ol_arg"
+	ol_enable_memberof="$ol_arg"
 
 else
-  	ol_enable_lastmod=${ol_enable_overlays:-no}
+  	ol_enable_memberof=${ol_enable_overlays:-no}
 fi;
-# end --enable-lastmod
+# end --enable-memberof
 
 # OpenLDAP --enable-ppolicy
 
@@ -3472,6 +3427,30 @@
 fi;
 # end --enable-rwm
 
+# OpenLDAP --enable-seqmod
+
+	# Check whether --enable-seqmod or --disable-seqmod was given.
+if test "${enable_seqmod+set}" = set; then
+  enableval="$enable_seqmod"
+
+	ol_arg=invalid
+	for ol_val in no yes mod ; do
+		if test "$enableval" = "$ol_val" ; then
+			ol_arg="$ol_val"
+		fi
+	done
+	if test "$ol_arg" = "invalid" ; then
+		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-seqmod" >&5
+echo "$as_me: error: bad value $enableval for --enable-seqmod" >&2;}
+   { (exit 1); exit 1; }; }
+	fi
+	ol_enable_seqmod="$ol_arg"
+
+else
+  	ol_enable_seqmod=${ol_enable_overlays:-yes}
+fi;
+# end --enable-seqmod
+
 # OpenLDAP --enable-syncprov
 
 	# Check whether --enable-syncprov or --disable-syncprov was given.
@@ -3569,35 +3548,6 @@
 # end --enable-valsort
 
 
-# Check whether --enable-xxslurpdoptions or --disable-xxslurpdoptions was given.
-if test "${enable_xxslurpdoptions+set}" = set; then
-  enableval="$enable_xxslurpdoptions"
-
-fi;
-# OpenLDAP --enable-slurpd
-
-	# Check whether --enable-slurpd or --disable-slurpd was given.
-if test "${enable_slurpd+set}" = set; then
-  enableval="$enable_slurpd"
-
-	ol_arg=invalid
-	for ol_val in auto yes no ; do
-		if test "$enableval" = "$ol_val" ; then
-			ol_arg="$ol_val"
-		fi
-	done
-	if test "$ol_arg" = "invalid" ; then
-		{ { echo "$as_me:$LINENO: error: bad value $enableval for --enable-slurpd" >&5
-echo "$as_me: error: bad value $enableval for --enable-slurpd" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-	ol_enable_slurpd="$ol_arg"
-
-else
-  	ol_enable_slurpd=auto
-fi;
-# end --enable-slurpd
-
 # Check whether --enable-xxliboptions or --disable-xxliboptions was given.
 if test "${enable_xxliboptions+set}" = set; then
   enableval="$enable_xxliboptions"
@@ -3675,10 +3625,6 @@
 		{ echo "$as_me:$LINENO: WARNING: slapd disabled, ignoring --enable-modules argument" >&5
 echo "$as_me: WARNING: slapd disabled, ignoring --enable-modules argument" >&2;}
 	fi
-	if test $ol_enable_multimaster = yes ; then
-		{ echo "$as_me:$LINENO: WARNING: slapd disabled, ignoring --enable-multimaster argument" >&5
-echo "$as_me: WARNING: slapd disabled, ignoring --enable-multimaster argument" >&2;}
-	fi
 	if test $ol_enable_wrappers = yes ; then
 		{ echo "$as_me:$LINENO: WARNING: slapd disabled, ignoring --enable-wrappers argument" >&5
 echo "$as_me: WARNING: slapd disabled, ignoring --enable-wrappers argument" >&2;}
@@ -3687,23 +3633,14 @@
 		{ echo "$as_me:$LINENO: WARNING: slapd disabled, ignoring --enable-rlookups argument" >&5
 echo "$as_me: WARNING: slapd disabled, ignoring --enable-rlookups argument" >&2;}
 	fi
-	if test $ol_enable_aci = yes ; then
+	if test $ol_enable_dynacl = yes ; then
+		{ echo "$as_me:$LINENO: WARNING: slapd disabled, ignoring --enable-dynacl argument" >&5
+echo "$as_me: WARNING: slapd disabled, ignoring --enable-dynacl argument" >&2;}
+	fi
+	if test $ol_enable_aci != no ; then
 		{ echo "$as_me:$LINENO: WARNING: slapd disabled, ignoring --enable-aci argument" >&5
 echo "$as_me: WARNING: slapd disabled, ignoring --enable-aci argument" >&2;}
 	fi
-	if test $ol_enable_ldbm_api != auto ; then
-		{ echo "$as_me:$LINENO: WARNING: slapd disabled, ignoring --enable-ldbm-api argument" >&5
-echo "$as_me: WARNING: slapd disabled, ignoring --enable-ldbm-api argument" >&2;}
-	fi
-	if test $ol_enable_ldbm_type != auto ; then
-		{ echo "$as_me:$LINENO: WARNING: slapd disabled, ignoring --enable-ldbm-type argument" >&5
-echo "$as_me: WARNING: slapd disabled, ignoring --enable-ldbm-type argument" >&2;}
-	fi
-	if test $ol_enable_slurpd = yes ; then
-		{ { echo "$as_me:$LINENO: error: slurpd requires slapd" >&5
-echo "$as_me: error: slurpd requires slapd" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
 	if test $ol_enable_rewrite = yes ; then
 		{ echo "$as_me:$LINENO: WARNING: slapd disabled, ignoring --enable-rewrite argument" >&5
 echo "$as_me: WARNING: slapd disabled, ignoring --enable-rewrite argument" >&2;}
@@ -3727,91 +3664,36 @@
 	ol_enable_backends=
 	ol_enable_overlays=
 	ol_enable_modules=no
-	ol_enable_multimaster=no
 	ol_enable_rlookups=no
+	ol_enable_dynacl=no
 	ol_enable_aci=no
 	ol_enable_wrappers=no
 
-	ol_enable_ldbm_api=no
-	ol_enable_ldbm_type=no
-
-	ol_enable_slurpd=no
-
 	ol_enable_rewrite=no
 
-elif test $ol_enable_ldbm = no ; then
+elif test $ol_enable_modules != yes &&
+	test $ol_enable_bdb = no &&
+	test $ol_enable_dnssrv = no &&
+	test $ol_enable_hdb = no &&
+	test $ol_enable_ldap = no &&
+	test $ol_enable_meta = no &&
+	test $ol_enable_monitor = no &&
+	test $ol_enable_null = no &&
+	test $ol_enable_passwd = no &&
+	test $ol_enable_perl = no &&
+	test $ol_enable_relay = no &&
+	test $ol_enable_shell = no &&
+	test $ol_enable_sql = no ; then
 
-	if test $ol_enable_ldbm_api != auto ; then
-		{ echo "$as_me:$LINENO: WARNING: LDBM disabled, ignoring --enable-ldbm-api argument" >&5
-echo "$as_me: WARNING: LDBM disabled, ignoring --enable-ldbm-api argument" >&2;}
-	fi
-
-	if test $ol_enable_ldbm_type != auto ; then
-		{ echo "$as_me:$LINENO: WARNING: LDBM disabled, ignoring --enable-ldbm-type argument" >&5
-echo "$as_me: WARNING: LDBM disabled, ignoring --enable-ldbm-type argument" >&2;}
-	fi
-
-	if test $ol_enable_modules != yes &&
-	   test $ol_enable_bdb = no &&
-	   test $ol_enable_dnssrv = no &&
-	   test $ol_enable_hdb = no &&
-	   test $ol_enable_ldap = no &&
-	   test $ol_enable_meta = no &&
-	   test $ol_enable_monitor = no &&
-	   test $ol_enable_null = no &&
-	   test $ol_enable_passwd = no &&
-	   test $ol_enable_perl = no &&
-	   test $ol_enable_relay = no &&
-	   test $ol_enable_shell = no &&
-	   test $ol_enable_sql = no ; then
-
-		if test $ol_enable_slapd = yes ; then
-			{ { echo "$as_me:$LINENO: error: slapd requires a backend" >&5
+	if test $ol_enable_slapd = yes ; then
+		{ { echo "$as_me:$LINENO: error: slapd requires a backend" >&5
 echo "$as_me: error: slapd requires a backend" >&2;}
    { (exit 1); exit 1; }; }
-		else
-			{ echo "$as_me:$LINENO: WARNING: skipping slapd, no backend specified" >&5
+	else
+		{ echo "$as_me:$LINENO: WARNING: skipping slapd, no backend specified" >&5
 echo "$as_me: WARNING: skipping slapd, no backend specified" >&2;}
-			ol_enable_slapd=no
-		fi
+		ol_enable_slapd=no
 	fi
-
-	ol_enable_ldbm_api=no
-	ol_enable_ldbm_type=no
-
-	if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
-		ol_enable_ldbm_api=berkeley
-	fi
-
-else
-		if test $ol_enable_ldbm_api = gdbm &&
-	   test $ol_enable_ldbm_type = btree ; then
-		{ { echo "$as_me:$LINENO: error: GDBM only supports LDBM type hash" >&5
-echo "$as_me: error: GDBM only supports LDBM type hash" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-	if test $ol_enable_ldbm_api = mdbm &&
-	   test $ol_enable_ldbm_type = btree ; then
-		{ { echo "$as_me:$LINENO: error: MDBM only supports LDBM type hash" >&5
-echo "$as_me: error: MDBM only supports LDBM type hash" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-	if test $ol_enable_ldbm_api = ndbm &&
-	   test $ol_enable_ldbm_type = btree ; then
-		{ { echo "$as_me:$LINENO: error: NDBM only supports LDBM type hash" >&5
-echo "$as_me: error: NDBM only supports LDBM type hash" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-
-	if test $ol_enable_bdb/$ol_enable_hdb != no/no ; then
-		if test $ol_enable_ldbm_api = auto ; then
-			ol_enable_ldbm_api=berkeley
-		elif test $ol_enable_ldbm_api != berkeley ; then
-			{ { echo "$as_me:$LINENO: error: LDBM API not compatible with BDB/HDB" >&5
-echo "$as_me: error: LDBM API not compatible with BDB/HDB" >&2;}
-   { (exit 1); exit 1; }; }
-		fi
-	fi
 fi
 
 if test $ol_enable_meta/$ol_enable_ldap = yes/no ; then
@@ -3820,14 +3702,6 @@
    { (exit 1); exit 1; }; }
 fi
 
-if test $ol_enable_slurpd = yes ; then
-		if test $ol_with_threads = no ; then
-		{ { echo "$as_me:$LINENO: error: slurpd requires threads" >&5
-echo "$as_me: error: slurpd requires threads" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-fi
-
 if test $ol_enable_lmpasswd = yes ; then
 	if test $ol_with_tls = no ; then
 		{ { echo "$as_me:$LINENO: error: LAN Manager passwords require OpenSSL" >&5
@@ -3836,25 +3710,6 @@
 	fi
 fi
 
-if test $ol_enable_kbind = yes ; then
-	if test $ol_with_kerberos = no ; then
-		{ { echo "$as_me:$LINENO: error: options require --with-kerberos" >&5
-echo "$as_me: error: options require --with-kerberos" >&2;}
-   { (exit 1); exit 1; }; }
-	elif test $ol_with_kerberos = auto ; then
-		ol_with_kerberos=yes
-	fi
-
-elif test $ol_enable_kbind = no ; then
-	if test $ol_with_kerberos = auto ; then
-		ol_with_kerberos=no
-	elif test $ol_with_kerberos != no ; then
-		{ echo "$as_me:$LINENO: WARNING: Kerberos detection enabled unnecessarily" >&5
-echo "$as_me: WARNING: Kerberos detection enabled unnecessarily" >&2;};
-		ol_with_kerberos=no
-	fi
-fi
-
 if test $ol_enable_spasswd = yes ; then
 	if test $ol_with_cyrus_sasl = no ; then
 		{ { echo "$as_me:$LINENO: error: options require --with-cyrus-sasl" >&5
@@ -3868,15 +3723,13 @@
 echo "${ECHO_T}done" >&6
 
 LDAP_LIBS=
-LDBM_LIBS=
+BDB_LIBS=
 LTHREAD_LIBS=
 LUTIL_LIBS=
 
 SLAPD_LIBS=
-SLURPD_LIBS=
 
 BUILD_SLAPD=no
-BUILD_SLURPD=no
 
 BUILD_THREAD=no
 
@@ -3887,7 +3740,6 @@
 BUILD_DNSSRV=no
 BUILD_HDB=no
 BUILD_LDAP=no
-BUILD_LDBM=no
 BUILD_META=no
 BUILD_MONITOR=no
 BUILD_NULL=no
@@ -3899,15 +3751,19 @@
 
 BUILD_ACCESSLOG=no
 BUILD_AUDITLOG=no
+BUILD_CONSTRAINT=no
+BUILD_DDS=no
 BUILD_DENYOP=no
 BUILD_DYNGROUP=no
 BUILD_DYNLIST=no
 BUILD_LASTMOD=no
+BUILD_MEMBEROF=no
 BUILD_PPOLICY=no
 BUILD_PROXYCACHE=no
 BUILD_REFINT=no
 BUILD_RETCODE=no
 BUILD_RWM=no
+BUILD_SEQMOD=no
 BUILD_SYNCPROV=no
 BUILD_TRANSLUCENT=no
 BUILD_UNIQUE=no
@@ -3939,6 +3795,7 @@
 LIBSLAPI=
 LIBSLAPITOOLS=
 AUTH_LIBS=
+ICU_LIBS=
 
 SLAPD_SLP_LIBS=
 SLAPD_GMP_LIBS=
@@ -5737,7 +5594,7 @@
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 5740 "configure"' > conftest.$ac_ext
+  echo '#line 5597 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -7717,11 +7574,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7720: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7577: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7724: \$? = $ac_status" >&5
+   echo "$as_me:7581: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7979,11 +7836,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7982: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7839: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7986: \$? = $ac_status" >&5
+   echo "$as_me:7843: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8041,11 +7898,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8044: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7901: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8048: \$? = $ac_status" >&5
+   echo "$as_me:7905: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -10289,7 +10146,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10292 "configure"
+#line 10149 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10387,7 +10244,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10390 "configure"
+#line 10247 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12873,6 +12730,7 @@
 fi
 echo "$as_me:$LINENO: result: $ol_cv_mkdep" >&5
 echo "${ECHO_T}$ol_cv_mkdep" >&6
+		test "$ol_cv_mkdep" = no && OL_MKDEP=":"
 	else
 		cc_cv_mkdep=yes
 		OL_MKDEP_FLAGS="${MKDEP_FLAGS}"
@@ -13965,6 +13823,9 @@
 
 
 
+
+
+
 for ac_header in \
 	arpa/inet.h		\
 	arpa/nameser.h	\
@@ -13995,9 +13856,11 @@
 	sysexits.h		\
 	sys/file.h		\
 	sys/filio.h		\
+	sys/fstyp.h		\
 	sys/errno.h		\
 	sys/ioctl.h		\
 	sys/param.h		\
+	sys/privgrp.h	\
 	sys/resource.h	\
 	sys/select.h	\
 	sys/socket.h	\
@@ -14006,6 +13869,7 @@
 	sys/time.h		\
 	sys/types.h		\
 	sys/uio.h		\
+	sys/vmount.h	\
 	syslog.h		\
 	termios.h		\
 	unistd.h		\
@@ -15739,8 +15603,10 @@
 fi
 done
 
+if test $ac_cv_func_poll = yes; then
 
-for ac_header in poll.h
+
+for ac_header in poll.h sys/poll.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -15889,6 +15755,7 @@
 
 done
 
+fi
 
 
 for ac_header in sys/epoll.h
@@ -16041,9 +15908,9 @@
 done
 
 if test "${ac_cv_header_sys_epoll_h}" = yes; then
-echo "$as_me:$LINENO: checking for epoll system call" >&5
+	echo "$as_me:$LINENO: checking for epoll system call" >&5
 echo $ECHO_N "checking for epoll system call... $ECHO_C" >&6
-if test "$cross_compiling" = yes; then
+	if test "$cross_compiling" = yes; then
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 else
@@ -16053,7 +15920,7 @@
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-int main(int argc, char *argv)
+int main(int argc, char **argv)
 {
 	int epfd = epoll_create(256);
 	exit (epfd == -1 ? 1 : 0);
@@ -16090,6 +15957,208 @@
 fi
 fi
 
+
+for ac_header in sys/devpoll.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to <http://www.openldap.org/its/> ##
+## --------------------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+if test "${ac_cv_header_sys_devpoll_h}" = yes \
+		-a "${ac_cv_header_poll_h}" = yes ; \
+then
+	echo "$as_me:$LINENO: checking for /dev/poll" >&5
+echo $ECHO_N "checking for /dev/poll... $ECHO_C" >&6
+	if test "$cross_compiling" = yes; then
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int main(int argc, char **argv)
+{
+	int devpollfd = open("/dev/poll", /* O_RDWR */ 2);
+	exit (devpollfd == -1 ? 1 : 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DEVPOLL 1
+_ACEOF
+
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+
 # strerror checks
 echo "$as_me:$LINENO: checking declaration of sys_errlist" >&5
 echo $ECHO_N "checking declaration of sys_errlist... $ECHO_C" >&6
@@ -16107,7 +16176,7 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include <errno.h>
-#ifdef WINNT
+#ifdef _WIN32
 #include <stdlib.h>
 #endif
 int
@@ -16472,7 +16541,7 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include <errno.h>
-#ifdef WINNT
+#ifdef _WIN32
 #include <stdlib.h>
 #endif
 int
@@ -16597,25 +16666,23 @@
 for ac_header in regex.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo "$as_me:$LINENO: checking for $ac_header" >&5
 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+
 #include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
@@ -16640,100 +16707,17 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_header_compiler=yes
+  eval "$as_ac_Header=yes"
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_header_compiler=no
+eval "$as_ac_Header=no"
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
 fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## --------------------------------------------- ##
-## Report this to <http://www.openldap.org/its/> ##
-## --------------------------------------------- ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
 echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
 if test `eval echo '${'$as_ac_Header'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
@@ -16743,6 +16727,7 @@
 
 done
 
+
 if test "$ac_cv_header_regex_h" != yes ; then
 	{ { echo "$as_me:$LINENO: error: POSIX regex.h required." >&5
 echo "$as_me: error: POSIX regex.h required." >&2;}
@@ -17248,6 +17233,302 @@
 fi
 
 if test $have_uuid = no ; then
+
+for ac_header in uuid/uuid.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to <http://www.openldap.org/its/> ##
+## --------------------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+	if test $ac_cv_header_uuid_uuid_h = yes ; then
+		save_LIBS="$LIBS"
+		echo "$as_me:$LINENO: checking for library containing uuid_generate" >&5
+echo $ECHO_N "checking for library containing uuid_generate... $ECHO_C" >&6
+if test "${ac_cv_search_uuid_generate+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_uuid_generate=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char uuid_generate ();
+int
+main ()
+{
+uuid_generate ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_uuid_generate="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_uuid_generate" = no; then
+  for ac_lib in uuid; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char uuid_generate ();
+int
+main ()
+{
+uuid_generate ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_uuid_generate="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_uuid_generate" >&5
+echo "${ECHO_T}$ac_cv_search_uuid_generate" >&6
+if test "$ac_cv_search_uuid_generate" != no; then
+  test "$ac_cv_search_uuid_generate" = "none required" || LIBS="$ac_cv_search_uuid_generate $LIBS"
+  have_uuid=yes
+else
+  :
+fi
+
+		LIBS="$save_LIBS"
+
+		if test have_uuid = yes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_UUID_GENERATE 1
+_ACEOF
+
+
+			test "$ac_cv_search_uuid_generate" = "none required" || \
+				SLAPD_LIBS="$SLAPD_LIBS $ac_cv_search_uuid_generate"
+		fi
+	fi
+fi
+
+if test $have_uuid = no ; then
 	echo "$as_me:$LINENO: checking to see if -lrpcrt4 is needed for win32 UUID support" >&5
 echo $ECHO_N "checking to see if -lrpcrt4 is needed for win32 UUID support... $ECHO_C" >&6
 	save_LIBS="$LIBS"
@@ -18155,166 +18436,15 @@
 	fi
 fi
 
-ol_link_kbind=no
-ol_link_krb5=no
-ol_link_krb4=no
 
-case $ol_with_kerberos in yes | auto | k5 | k5only | k425)
-
-
-for ac_header in krb5.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+if test $ol_with_tls = yes ; then
+	ol_with_tls=auto
 fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
+ol_link_tls=no
+if test $ol_with_tls = openssl || test $ol_with_tls = auto ; then
 
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## --------------------------------------------- ##
-## Report this to <http://www.openldap.org/its/> ##
-## --------------------------------------------- ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-	if test $ac_cv_header_krb5_h = yes ; then
-
-for ac_header in heim_err.h
+for ac_header in openssl/ssl.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -18463,20 +18593,15 @@
 
 done
 
-		if test $ac_cv_header_heim_err_h = yes ; then
-			krb5_impl=heimdal
-		else
-			krb5_impl=mit
-		fi
 
-		if test $krb5_impl = mit; then
-			echo "$as_me:$LINENO: checking for main in -lk5crypto" >&5
-echo $ECHO_N "checking for main in -lk5crypto... $ECHO_C" >&6
-if test "${ac_cv_lib_k5crypto_main+set}" = set; then
+	if test $ac_cv_header_openssl_ssl_h = yes ; then
+		echo "$as_me:$LINENO: checking for SSL_library_init in -lssl" >&5
+echo $ECHO_N "checking for SSL_library_init in -lssl... $ECHO_C" >&6
+if test "${ac_cv_lib_ssl_SSL_library_init+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lk5crypto  $LIBS"
+LIBS="-lssl -lcrypto $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -18484,11 +18609,17 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char SSL_library_init ();
 int
 main ()
 {
-main ();
+SSL_library_init ();
   ;
   return 0;
 }
@@ -18515,33 +18646,35 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_k5crypto_main=yes
+  ac_cv_lib_ssl_SSL_library_init=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_k5crypto_main=no
+ac_cv_lib_ssl_SSL_library_init=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_k5crypto_main" >&5
-echo "${ECHO_T}$ac_cv_lib_k5crypto_main" >&6
-if test $ac_cv_lib_k5crypto_main = yes; then
-  krb5crypto=k5crypto
+echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_library_init" >&5
+echo "${ECHO_T}$ac_cv_lib_ssl_SSL_library_init" >&6
+if test $ac_cv_lib_ssl_SSL_library_init = yes; then
+  have_openssl=yes
+			need_rsaref=no
 else
-  krb5crypto=crypto
+  have_openssl=no
 fi
 
 
-			echo "$as_me:$LINENO: checking for main in -lkrb5" >&5
-echo $ECHO_N "checking for main in -lkrb5... $ECHO_C" >&6
-if test "${ac_cv_lib_krb5_main+set}" = set; then
+		if test $have_openssl = no ; then
+			echo "$as_me:$LINENO: checking for ssl3_accept in -lssl" >&5
+echo $ECHO_N "checking for ssl3_accept in -lssl... $ECHO_C" >&6
+if test "${ac_cv_lib_ssl_ssl3_accept+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lkrb5 -l$krb5crypto -lcom_err $LIBS"
+LIBS="-lssl -lcrypto -lRSAglue -lrsaref $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -18549,11 +18682,17 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char ssl3_accept ();
 int
 main ()
 {
-main ();
+ssl3_accept ();
   ;
   return 0;
 }
@@ -18580,596 +18719,100 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_krb5_main=yes
+  ac_cv_lib_ssl_ssl3_accept=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_krb5_main=no
+ac_cv_lib_ssl_ssl3_accept=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_krb5_main" >&5
-echo "${ECHO_T}$ac_cv_lib_krb5_main" >&6
-if test $ac_cv_lib_krb5_main = yes; then
-  have_krb5=yes
-				KRB5_LIBS="-lkrb5 -l$krb5crypto -lcom_err"
+echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_ssl3_accept" >&5
+echo "${ECHO_T}$ac_cv_lib_ssl_ssl3_accept" >&6
+if test $ac_cv_lib_ssl_ssl3_accept = yes; then
+  have_openssl=yes
+				need_rsaref=yes
 else
-  have_krb5=no
+  have_openssl=no
 fi
 
+		fi
 
-		elif test $krb5_impl = heimdal; then
-			echo "$as_me:$LINENO: checking for main in -ldes" >&5
-echo $ECHO_N "checking for main in -ldes... $ECHO_C" >&6
-if test "${ac_cv_lib_des_main+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldes  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
+		if test $have_openssl = yes ; then
+			ol_with_tls=openssl
+			ol_link_tls=yes
 
 
-int
-main ()
-{
-main ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_des_main=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_des_main=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_des_main" >&5
-echo "${ECHO_T}$ac_cv_lib_des_main" >&6
-if test $ac_cv_lib_des_main = yes; then
-  krb5crypto=des
-else
-  krb5crypto=crypto
-fi
-
-
-			echo "$as_me:$LINENO: checking for main in -lkrb5" >&5
-echo $ECHO_N "checking for main in -lkrb5... $ECHO_C" >&6
-if test "${ac_cv_lib_krb5_main+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lkrb5 -l$krb5crypto -lasn1 -lroken -lcom_err $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-
-int
-main ()
-{
-main ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_krb5_main=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_krb5_main=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_krb5_main" >&5
-echo "${ECHO_T}$ac_cv_lib_krb5_main" >&6
-if test $ac_cv_lib_krb5_main = yes; then
-  have_krb5=yes
-				KRB5_LIBS="-lkrb5 -l$krb5crypto -lasn1 -lroken -lcom_err"
-else
-  have_krb5=no
-fi
-
-
-
 cat >>confdefs.h <<\_ACEOF
-#define HAVE_HEIMDAL_KERBEROS 1
+#define HAVE_OPENSSL 1
 _ACEOF
 
 
-		else
-			have_krb5=no
-			{ echo "$as_me:$LINENO: WARNING: Unrecognized Kerberos5 Implementation" >&5
-echo "$as_me: WARNING: Unrecognized Kerberos5 Implementation" >&2;}
-		fi
+			if test $need_rsaref = yes; then
 
-		if test $have_krb5 = yes ; then
-			ol_link_krb5=yes
-
-
 cat >>confdefs.h <<\_ACEOF
-#define HAVE_KRB5 1
+#define HAVE_RSAREF 1
 _ACEOF
 
 
-			if test $ol_with_kerberos = k5only ; then
-				ol_with_kerberos=found
+				TLS_LIBS="-lssl -lcrypto -lRSAglue -lrsaref"
+			else
+				TLS_LIBS="-lssl -lcrypto"
 			fi
 
-		elif test $ol_with_kerberos != auto ; then
-			{ { echo "$as_me:$LINENO: error: Required Kerberos 5 support not available" >&5
-echo "$as_me: error: Required Kerberos 5 support not available" >&2;}
-   { (exit 1); exit 1; }; }
-		fi
-
-	fi
-	;;
-esac
-
-if test $ol_link_krb5 = yes &&
-   { test $ol_with_kerberos = yes ||
-     test $ol_with_kerberos = auto ||
-     test $ol_with_kerberos = k425; }; then
-
-
-
-for ac_header in kerberosIV/krb.h kerberosIV/des.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+			echo "$as_me:$LINENO: checking OpenSSL library version (CRL checking capability)" >&5
+echo $ECHO_N "checking OpenSSL library version (CRL checking capability)... $ECHO_C" >&6
+if test "${ol_cv_ssl_crl_compat+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
+		cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
+#ifdef HAVE_OPENSSL_SSL_H
+#include <openssl/ssl.h>
+#endif
 
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## --------------------------------------------- ##
-## Report this to <http://www.openldap.org/its/> ##
-## --------------------------------------------- ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+/* Require 0.9.7d+ */
+#if OPENSSL_VERSION_NUMBER >= 0x0090704fL
+	char *__ssl_compat = "0.9.7d";
+#endif
 
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
-
-fi
-
-done
-
-
-	if test $ac_cv_header_kerberosIV_krb_h = yes ; then
-		if test $krb5_impl = mit; then
-			echo "$as_me:$LINENO: checking for main in -lkrb4" >&5
-echo $ECHO_N "checking for main in -lkrb4... $ECHO_C" >&6
-if test "${ac_cv_lib_krb4_main+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__ssl_compat" >/dev/null 2>&1; then
+  ol_cv_ssl_crl_compat=yes
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lkrb4 -ldes425 -lkrb5 -l$krb5crypto -lcom_err $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-
-int
-main ()
-{
-main ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_krb4_main=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_krb4_main=no
+  ol_cv_ssl_crl_compat=no
 fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_krb4_main" >&5
-echo "${ECHO_T}$ac_cv_lib_krb4_main" >&6
-if test $ac_cv_lib_krb4_main = yes; then
-  have_k425=yes
-				KRB4_LIBS="-lkrb4 -ldes425"
-else
-  have_k425=no
-fi
+rm -f conftest*
 
-
-		elif test $krb5_impl = heimdal; then
-			echo "$as_me:$LINENO: checking for main in -lkrb4" >&5
-echo $ECHO_N "checking for main in -lkrb4... $ECHO_C" >&6
-if test "${ac_cv_lib_krb4_main+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lkrb4 -lkrb5 -l$krb5crypto -lasn1 -lroken -lcom_err $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-
-int
-main ()
-{
-main ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_krb4_main=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_krb4_main=no
 fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_krb4_main" >&5
-echo "${ECHO_T}$ac_cv_lib_krb4_main" >&6
-if test $ac_cv_lib_krb4_main = yes; then
-  have_k425=yes
-				KRB4_LIBS="-lkrb4"
-else
-  have_k425=no
-fi
+echo "$as_me:$LINENO: result: $ol_cv_ssl_crl_compat" >&5
+echo "${ECHO_T}$ol_cv_ssl_crl_compat" >&6
 
+			if test $ol_cv_ssl_crl_compat = yes ; then
 
-		else
-			have_425=no
-			{ echo "$as_me:$LINENO: WARNING: Unrecongized Kerberos V Implementation" >&5
-echo "$as_me: WARNING: Unrecongized Kerberos V Implementation" >&2;}
-		fi
-
-		if test $have_k425 = yes ; then
-			ol_with_kerberos=found
-			ol_link_krb4=yes
-
-
 cat >>confdefs.h <<\_ACEOF
-#define HAVE_KRB425 1
+#define HAVE_OPENSSL_CRL 1
 _ACEOF
 
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_KRB4 1
-_ACEOF
-
-
-			echo "$as_me:$LINENO: checking for des_debug in Kerberos libraries" >&5
-echo $ECHO_N "checking for des_debug in Kerberos libraries... $ECHO_C" >&6
-if test "${ol_cv_var_des_debug+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-								save_LIBS="$LIBS"
-				LIBS="$KRB4_LIBS $KRB5_LIBS $LIBS"
-				cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <kerberosIV/krb.h>
-#include <kerberosIV/des.h>
-extern int des_debug;
-
-int
-main ()
-{
-
-des_debug = 1;
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_var_des_debug=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_var_des_debug=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-								LIBS="$save_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_var_des_debug" >&5
-echo "${ECHO_T}$ol_cv_var_des_debug" >&6
-
-			if test $ol_cv_var_des_debug = yes ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_DES_DEBUG 1
-_ACEOF
-
 			fi
-
-			LIBS="$save_LIBS"
 		fi
 	fi
 fi
 
-if test $ol_link_krb5 = yes ; then
-	ol_with_kerberos=found
-fi
+if test $ol_link_tls = no ; then
+	if test $ol_with_tls = gnutls || test $ol_with_tls = auto ; then
 
-case $ol_with_kerberos in yes | auto | k4 | kth)
-
-
-
-
-for ac_header in krb.h des.h krb-archaeology.h
+for ac_header in gnutls/gnutls.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -19319,14 +18962,14 @@
 done
 
 
-	if test $ac_cv_header_krb_h = yes ; then
-		echo "$as_me:$LINENO: checking for main in -lkrb" >&5
-echo $ECHO_N "checking for main in -lkrb... $ECHO_C" >&6
-if test "${ac_cv_lib_krb_main+set}" = set; then
+		if test $ac_cv_header_gnutls_gnutls_h = yes ; then
+			echo "$as_me:$LINENO: checking for gnutls_init in -lgnutls" >&5
+echo $ECHO_N "checking for gnutls_init in -lgnutls... $ECHO_C" >&6
+if test "${ac_cv_lib_gnutls_gnutls_init+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lkrb -ldes $LIBS"
+LIBS="-lgnutls  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -19334,283 +18977,17 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-
-int
-main ()
-{
-main ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_krb_main=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_krb_main=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_krb_main" >&5
-echo "${ECHO_T}$ac_cv_lib_krb_main" >&6
-if test $ac_cv_lib_krb_main = yes; then
-  have_k4=yes
-else
-  have_k4=no
-fi
-
-
-		if test $have_k4 = yes ; then
-			ol_with_kerberos=found
-			ol_link_krb4=yes
-
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_KRB4 1
-_ACEOF
-
-
-			KRB4_LIBS="-lkrb -ldes"
-
-			if test $ac_cv_header_krb_archaeology_h = yes ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_KTH_KERBEROS 1
-_ACEOF
-
-			fi
-		fi
-	fi
-	;;
-esac
-
-if test $ol_link_krb4 = yes && test $ol_enable_kbind != no ; then
-	ol_link_kbind=yes
-
-elif test $ol_enable_kbind = yes ; then
-	{ { echo "$as_me:$LINENO: error: Kerberos IV detection failed" >&5
-echo "$as_me: error: Kerberos IV detection failed" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-if test $ol_link_krb4 = yes || test $ol_link_krb5 = yes ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_KERBEROS 1
-_ACEOF
-
-
-elif test $ol_with_kerberos != auto && test $ol_with_kerberos != no ; then
-	{ { echo "$as_me:$LINENO: error: Kerberos detection failed" >&5
-echo "$as_me: error: Kerberos detection failed" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-
-ol_link_tls=no
-if test $ol_with_tls != no ; then
-
-for ac_header in openssl/ssl.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## --------------------------------------------- ##
-## Report this to <http://www.openldap.org/its/> ##
-## --------------------------------------------- ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-	if test $ac_cv_header_openssl_ssl_h = yes ; then
-		echo "$as_me:$LINENO: checking for SSL_library_init in -lssl" >&5
-echo $ECHO_N "checking for SSL_library_init in -lssl... $ECHO_C" >&6
-if test "${ac_cv_lib_ssl_SSL_library_init+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl -lcrypto $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
 /* Override any gcc2 internal prototype to avoid an error.  */
 #ifdef __cplusplus
 extern "C"
 #endif
 /* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
-char SSL_library_init ();
+char gnutls_init ();
 int
 main ()
 {
-SSL_library_init ();
+gnutls_init ();
   ;
   return 0;
 }
@@ -19637,174 +19014,40 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_ssl_SSL_library_init=yes
+  ac_cv_lib_gnutls_gnutls_init=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_ssl_SSL_library_init=no
+ac_cv_lib_gnutls_gnutls_init=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_library_init" >&5
-echo "${ECHO_T}$ac_cv_lib_ssl_SSL_library_init" >&6
-if test $ac_cv_lib_ssl_SSL_library_init = yes; then
-  have_openssl=yes
-			need_rsaref=no
+echo "$as_me:$LINENO: result: $ac_cv_lib_gnutls_gnutls_init" >&5
+echo "${ECHO_T}$ac_cv_lib_gnutls_gnutls_init" >&6
+if test $ac_cv_lib_gnutls_gnutls_init = yes; then
+  have_gnutls=yes
 else
-  have_openssl=no
+  have_gnutls=no
 fi
 
 
-		if test $have_openssl = no ; then
-			echo "$as_me:$LINENO: checking for ssl3_accept in -lssl" >&5
-echo $ECHO_N "checking for ssl3_accept in -lssl... $ECHO_C" >&6
-if test "${ac_cv_lib_ssl_ssl3_accept+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl -lcrypto -lRSAglue -lrsaref $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
+			if test $have_gnutls = yes ; then
+				ol_with_tls=gnutls
+				ol_link_tls=yes
 
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char ssl3_accept ();
-int
-main ()
-{
-ssl3_accept ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_ssl_ssl3_accept=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+				TLS_LIBS="-lgnutls"
 
-ac_cv_lib_ssl_ssl3_accept=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_ssl3_accept" >&5
-echo "${ECHO_T}$ac_cv_lib_ssl_ssl3_accept" >&6
-if test $ac_cv_lib_ssl_ssl3_accept = yes; then
-  have_openssl=yes
-				need_rsaref=yes
-else
-  have_openssl=no
-fi
 
-		fi
-
-		if test $have_openssl = yes ; then
-			ol_with_tls=found
-			ol_link_tls=yes
-
-
 cat >>confdefs.h <<\_ACEOF
-#define HAVE_OPENSSL 1
+#define HAVE_GNUTLS 1
 _ACEOF
 
-
-			if test $need_rsaref = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_RSAREF 1
-_ACEOF
-
-
-				TLS_LIBS="-lssl -lcrypto -lRSAglue -lrsaref"
-			else
-				TLS_LIBS="-lssl -lcrypto"
 			fi
 		fi
-		echo "$as_me:$LINENO: checking OpenSSL library version (CRL checking capability)" >&5
-echo $ECHO_N "checking OpenSSL library version (CRL checking capability)... $ECHO_C" >&6
-if test "${ol_cv_ssl_crl_compat+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_OPENSSL_SSL_H
-#include <openssl/ssl.h>
-#else
-#include <ssl.h>
-#endif
-
-/* Require 0.9.7d+ */
-#if OPENSSL_VERSION_NUMBER >= 0x0090704fL
-	char *__ssl_compat = "0.9.7d";
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__ssl_compat" >/dev/null 2>&1; then
-  ol_cv_ssl_crl_compat=yes
-else
-  ol_cv_ssl_crl_compat=no
-fi
-rm -f conftest*
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_ssl_crl_compat" >&5
-echo "${ECHO_T}$ol_cv_ssl_crl_compat" >&6
-
-		if test $ol_cv_ssl_crl_compat = no ; then
-			ol_link_ssl=no
-                else
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_OPENSSL_CRL 1
-_ACEOF
-
-		fi
 	fi
-
-else
-	{ echo "$as_me:$LINENO: WARNING: TLS data protection not supported!" >&5
-echo "$as_me: WARNING: TLS data protection not supported!" >&2;}
 fi
 
 WITH_TLS=no
@@ -19815,17 +19058,18 @@
 _ACEOF
 
 	WITH_TLS=yes
-
 elif test $ol_with_tls = auto ; then
 	{ echo "$as_me:$LINENO: WARNING: Could not locate TLS/SSL package" >&5
 echo "$as_me: WARNING: Could not locate TLS/SSL package" >&2;}
 	{ echo "$as_me:$LINENO: WARNING: TLS data protection not supported!" >&5
 echo "$as_me: WARNING: TLS data protection not supported!" >&2;}
-
 elif test $ol_with_tls != no ; then
 	{ { echo "$as_me:$LINENO: error: Could not locate TLS/SSL package" >&5
 echo "$as_me: error: Could not locate TLS/SSL package" >&2;}
    { (exit 1); exit 1; }; }
+else
+	{ echo "$as_me:$LINENO: WARNING: TLS data protection not supported!" >&5
+echo "$as_me: WARNING: TLS data protection not supported!" >&2;}
 fi
 
 if test $ol_enable_lmpasswd != no; then
@@ -24455,8 +23699,7 @@
 			fi
 
 
-
-for ac_func in pthread_kill pthread_rwlock_destroy
+for ac_func in pthread_kill
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -24558,6 +23801,73 @@
 done
 
 
+									echo "$as_me:$LINENO: checking for pthread_rwlock_destroy with <pthread.h>" >&5
+echo $ECHO_N "checking for pthread_rwlock_destroy with <pthread.h>... $ECHO_C" >&6
+if test "${ol_cv_func_pthread_rwlock_destroy+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+								cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <pthread.h>
+pthread_rwlock_t rwlock;
+
+int
+main ()
+{
+pthread_rwlock_destroy(&rwlock);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ol_cv_func_pthread_rwlock_destroy=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_func_pthread_rwlock_destroy=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_func_pthread_rwlock_destroy" >&5
+echo "${ECHO_T}$ol_cv_func_pthread_rwlock_destroy" >&6
+			if test $ol_cv_func_pthread_rwlock_destroy = yes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PTHREAD_RWLOCK_DESTROY 1
+_ACEOF
+
+			fi
+
 									echo "$as_me:$LINENO: checking for pthread_detach with <pthread.h>" >&5
 echo $ECHO_N "checking for pthread_detach with <pthread.h>... $ECHO_C" >&6
 if test "${ol_cv_func_pthread_detach+set}" = set; then
@@ -25094,7 +24404,7 @@
 #endif
 
 	/* make sure task runs first */
-#if HAVE_THR_YIELD
+#ifdef HAVE_THR_YIELD
 	thr_yield();
 #elif defined( HAVE_SCHED_YIELD )
 	sched_yield();
@@ -27907,14 +27217,12 @@
  	ol_cv_func_gethostbyaddr_r_nargs=0
 fi
 
-ol_link_ldbm=no
+ol_link_bdb=no
 
-case $ol_enable_ldbm_api in auto | berkeley | bcompat)
+if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
+	ol_cv_berkeley_db=no
 
-	if test $ol_enable_ldbm_api = bcompat; then \
-
-
-for ac_header in db_185.h db.h
+for ac_header in db.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -28063,51 +27371,9 @@
 
 done
 
-if test $ac_cv_header_db_185_h = yes || test $ac_cv_header_db_h = yes; then
-	echo "$as_me:$LINENO: checking if Berkeley DB header compatibility" >&5
-echo $ECHO_N "checking if Berkeley DB header compatibility... $ECHO_C" >&6
-if test "${ol_cv_header_db1+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
+if test $ac_cv_header_db_h = yes; then
+	ol_cv_lib_db=no
 
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#if HAVE_DB_185_H
-#	include <db_185.h>
-#else
-#	include <db.h>
-#endif
-
- /* this check could be improved */
-#ifndef DB_VERSION_MAJOR
-#	define DB_VERSION_MAJOR 1
-#endif
-
-#if DB_VERSION_MAJOR == 1
-	__db_version_1
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version_1" >/dev/null 2>&1; then
-  ol_cv_header_db1=yes
-else
-  ol_cv_header_db1=no
-fi
-rm -f conftest*
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_header_db1" >&5
-echo "${ECHO_T}$ol_cv_header_db1" >&6
-
-	if test $ol_cv_header_db1 = yes ; then
-		ol_cv_lib_db=no
-
 echo "$as_me:$LINENO: checking for Berkeley DB major version" >&5
 echo $ECHO_N "checking for Berkeley DB major version... $ECHO_C" >&6
 if test "${ol_cv_bdb_major+set}" = set; then
@@ -28477,15 +27743,15 @@
 echo "${ECHO_T}$ol_cv_bdb_minor" >&6
 
 if test $ol_cv_bdb_major = 4 ; then
-	if test $ol_cv_bdb_minor = 5 ; then
+	if test $ol_cv_bdb_minor = 6 ; then
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb45)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb45)... $ECHO_C" >&6
-if test "${ol_cv_db_db45+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.6)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.6)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_6+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb45
+	ol_DB_LIB=-ldb-4.6
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28566,12 +27832,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db45=yes
+  ol_cv_db_db_4_dot_6=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db45=no
+ol_cv_db_db_4_dot_6=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28579,22 +27845,22 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db45" >&5
-echo "${ECHO_T}$ol_cv_db_db45" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_6" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_6" >&6
 
-	if test $ol_cv_db_db45 = yes ; then
-		ol_cv_lib_db=-ldb45
+	if test $ol_cv_db_db_4_dot_6 = yes ; then
+		ol_cv_lib_db=-ldb-4.6
 	fi
 fi
 
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-45)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-45)... $ECHO_C" >&6
-if test "${ol_cv_db_db_45+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb46)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb46)... $ECHO_C" >&6
+if test "${ol_cv_db_db46+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-45
+	ol_DB_LIB=-ldb46
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28675,12 +27941,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_45=yes
+  ol_cv_db_db46=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_45=no
+ol_cv_db_db46=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28688,22 +27954,22 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_45" >&5
-echo "${ECHO_T}$ol_cv_db_db_45" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db46" >&5
+echo "${ECHO_T}$ol_cv_db_db46" >&6
 
-	if test $ol_cv_db_db_45 = yes ; then
-		ol_cv_lib_db=-ldb-45
+	if test $ol_cv_db_db46 = yes ; then
+		ol_cv_lib_db=-ldb46
 	fi
 fi
 
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.5)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.5)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_5+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-46)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-46)... $ECHO_C" >&6
+if test "${ol_cv_db_db_46+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4.5
+	ol_DB_LIB=-ldb-46
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28784,12 +28050,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_5=yes
+  ol_cv_db_db_46=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_dot_5=no
+ol_cv_db_db_46=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28797,22 +28063,22 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_5" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_5" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_46" >&5
+echo "${ECHO_T}$ol_cv_db_db_46" >&6
 
-	if test $ol_cv_db_db_4_dot_5 = yes ; then
-		ol_cv_lib_db=-ldb-4.5
+	if test $ol_cv_db_db_46 = yes ; then
+		ol_cv_lib_db=-ldb-46
 	fi
 fi
 
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-5)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-5)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_5+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-6)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4-6)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_6+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4-5
+	ol_DB_LIB=-ldb-4-6
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28893,12 +28159,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_5=yes
+  ol_cv_db_db_4_6=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_5=no
+ol_cv_db_db_4_6=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28906,23 +28172,23 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_5" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_5" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_6" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_6" >&6
 
-	if test $ol_cv_db_db_4_5 = yes ; then
-		ol_cv_lib_db=-ldb-4-5
+	if test $ol_cv_db_db_4_6 = yes ; then
+		ol_cv_lib_db=-ldb-4-6
 	fi
 fi
 
-	elif test $ol_cv_bdb_minor = 4 ; then
+	elif test $ol_cv_bdb_minor = 5 ; then
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb44)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb44)... $ECHO_C" >&6
-if test "${ol_cv_db_db44+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.5)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.5)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_5+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb44
+	ol_DB_LIB=-ldb-4.5
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -29003,12 +28269,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db44=yes
+  ol_cv_db_db_4_dot_5=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db44=no
+ol_cv_db_db_4_dot_5=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -29016,3283 +28282,15 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db44" >&5
-echo "${ECHO_T}$ol_cv_db_db44" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_5" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_5" >&6
 
-	if test $ol_cv_db_db44 = yes ; then
-		ol_cv_lib_db=-ldb44
+	if test $ol_cv_db_db_4_dot_5 = yes ; then
+		ol_cv_lib_db=-ldb-4.5
 	fi
 fi
 
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-44)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-44)... $ECHO_C" >&6
-if test "${ol_cv_db_db_44+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-44
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_44=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_44=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_44" >&5
-echo "${ECHO_T}$ol_cv_db_db_44" >&6
-
-	if test $ol_cv_db_db_44 = yes ; then
-		ol_cv_lib_db=-ldb-44
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.4)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_4+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4.4
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_4=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_dot_4=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_4" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_4" >&6
-
-	if test $ol_cv_db_db_4_dot_4 = yes ; then
-		ol_cv_lib_db=-ldb-4.4
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-4)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_4+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4-4
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_4=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_4=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_4" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_4" >&6
-
-	if test $ol_cv_db_db_4_4 = yes ; then
-		ol_cv_lib_db=-ldb-4-4
-	fi
-fi
-
-	elif test $ol_cv_bdb_minor = 3 ; then
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb43)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb43)... $ECHO_C" >&6
-if test "${ol_cv_db_db43+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb43
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db43=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db43=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db43" >&5
-echo "${ECHO_T}$ol_cv_db_db43" >&6
-
-	if test $ol_cv_db_db43 = yes ; then
-		ol_cv_lib_db=-ldb43
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-43)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-43)... $ECHO_C" >&6
-if test "${ol_cv_db_db_43+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-43
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_43=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_43=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_43" >&5
-echo "${ECHO_T}$ol_cv_db_db_43" >&6
-
-	if test $ol_cv_db_db_43 = yes ; then
-		ol_cv_lib_db=-ldb-43
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.3)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_3+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4.3
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_3=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_dot_3=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_3" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_3" >&6
-
-	if test $ol_cv_db_db_4_dot_3 = yes ; then
-		ol_cv_lib_db=-ldb-4.3
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-3)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_3+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4-3
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_3=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_3=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_3" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_3" >&6
-
-	if test $ol_cv_db_db_4_3 = yes ; then
-		ol_cv_lib_db=-ldb-4-3
-	fi
-fi
-
-	elif test $ol_cv_bdb_minor = 2 ; then
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb42)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb42)... $ECHO_C" >&6
-if test "${ol_cv_db_db42+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb42
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db42=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db42=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db42" >&5
-echo "${ECHO_T}$ol_cv_db_db42" >&6
-
-	if test $ol_cv_db_db42 = yes ; then
-		ol_cv_lib_db=-ldb42
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-42)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-42)... $ECHO_C" >&6
-if test "${ol_cv_db_db_42+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-42
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_42=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_42=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_42" >&5
-echo "${ECHO_T}$ol_cv_db_db_42" >&6
-
-	if test $ol_cv_db_db_42 = yes ; then
-		ol_cv_lib_db=-ldb-42
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.2)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_2+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4.2
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_2=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_dot_2=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_2" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_2" >&6
-
-	if test $ol_cv_db_db_4_dot_2 = yes ; then
-		ol_cv_lib_db=-ldb-4.2
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-2)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_2+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4-2
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_2=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_2=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_2" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_2" >&6
-
-	if test $ol_cv_db_db_4_2 = yes ; then
-		ol_cv_lib_db=-ldb-4-2
-	fi
-fi
-
-	elif test $ol_cv_bdb_minor = 1 ; then
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb41)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb41)... $ECHO_C" >&6
-if test "${ol_cv_db_db41+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb41
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db41=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db41=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db41" >&5
-echo "${ECHO_T}$ol_cv_db_db41" >&6
-
-	if test $ol_cv_db_db41 = yes ; then
-		ol_cv_lib_db=-ldb41
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-41)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-41)... $ECHO_C" >&6
-if test "${ol_cv_db_db_41+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-41
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_41=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_41=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_41" >&5
-echo "${ECHO_T}$ol_cv_db_db_41" >&6
-
-	if test $ol_cv_db_db_41 = yes ; then
-		ol_cv_lib_db=-ldb-41
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.1)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_1+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4.1
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_1=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_dot_1=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_1" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_1" >&6
-
-	if test $ol_cv_db_db_4_dot_1 = yes ; then
-		ol_cv_lib_db=-ldb-4.1
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-1)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_1+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4-1
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_1=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_1=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_1" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_1" >&6
-
-	if test $ol_cv_db_db_4_1 = yes ; then
-		ol_cv_lib_db=-ldb-4-1
-	fi
-fi
-
-	fi
-	if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4" >&5
-echo "${ECHO_T}$ol_cv_db_db_4" >&6
-
-	if test $ol_cv_db_db_4 = yes ; then
-		ol_cv_lib_db=-ldb-4
-	fi
-fi
-
-	if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb4)... $ECHO_C" >&6
-if test "${ol_cv_db_db4+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb4
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db4=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db4=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db4" >&5
-echo "${ECHO_T}$ol_cv_db_db4" >&6
-
-	if test $ol_cv_db_db4 = yes ; then
-		ol_cv_lib_db=-ldb4
-	fi
-fi
-
-	if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb)... $ECHO_C" >&6
-if test "${ol_cv_db_db+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db" >&5
-echo "${ECHO_T}$ol_cv_db_db" >&6
-
-	if test $ol_cv_db_db = yes ; then
-		ol_cv_lib_db=-ldb
-	fi
-fi
-
-
-elif test $ol_cv_bdb_major = 3 ; then
-	if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb3)... $ECHO_C" >&6
-if test "${ol_cv_db_db3+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb3
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db3=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db3=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db3" >&5
-echo "${ECHO_T}$ol_cv_db_db3" >&6
-
-	if test $ol_cv_db_db3 = yes ; then
-		ol_cv_lib_db=-ldb3
-	fi
-fi
-
-	if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-3)... $ECHO_C" >&6
-if test "${ol_cv_db_db_3+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-3
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_3=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_3=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_3" >&5
-echo "${ECHO_T}$ol_cv_db_db_3" >&6
-
-	if test $ol_cv_db_db_3 = yes ; then
-		ol_cv_lib_db=-ldb-3
-	fi
-fi
-
-
-elif test $ol_cv_bdb_major = 2 ; then
-	if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb2)... $ECHO_C" >&6
-if test "${ol_cv_db_db2+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb2
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db2=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db2=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db2" >&5
-echo "${ECHO_T}$ol_cv_db_db2" >&6
-
-	if test $ol_cv_db_db2 = yes ; then
-		ol_cv_lib_db=-ldb2
-	fi
-fi
-
-	if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-2)... $ECHO_C" >&6
-if test "${ol_cv_db_db_2+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-2
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_2=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_2=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_2" >&5
-echo "${ECHO_T}$ol_cv_db_db_2" >&6
-
-	if test $ol_cv_db_db_2 = yes ; then
-		ol_cv_lib_db=-ldb-2
-	fi
-fi
-
-
-elif test $ol_cv_bdb_major = 1 ; then
-	if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb1)... $ECHO_C" >&6
-if test "${ol_cv_db_db1+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb1
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db1=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db1=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db1" >&5
-echo "${ECHO_T}$ol_cv_db_db1" >&6
-
-	if test $ol_cv_db_db1 = yes ; then
-		ol_cv_lib_db=-ldb1
-	fi
-fi
-
-	if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-1)... $ECHO_C" >&6
-if test "${ol_cv_db_db_1+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-1
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_1=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_1=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_1" >&5
-echo "${ECHO_T}$ol_cv_db_db_1" >&6
-
-	if test $ol_cv_db_db_1 = yes ; then
-		ol_cv_lib_db=-ldb-1
-	fi
-fi
-
-fi
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (default)" >&5
-echo $ECHO_N "checking for Berkeley DB link (default)... $ECHO_C" >&6
-if test "${ol_cv_db_none+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_none=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_none=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_none" >&5
-echo "${ECHO_T}$ol_cv_db_none" >&6
-
-	if test $ol_cv_db_none = yes ; then
-		ol_cv_lib_db=yes
-	fi
-fi
-
-
-		if test "$ol_cv_lib_db" != no ; then
-			ol_cv_berkeley_db=yes
-		fi
-	fi
-fi
-
-	else
-		ol_cv_berkeley_db=no
-
-for ac_header in db.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## --------------------------------------------- ##
-## Report this to <http://www.openldap.org/its/> ##
-## --------------------------------------------- ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-if test $ac_cv_header_db_h = yes; then
-	ol_cv_lib_db=no
-
-echo "$as_me:$LINENO: checking for Berkeley DB major version" >&5
-echo $ECHO_N "checking for Berkeley DB major version... $ECHO_C" >&6
-if test "${ol_cv_bdb_major+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_cv_bdb_major=0
-	if test $ol_cv_bdb_major = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MAJOR
-#	define DB_VERSION_MAJOR 1
-#endif
-#if DB_VERSION_MAJOR == 4
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_major=4
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_major = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MAJOR
-#	define DB_VERSION_MAJOR 1
-#endif
-#if DB_VERSION_MAJOR == 3
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_major=3
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_major = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MAJOR
-#	define DB_VERSION_MAJOR 1
-#endif
-#if DB_VERSION_MAJOR == 2
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_major=2
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_major = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MAJOR
-#	define DB_VERSION_MAJOR 1
-#endif
-#if DB_VERSION_MAJOR == 1
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_major=1
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-
-	if test $ol_cv_bdb_major = 0 ; then
-		{ { echo "$as_me:$LINENO: error: Unknown Berkeley DB major version" >&5
-echo "$as_me: error: Unknown Berkeley DB major version" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_bdb_major" >&5
-echo "${ECHO_T}$ol_cv_bdb_major" >&6
-
-echo "$as_me:$LINENO: checking for Berkeley DB minor version" >&5
-echo $ECHO_N "checking for Berkeley DB minor version... $ECHO_C" >&6
-if test "${ol_cv_bdb_minor+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_cv_bdb_minor=0
-	if test $ol_cv_bdb_minor = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#	define DB_VERSION_MINOR 0
-#endif
-#if DB_VERSION_MINOR == 9
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_minor=9
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_minor = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#	define DB_VERSION_MINOR 0
-#endif
-#if DB_VERSION_MINOR == 8
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_minor=8
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_minor = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#	define DB_VERSION_MINOR 0
-#endif
-#if DB_VERSION_MINOR == 7
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_minor=7
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_minor = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#	define DB_VERSION_MINOR 0
-#endif
-#if DB_VERSION_MINOR == 6
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_minor=6
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_minor = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#	define DB_VERSION_MINOR 0
-#endif
-#if DB_VERSION_MINOR == 5
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_minor=5
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_minor = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#	define DB_VERSION_MINOR 0
-#endif
-#if DB_VERSION_MINOR == 4
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_minor=4
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_minor = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#	define DB_VERSION_MINOR 0
-#endif
-#if DB_VERSION_MINOR == 3
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_minor=3
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_minor = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#	define DB_VERSION_MINOR 0
-#endif
-#if DB_VERSION_MINOR == 2
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_minor=2
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-	if test $ol_cv_bdb_minor = 0 ; then
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#	define DB_VERSION_MINOR 0
-#endif
-#if DB_VERSION_MINOR == 1
-__db_version
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "__db_version" >/dev/null 2>&1; then
-  ol_cv_bdb_minor=1
-else
-  :
-fi
-rm -f conftest*
-
-	fi
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_bdb_minor" >&5
-echo "${ECHO_T}$ol_cv_bdb_minor" >&6
-
-if test $ol_cv_bdb_major = 4 ; then
-	if test $ol_cv_bdb_minor = 5 ; then
-		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb45)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb45)... $ECHO_C" >&6
 if test "${ol_cv_db_db45+set}" = set; then
@@ -32511,13 +28509,13 @@
 fi
 
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.5)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.5)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_5+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-5)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4-5)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_5+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4.5
+	ol_DB_LIB=-ldb-4-5
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32598,12 +28596,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_5=yes
+  ol_cv_db_db_4_5=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_dot_5=no
+ol_cv_db_db_4_5=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32611,22 +28609,23 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_5" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_5" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_5" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_5" >&6
 
-	if test $ol_cv_db_db_4_dot_5 = yes ; then
-		ol_cv_lib_db=-ldb-4.5
+	if test $ol_cv_db_db_4_5 = yes ; then
+		ol_cv_lib_db=-ldb-4-5
 	fi
 fi
 
+	elif test $ol_cv_bdb_minor = 4 ; then
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-5)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-5)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_5+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.4)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_4+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4-5
+	ol_DB_LIB=-ldb-4.4
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32707,12 +28706,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_5=yes
+  ol_cv_db_db_4_dot_4=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_5=no
+ol_cv_db_db_4_dot_4=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32720,15 +28719,14 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_5" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_5" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_4" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_4" >&6
 
-	if test $ol_cv_db_db_4_5 = yes ; then
-		ol_cv_lib_db=-ldb-4-5
+	if test $ol_cv_db_db_4_dot_4 = yes ; then
+		ol_cv_lib_db=-ldb-4.4
 	fi
 fi
 
-	elif test $ol_cv_bdb_minor = 4 ; then
 		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb44)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb44)... $ECHO_C" >&6
@@ -32948,13 +28946,13 @@
 fi
 
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.4)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_4+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4-4)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_4+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4.4
+	ol_DB_LIB=-ldb-4-4
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -33035,12 +29033,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_4=yes
+  ol_cv_db_db_4_4=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_dot_4=no
+ol_cv_db_db_4_4=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -33048,22 +29046,23 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_4" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_4" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_4" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_4" >&6
 
-	if test $ol_cv_db_db_4_dot_4 = yes ; then
-		ol_cv_lib_db=-ldb-4.4
+	if test $ol_cv_db_db_4_4 = yes ; then
+		ol_cv_lib_db=-ldb-4-4
 	fi
 fi
 
+	elif test $ol_cv_bdb_minor = 3 ; then
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-4)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_4+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.3)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.3)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_3+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4-4
+	ol_DB_LIB=-ldb-4.3
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -33144,12 +29143,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_4=yes
+  ol_cv_db_db_4_dot_3=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_4=no
+ol_cv_db_db_4_dot_3=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -33157,15 +29156,14 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_4" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_4" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_3" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_3" >&6
 
-	if test $ol_cv_db_db_4_4 = yes ; then
-		ol_cv_lib_db=-ldb-4-4
+	if test $ol_cv_db_db_4_dot_3 = yes ; then
+		ol_cv_lib_db=-ldb-4.3
 	fi
 fi
 
-	elif test $ol_cv_bdb_minor = 3 ; then
 		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb43)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb43)... $ECHO_C" >&6
@@ -33385,13 +29383,13 @@
 fi
 
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.3)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_3+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-3)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4-3)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_3+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4.3
+	ol_DB_LIB=-ldb-4-3
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -33472,12 +29470,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_3=yes
+  ol_cv_db_db_4_3=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_dot_3=no
+ol_cv_db_db_4_3=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -33485,22 +29483,23 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_3" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_3" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_3" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_3" >&6
 
-	if test $ol_cv_db_db_4_dot_3 = yes ; then
-		ol_cv_lib_db=-ldb-4.3
+	if test $ol_cv_db_db_4_3 = yes ; then
+		ol_cv_lib_db=-ldb-4-3
 	fi
 fi
 
+	elif test $ol_cv_bdb_minor = 2 ; then
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-3)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_3+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.2)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.2)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_2+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4-3
+	ol_DB_LIB=-ldb-4.2
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -33581,12 +29580,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_3=yes
+  ol_cv_db_db_4_dot_2=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_3=no
+ol_cv_db_db_4_dot_2=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -33594,15 +29593,14 @@
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_3" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_3" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_2" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_2" >&6
 
-	if test $ol_cv_db_db_4_3 = yes ; then
-		ol_cv_lib_db=-ldb-4-3
+	if test $ol_cv_db_db_4_dot_2 = yes ; then
+		ol_cv_lib_db=-ldb-4.2
 	fi
 fi
 
-	elif test $ol_cv_bdb_minor = 2 ; then
 		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb42)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb42)... $ECHO_C" >&6
@@ -33822,115 +29820,6 @@
 fi
 
 		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.2)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_2+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4.2
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_2=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_dot_2=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_2" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_2" >&6
-
-	if test $ol_cv_db_db_4_dot_2 = yes ; then
-		ol_cv_lib_db=-ldb-4.2
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-2)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-4-2)... $ECHO_C" >&6
 if test "${ol_cv_db_db_4_2+set}" = set; then
@@ -34039,444 +29928,7 @@
 	fi
 fi
 
-	elif test $ol_cv_bdb_minor = 1 ; then
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb41)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb41)... $ECHO_C" >&6
-if test "${ol_cv_db_db41+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb41
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db41=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db41=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db41" >&5
-echo "${ECHO_T}$ol_cv_db_db41" >&6
-
-	if test $ol_cv_db_db41 = yes ; then
-		ol_cv_lib_db=-ldb41
 	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-41)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-41)... $ECHO_C" >&6
-if test "${ol_cv_db_db_41+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-41
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_41=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_41=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_41" >&5
-echo "${ECHO_T}$ol_cv_db_db_41" >&6
-
-	if test $ol_cv_db_db_41 = yes ; then
-		ol_cv_lib_db=-ldb-41
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.1)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_1+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4.1
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_1=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_dot_1=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_1" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_1" >&6
-
-	if test $ol_cv_db_db_4_dot_1 = yes ; then
-		ol_cv_lib_db=-ldb-4.1
-	fi
-fi
-
-		if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-1)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_1+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	ol_DB_LIB=-ldb-4-1
-	ol_LIBS=$LIBS
-	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-	cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-int
-main ()
-{
-
-#if DB_VERSION_MAJOR > 1
-	{
-		char *version;
-		int major, minor, patch;
-
-		version = db_version( &major, &minor, &patch );
-
-		if( major != DB_VERSION_MAJOR ||
-			minor < DB_VERSION_MINOR )
-		{
-			printf("Berkeley DB version mismatch\n"
-				"\theader: %s\n\tlibrary: %s\n",
-				DB_VERSION_STRING, version);
-			return 1;
-		}
-	}
-#endif
-
-#if DB_VERSION_MAJOR > 2
-	db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-	db_appexit( NULL );
-#else
-	(void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ol_cv_db_db_4_1=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ol_cv_db_db_4_1=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_1" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_1" >&6
-
-	if test $ol_cv_db_db_4_1 = yes ; then
-		ol_cv_lib_db=-ldb-4-1
-	fi
-fi
-
-	fi
 	if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-4)... $ECHO_C" >&6
@@ -35793,46 +31245,24 @@
 	fi
 fi
 
+
+	if test $ol_cv_berkeley_db = no ; then
+		{ { echo "$as_me:$LINENO: error: BDB/HDB: BerkeleyDB not available" >&5
+echo "$as_me: error: BDB/HDB: BerkeleyDB not available" >&2;}
+   { (exit 1); exit 1; }; }
 	fi
 
-	if test $ol_cv_berkeley_db != no ; then
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_BERKELEY_DB 1
 _ACEOF
 
 
-		ol_link_ldbm=berkeley
-		ol_enable_ldbm_api=berkeley
-
-		if test $ol_enable_ldbm_type = hash ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define LDBM_USE_DBHASH 1
-_ACEOF
-
-		else
-
-cat >>confdefs.h <<\_ACEOF
-#define LDBM_USE_DBBTREE 1
-_ACEOF
-
-		fi
-
-						if test $ol_cv_lib_db != yes ; then
-			LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_db"
-		fi
+			if test $ol_cv_lib_db != yes ; then
+		BDB_LIBS="$BDB_LIBS $ol_cv_lib_db"
 	fi
-	;;
-esac
 
-if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
-	if test $ol_link_ldbm != berkeley ; then
-		{ { echo "$as_me:$LINENO: error: BDB/HDB: BerkeleyDB not available" >&5
-echo "$as_me: error: BDB/HDB: BerkeleyDB not available" >&2;}
-   { (exit 1); exit 1; }; }
-	else
-		echo "$as_me:$LINENO: checking Berkeley DB version for BDB/HDB backends" >&5
+	echo "$as_me:$LINENO: checking Berkeley DB version for BDB/HDB backends" >&5
 echo $ECHO_N "checking Berkeley DB version for BDB/HDB backends... $ECHO_C" >&6
 if test "${ol_cv_bdb_compat+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -35855,8 +31285,8 @@
 #	define DB_VERSION_MINOR 0
 #endif
 
-/* require 4.2-4.5 */
-#if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 2) && (DB_VERSION_MINOR < 6)
+/* require 4.2 or later, but exclude 4.3 */
+#if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 2) && (DB_VERSION_MINOR !=3)
 	__db_version_compat
 #endif
 
@@ -35874,203 +31304,34 @@
 echo "${ECHO_T}$ol_cv_bdb_compat" >&6
 
 
-		if test $ol_cv_bdb_compat != yes ; then
-			{ { echo "$as_me:$LINENO: error: BDB/HDB: BerkeleyDB version incompatible" >&5
+	if test $ol_cv_bdb_compat != yes ; then
+		{ { echo "$as_me:$LINENO: error: BDB/HDB: BerkeleyDB version incompatible" >&5
 echo "$as_me: error: BDB/HDB: BerkeleyDB version incompatible" >&2;}
    { (exit 1); exit 1; }; }
-		fi
 	fi
-fi
 
-if test $ol_link_ldbm = no && test $ol_enable_ldbm_type = btree ; then
-	{ echo "$as_me:$LINENO: WARNING: Could not find LDBM with BTREE support" >&5
-echo "$as_me: WARNING: Could not find LDBM with BTREE support" >&2;}
-	ol_enable_ldbm_api=none
+	SLAPD_LIBS="$SLAPD_LIBS \$(BDB_LIBS)"
+
+	ol_link_bdb=yes
 fi
 
-if test $ol_enable_ldbm_api = auto || test $ol_enable_ldbm_api = mdbm ; then
-	echo "$as_me:$LINENO: checking for MDBM library" >&5
-echo $ECHO_N "checking for MDBM library... $ECHO_C" >&6
-if test "${ol_cv_lib_mdbm+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  	ol_LIBS="$LIBS"
-	echo "$as_me:$LINENO: checking for mdbm_set_chain" >&5
-echo $ECHO_N "checking for mdbm_set_chain... $ECHO_C" >&6
-if test "${ac_cv_func_mdbm_set_chain+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define mdbm_set_chain to an innocuous variant, in case <limits.h> declares mdbm_set_chain.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define mdbm_set_chain innocuous_mdbm_set_chain
 
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char mdbm_set_chain (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
+if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then
+	BUILD_LIBS_DYNAMIC=shared
 
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef mdbm_set_chain
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char mdbm_set_chain ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_mdbm_set_chain) || defined (__stub___mdbm_set_chain)
-choke me
-#else
-char (*f) () = mdbm_set_chain;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != mdbm_set_chain;
-  ;
-  return 0;
-}
+cat >>confdefs.h <<\_ACEOF
+#define LDAP_LIBS_DYNAMIC 1
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_mdbm_set_chain=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_func_mdbm_set_chain=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_mdbm_set_chain" >&5
-echo "${ECHO_T}$ac_cv_func_mdbm_set_chain" >&6
-if test $ac_cv_func_mdbm_set_chain = yes; then
-  ol_cv_lib_mdbm=yes
+	LTSTATIC=""
 else
-
-		echo "$as_me:$LINENO: checking for mdbm_set_chain in -lmdbm" >&5
-echo $ECHO_N "checking for mdbm_set_chain in -lmdbm... $ECHO_C" >&6
-if test "${ac_cv_lib_mdbm_mdbm_set_chain+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lmdbm  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char mdbm_set_chain ();
-int
-main ()
-{
-mdbm_set_chain ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_mdbm_mdbm_set_chain=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_mdbm_mdbm_set_chain=no
+	BUILD_LIBS_DYNAMIC=static
+	LTSTATIC="-static"
 fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_mdbm_mdbm_set_chain" >&5
-echo "${ECHO_T}$ac_cv_lib_mdbm_mdbm_set_chain" >&6
-if test $ac_cv_lib_mdbm_mdbm_set_chain = yes; then
-  ol_cv_lib_mdbm=-lmdbm
-else
-  ol_cv_lib_mdbm=no
-fi
 
+if test $ol_enable_wrappers != no ; then
 
-fi
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_lib_mdbm" >&5
-echo "${ECHO_T}$ol_cv_lib_mdbm" >&6
-
-
-
-for ac_header in mdbm.h
+for ac_header in tcpd.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -36215,102 +31476,29 @@
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
-fi
-
-done
-
- echo "$as_me:$LINENO: checking for db" >&5
-echo $ECHO_N "checking for db... $ECHO_C" >&6
-if test "${ol_cv_mdbm+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-	if test $ol_cv_lib_mdbm = no || test $ac_cv_header_mdbm_h = no ; then
-		ol_cv_mdbm=no
-	else
-		ol_cv_mdbm=yes
-	fi
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_mdbm" >&5
-echo "${ECHO_T}$ol_cv_mdbm" >&6
- if test $ol_cv_mdbm = yes ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_MDBM 1
-_ACEOF
-
- fi
-
-
-	if test $ol_cv_mdbm = yes ; then
-		ol_link_ldbm=mdbm
-		ol_enable_ldbm_api=mdbm
-		if test $ol_cv_lib_mdbm != yes ; then
-			LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_mdbm"
-		fi
-	fi
-fi
-
-if test $ol_enable_ldbm_api = auto || test $ol_enable_ldbm_api = gdbm ; then
-	echo "$as_me:$LINENO: checking for GDBM library" >&5
-echo $ECHO_N "checking for GDBM library... $ECHO_C" >&6
-if test "${ol_cv_lib_gdbm+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  	ol_LIBS="$LIBS"
-	echo "$as_me:$LINENO: checking for gdbm_open" >&5
-echo $ECHO_N "checking for gdbm_open... $ECHO_C" >&6
-if test "${ac_cv_func_gdbm_open+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
+		echo "$as_me:$LINENO: checking for TCP wrappers library" >&5
+echo $ECHO_N "checking for TCP wrappers library... $ECHO_C" >&6
+		save_LIBS="$LIBS"
+		LIBS="$LIBS -lwrap"
+		cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-/* Define gdbm_open to an innocuous variant, in case <limits.h> declares gdbm_open.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define gdbm_open innocuous_gdbm_open
 
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char gdbm_open (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
+#include <tcpd.h>
+int allow_severity = 0;
+int deny_severity  = 0;
 
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+struct request_info *req;
 
-#undef gdbm_open
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char gdbm_open ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_gdbm_open) || defined (__stub___gdbm_open)
-choke me
-#else
-char (*f) () = gdbm_open;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
 int
 main ()
 {
-return f != gdbm_open;
+
+hosts_access(req)
+
   ;
   return 0;
 }
@@ -36337,47 +31525,35 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_func_gdbm_open=yes
+  echo "$as_me:$LINENO: result: -lwrap" >&5
+echo "${ECHO_T}-lwrap" >&6
+		have_wrappers=yes
+		LIBS="$save_LIBS"
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_func_gdbm_open=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_gdbm_open" >&5
-echo "${ECHO_T}$ac_cv_func_gdbm_open" >&6
-if test $ac_cv_func_gdbm_open = yes; then
-  ol_cv_lib_gdbm=yes
-else
 
-		echo "$as_me:$LINENO: checking for gdbm_open in -lgdbm" >&5
-echo $ECHO_N "checking for gdbm_open in -lgdbm... $ECHO_C" >&6
-if test "${ac_cv_lib_gdbm_gdbm_open+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lgdbm  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
+				LIBS="$LIBS -lnsl"
+		cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char gdbm_open ();
+#include <tcpd.h>
+int allow_severity = 0;
+int deny_severity  = 0;
+
+struct request_info *req;
+
 int
 main ()
 {
-gdbm_open ();
+
+hosts_access(req)
+
   ;
   return 0;
 }
@@ -36404,243 +31580,68 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_gdbm_gdbm_open=yes
+  echo "$as_me:$LINENO: result: -lwrap -lnsl" >&5
+echo "${ECHO_T}-lwrap -lnsl" >&6
+		have_wrappers=yes
+		LIBS="$save_LIBS -lnsl"
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_gdbm_gdbm_open=no
+
+		echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+		have_wrappers=no
+		LIBS=$save_LIBS
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_gdbm_gdbm_open" >&5
-echo "${ECHO_T}$ac_cv_lib_gdbm_gdbm_open" >&6
-if test $ac_cv_lib_gdbm_gdbm_open = yes; then
-  ol_cv_lib_gdbm=-lgdbm
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
 else
-  ol_cv_lib_gdbm=no
+  have_wrappers=no
 fi
 
-
-fi
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_lib_gdbm" >&5
-echo "${ECHO_T}$ol_cv_lib_gdbm" >&6
-
-
-
-for ac_header in gdbm.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## --------------------------------------------- ##
-## Report this to <http://www.openldap.org/its/> ##
-## --------------------------------------------- ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
 done
 
- echo "$as_me:$LINENO: checking for db" >&5
-echo $ECHO_N "checking for db... $ECHO_C" >&6
-if test "${ol_cv_gdbm+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
 
-	if test $ol_cv_lib_gdbm = no || test $ac_cv_header_gdbm_h = no ; then
-		ol_cv_gdbm=no
-	else
-		ol_cv_gdbm=yes
-	fi
+	if test $have_wrappers = yes ; then
 
-fi
-echo "$as_me:$LINENO: result: $ol_cv_gdbm" >&5
-echo "${ECHO_T}$ol_cv_gdbm" >&6
- if test $ol_cv_gdbm = yes ; then
-
 cat >>confdefs.h <<\_ACEOF
-#define HAVE_GDBM 1
+#define HAVE_TCPD 1
 _ACEOF
 
- fi
-
-
-	if test $ol_cv_gdbm = yes ; then
-		ol_link_ldbm=gdbm
-		ol_enable_ldbm_api=gdbm
-
-		if test $ol_cv_lib_gdbm != yes ; then
-			LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_gdbm"
-		fi
+		WRAP_LIBS="-lwrap"
+	elif test $ol_enable_wrappers = yes ; then
+		{ { echo "$as_me:$LINENO: error: could not find TCP wrappers, select apppropriate options or disable" >&5
+echo "$as_me: error: could not find TCP wrappers, select apppropriate options or disable" >&2;}
+   { (exit 1); exit 1; }; }
+	else
+		{ echo "$as_me:$LINENO: WARNING: could not find TCP wrappers, support disabled" >&5
+echo "$as_me: WARNING: could not find TCP wrappers, support disabled" >&2;}
+		WRAP_LIBS=""
 	fi
 fi
 
-if test $ol_enable_ldbm_api = ndbm ; then
-	echo "$as_me:$LINENO: checking for NDBM library" >&5
-echo $ECHO_N "checking for NDBM library... $ECHO_C" >&6
-if test "${ol_cv_lib_ndbm+set}" = set; then
+if test $ol_enable_syslog != no ; then
+	echo "$as_me:$LINENO: checking for openlog" >&5
+echo $ECHO_N "checking for openlog... $ECHO_C" >&6
+if test "${ac_cv_func_openlog+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  	ol_LIBS="$LIBS"
-	echo "$as_me:$LINENO: checking for dbm_open" >&5
-echo $ECHO_N "checking for dbm_open... $ECHO_C" >&6
-if test "${ac_cv_func_dbm_open+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-/* Define dbm_open to an innocuous variant, in case <limits.h> declares dbm_open.
+/* Define openlog to an innocuous variant, in case <limits.h> declares openlog.
    For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define dbm_open innocuous_dbm_open
+#define openlog innocuous_openlog
 
 /* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char dbm_open (); below.
+    which can conflict with char openlog (); below.
     Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
     <limits.h> exists even on freestanding compilers.  */
 
@@ -36650,7 +31651,7 @@
 # include <assert.h>
 #endif
 
-#undef dbm_open
+#undef openlog
 
 /* Override any gcc2 internal prototype to avoid an error.  */
 #ifdef __cplusplus
@@ -36659,14 +31660,14 @@
 #endif
 /* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
-char dbm_open ();
+char openlog ();
 /* The GNU C library defines this for functions which it implements
     to always fail with ENOSYS.  Some functions are actually named
     something starting with __ and the normal name is an alias.  */
-#if defined (__stub_dbm_open) || defined (__stub___dbm_open)
+#if defined (__stub_openlog) || defined (__stub___openlog)
 choke me
 #else
-char (*f) () = dbm_open;
+char (*f) () = openlog;
 #endif
 #ifdef __cplusplus
 }
@@ -36675,7 +31676,7 @@
 int
 main ()
 {
-return f != dbm_open;
+return f != openlog;
   ;
   return 0;
 }
@@ -36702,174 +31703,32 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_func_dbm_open=yes
+  ac_cv_func_openlog=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_func_dbm_open=no
+ac_cv_func_openlog=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_func_dbm_open" >&5
-echo "${ECHO_T}$ac_cv_func_dbm_open" >&6
-if test $ac_cv_func_dbm_open = yes; then
-  ol_cv_lib_ndbm=yes
-else
+echo "$as_me:$LINENO: result: $ac_cv_func_openlog" >&5
+echo "${ECHO_T}$ac_cv_func_openlog" >&6
 
-		echo "$as_me:$LINENO: checking for dbm_open in -lndbm" >&5
-echo $ECHO_N "checking for dbm_open in -lndbm... $ECHO_C" >&6
-if test "${ac_cv_lib_ndbm_dbm_open+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lndbm  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dbm_open ();
-int
-main ()
-{
-dbm_open ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_ndbm_dbm_open=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_ndbm_dbm_open=no
+	if test $ac_cv_func_openlog = no && test $ol_enable_syslog = yes; then
+		{ { echo "$as_me:$LINENO: error: could not find syslog" >&5
+echo "$as_me: error: could not find syslog" >&2;}
+   { (exit select appropriate options or disable); exit select appropriate options or disable; }; }
+	fi
+	ol_enable_syslog=$ac_cv_func_openlog
 fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_ndbm_dbm_open" >&5
-echo "${ECHO_T}$ac_cv_lib_ndbm_dbm_open" >&6
-if test $ac_cv_lib_ndbm_dbm_open = yes; then
-  ol_cv_lib_ndbm=-lndbm
-else
 
-			echo "$as_me:$LINENO: checking for dbm_open in -ldbm" >&5
-echo $ECHO_N "checking for dbm_open in -ldbm... $ECHO_C" >&6
-if test "${ac_cv_lib_dbm_dbm_open+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldbm  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
+ol_link_sql=no
+if test $ol_enable_sql != no ; then
 
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dbm_open ();
-int
-main ()
-{
-dbm_open ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_dbm_dbm_open=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_dbm_dbm_open=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dbm_dbm_open" >&5
-echo "${ECHO_T}$ac_cv_lib_dbm_dbm_open" >&6
-if test $ac_cv_lib_dbm_dbm_open = yes; then
-  ol_cv_lib_ndbm=-ldbm
-else
-  ol_cv_lib_ndbm=no
-fi
-
-fi
-
-
-fi
-
-	LIBS="$ol_LIBS"
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_lib_ndbm" >&5
-echo "${ECHO_T}$ol_cv_lib_ndbm" >&6
-
-
-
-for ac_header in ndbm.h
+for ac_header in sql.h sqlext.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -37014,240 +31873,53 @@
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
-fi
-
-done
-
- echo "$as_me:$LINENO: checking for db" >&5
-echo $ECHO_N "checking for db... $ECHO_C" >&6
-if test "${ol_cv_ndbm+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	if test $ol_cv_lib_ndbm = no || test $ac_cv_header_ndbm_h = no ; then
-		ol_cv_ndbm=no
-	else
-		ol_cv_ndbm=yes
-	fi
+		{ { echo "$as_me:$LINENO: error: could not locate SQL headers" >&5
+echo "$as_me: error: could not locate SQL headers" >&2;}
+   { (exit 1); exit 1; }; }
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_ndbm" >&5
-echo "${ECHO_T}$ol_cv_ndbm" >&6
- if test $ol_cv_ndbm = yes ; then
 
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_NDBM 1
-_ACEOF
+done
 
- fi
 
+	sql_LIBS="$LIBS"
+	LIBS="$LTHREAD_LIBS"
 
-	if test $ol_cv_ndbm = yes ; then
-		ol_link_ldbm=ndbm
-		ol_enable_ldbm_api=ndbm
-
-		if test $ol_cv_lib_ndbm != yes ; then
-			LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_ndbm"
-		fi
+	if test $ol_with_odbc = auto ; then
+		ol_with_odbc="iodbc unixodbc"
 	fi
-fi
 
-if test $ol_link_ldbm = no && test $ol_enable_ldbm != no ; then
-	{ { echo "$as_me:$LINENO: error: could not find suitable LDBM backend" >&5
-echo "$as_me: error: could not find suitable LDBM backend" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-if test $ol_enable_bdb = yes ||
-   test $ol_enable_hdb = yes ||
-   test $ol_enable_ldbm = yes ; then
-	SLAPD_LIBS="$SLAPD_LIBS \$(LDBM_LIBS)"
-fi
-
-
-if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then
-	BUILD_LIBS_DYNAMIC=shared
-
-cat >>confdefs.h <<\_ACEOF
-#define LDAP_LIBS_DYNAMIC 1
-_ACEOF
-
-	LTSTATIC=""
-else
-	BUILD_LIBS_DYNAMIC=static
-	LTSTATIC="-static"
-fi
-
-if test $ol_enable_wrappers != no ; then
-
-for ac_header in tcpd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+	for odbc in $ol_with_odbc ; do
+		if test $ol_link_sql = no ; then
+			case $odbc in
+			iodbc)
+				echo "$as_me:$LINENO: checking for SQLDriverConnect in -liodbc" >&5
+echo $ECHO_N "checking for SQLDriverConnect in -liodbc... $ECHO_C" >&6
+if test "${ac_cv_lib_iodbc_SQLDriverConnect+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-liodbc  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## --------------------------------------------- ##
-## Report this to <http://www.openldap.org/its/> ##
-## --------------------------------------------- ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-		echo "$as_me:$LINENO: checking for TCP wrappers library" >&5
-echo $ECHO_N "checking for TCP wrappers library... $ECHO_C" >&6
-		save_LIBS="$LIBS"
-		LIBS="$LIBS -lwrap"
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <tcpd.h>
-int allow_severity = 0;
-int deny_severity  = 0;
-
-struct request_info *req;
-
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char SQLDriverConnect ();
 int
 main ()
 {
-
-hosts_access(req)
-
+SQLDriverConnect ();
   ;
   return 0;
 }
@@ -37274,158 +31946,56 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  echo "$as_me:$LINENO: result: -lwrap" >&5
-echo "${ECHO_T}-lwrap" >&6
-		have_wrappers=yes
-		LIBS="$save_LIBS"
+  ac_cv_lib_iodbc_SQLDriverConnect=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
-				LIBS="$LIBS -lnsl"
-		cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <tcpd.h>
-int allow_severity = 0;
-int deny_severity  = 0;
-
-struct request_info *req;
-
-int
-main ()
-{
-
-hosts_access(req)
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  echo "$as_me:$LINENO: result: -lwrap -lnsl" >&5
-echo "${ECHO_T}-lwrap -lnsl" >&6
-		have_wrappers=yes
-		LIBS="$save_LIBS -lnsl"
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-		echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-		have_wrappers=no
-		LIBS=$save_LIBS
+ac_cv_lib_iodbc_SQLDriverConnect=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_cv_lib_iodbc_SQLDriverConnect" >&5
+echo "${ECHO_T}$ac_cv_lib_iodbc_SQLDriverConnect" >&6
+if test $ac_cv_lib_iodbc_SQLDriverConnect = yes; then
+  have_iodbc=yes
 else
-  have_wrappers=no
+  have_iodbc=no
 fi
 
-done
+				if test $have_iodbc = yes ; then
+					ol_link_sql="-liodbc"
+				fi
+				;;
 
-
-	if test $have_wrappers = yes ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_TCPD 1
-_ACEOF
-
-		WRAP_LIBS="-lwrap"
-	elif test $ol_enable_wrappers = yes ; then
-		{ { echo "$as_me:$LINENO: error: could not find TCP wrappers, select apppropriate options or disable" >&5
-echo "$as_me: error: could not find TCP wrappers, select apppropriate options or disable" >&2;}
-   { (exit 1); exit 1; }; }
-	else
-		{ echo "$as_me:$LINENO: WARNING: could not find TCP wrappers, support disabled" >&5
-echo "$as_me: WARNING: could not find TCP wrappers, support disabled" >&2;}
-		WRAP_LIBS=""
-	fi
-fi
-
-if test $ol_enable_syslog != no ; then
-	echo "$as_me:$LINENO: checking for openlog" >&5
-echo $ECHO_N "checking for openlog... $ECHO_C" >&6
-if test "${ac_cv_func_openlog+set}" = set; then
+			unixodbc)
+				echo "$as_me:$LINENO: checking for SQLDriverConnect in -lodbc" >&5
+echo $ECHO_N "checking for SQLDriverConnect in -lodbc... $ECHO_C" >&6
+if test "${ac_cv_lib_odbc_SQLDriverConnect+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lodbc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-/* Define openlog to an innocuous variant, in case <limits.h> declares openlog.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define openlog innocuous_openlog
 
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char openlog (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef openlog
-
 /* Override any gcc2 internal prototype to avoid an error.  */
 #ifdef __cplusplus
 extern "C"
-{
 #endif
 /* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
-char openlog ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_openlog) || defined (__stub___openlog)
-choke me
-#else
-char (*f) () = openlog;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
+char SQLDriverConnect ();
 int
 main ()
 {
-return f != openlog;
+SQLDriverConnect ();
   ;
   return 0;
 }
@@ -37452,32 +32022,54 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_func_openlog=yes
+  ac_cv_lib_odbc_SQLDriverConnect=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_func_openlog=no
+ac_cv_lib_odbc_SQLDriverConnect=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_func_openlog" >&5
-echo "${ECHO_T}$ac_cv_func_openlog" >&6
+echo "$as_me:$LINENO: result: $ac_cv_lib_odbc_SQLDriverConnect" >&5
+echo "${ECHO_T}$ac_cv_lib_odbc_SQLDriverConnect" >&6
+if test $ac_cv_lib_odbc_SQLDriverConnect = yes; then
+  have_odbc=yes
+else
+  have_odbc=no
+fi
 
-	if test $ac_cv_func_openlog = no && test $ol_enable_syslog = yes; then
-		{ { echo "$as_me:$LINENO: error: could not find syslog" >&5
-echo "$as_me: error: could not find syslog" >&2;}
-   { (exit select appropriate options or disable); exit select appropriate options or disable; }; }
+				if test $have_odbc = yes ; then
+					ol_link_sql="-lodbc"
+				fi
+				;;
+
+			*)
+				{ { echo "$as_me:$LINENO: error: unknown ODBC library" >&5
+echo "$as_me: error: unknown ODBC library" >&2;}
+   { (exit 1); exit 1; }; }
+				;;
+			esac
+		fi
+	done
+
+	LIBS="$sql_LIBS"
+
+	if test $ol_link_sql != no ; then
+		SLAPD_SQL_LIBS="$ol_link_sql"
+
+	elif test $ol_enable_sql != auto ; then
+		{ { echo "$as_me:$LINENO: error: could not locate suitable ODBC library" >&5
+echo "$as_me: error: could not locate suitable ODBC library" >&2;}
+   { (exit 1); exit 1; }; }
 	fi
-	ol_enable_syslog=$ac_cv_func_openlog
 fi
 
-ol_link_sql=no
-if test $ol_enable_sql != no ; then
+ol_icu=no
 
-
-for ac_header in sql.h sqlext.h
+for ac_header in unicode/utypes.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -37622,129 +32214,36 @@
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
-else
-
-		{ { echo "$as_me:$LINENO: error: could not locate SQL headers" >&5
-echo "$as_me: error: could not locate SQL headers" >&2;}
-   { (exit 1); exit 1; }; }
-
 fi
 
 done
 
+if test $ac_cv_header_unicode_utypes_h = yes ; then
+		OL_ICULIBS="-licuuc -licudata"
 
-	sql_LIBS="$LIBS"
-	LIBS="$LTHREAD_LIBS"
-
-	if test $ol_with_odbc = auto ; then
-		ol_with_odbc="iodbc unixodbc"
-	fi
-
-	for odbc in $ol_with_odbc ; do
-		if test $ol_link_sql = no ; then
-			case $odbc in
-			iodbc)
-				echo "$as_me:$LINENO: checking for SQLDriverConnect in -liodbc" >&5
-echo $ECHO_N "checking for SQLDriverConnect in -liodbc... $ECHO_C" >&6
-if test "${ac_cv_lib_iodbc_SQLDriverConnect+set}" = set; then
+	echo "$as_me:$LINENO: checking for ICU libraries" >&5
+echo $ECHO_N "checking for ICU libraries... $ECHO_C" >&6
+if test "${ol_cv_lib_icu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-liodbc  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
+
+		ol_LIBS="$LIBS"
+		LIBS="$OL_ICULIBS $LIBS"
+		cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char SQLDriverConnect ();
+#include <unicode/utypes.h>
+
 int
 main ()
 {
-SQLDriverConnect ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_iodbc_SQLDriverConnect=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_iodbc_SQLDriverConnect=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_iodbc_SQLDriverConnect" >&5
-echo "${ECHO_T}$ac_cv_lib_iodbc_SQLDriverConnect" >&6
-if test $ac_cv_lib_iodbc_SQLDriverConnect = yes; then
-  have_iodbc=yes
-else
-  have_iodbc=no
-fi
+(void) u_errorName(0);
 
-				if test $have_iodbc = yes ; then
-					ol_link_sql="-liodbc"
-				fi
-				;;
-
-			unixodbc)
-				echo "$as_me:$LINENO: checking for SQLDriverConnect in -lodbc" >&5
-echo $ECHO_N "checking for SQLDriverConnect in -lodbc... $ECHO_C" >&6
-if test "${ac_cv_lib_odbc_SQLDriverConnect+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lodbc  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char SQLDriverConnect ();
-int
-main ()
-{
-SQLDriverConnect ();
   ;
   return 0;
 }
@@ -37771,51 +32270,37 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_odbc_SQLDriverConnect=yes
+  ol_cv_lib_icu=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_odbc_SQLDriverConnect=no
+ol_cv_lib_icu=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+		LIBS="$ol_LIBS"
+
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_odbc_SQLDriverConnect" >&5
-echo "${ECHO_T}$ac_cv_lib_odbc_SQLDriverConnect" >&6
-if test $ac_cv_lib_odbc_SQLDriverConnect = yes; then
-  have_odbc=yes
-else
-  have_odbc=no
-fi
+echo "$as_me:$LINENO: result: $ol_cv_lib_icu" >&5
+echo "${ECHO_T}$ol_cv_lib_icu" >&6
 
-				if test $have_odbc = yes ; then
-					ol_link_sql="-lodbc"
-				fi
-				;;
+	if test $ol_cv_lib_icu != no ; then
+		ol_icu="$OL_ICULIBS"
 
-			*)
-				{ { echo "$as_me:$LINENO: error: unknown ODBC library" >&5
-echo "$as_me: error: unknown ODBC library" >&2;}
-   { (exit 1); exit 1; }; }
-				;;
-			esac
-		fi
-	done
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ICU 1
+_ACEOF
 
-	LIBS="$sql_LIBS"
-
-	if test $ol_link_sql != no ; then
-		SLAPD_SQL_LIBS="$ol_link_sql"
-
-	elif test $ol_enable_sql != auto ; then
-		{ { echo "$as_me:$LINENO: error: could not locate suitable ODBC library" >&5
-echo "$as_me: error: could not locate suitable ODBC library" >&2;}
-   { (exit 1); exit 1; }; }
 	fi
 fi
 
+if test "$ol_icu" = no ; then
+	{ echo "$as_me:$LINENO: WARNING: ICU not available" >&5
+echo "$as_me: WARNING: ICU not available" >&2;}
+else
+	ICU_LIBS="$ol_icu"
+fi
 WITH_SASL=no
 ol_link_sasl=no
 ol_link_spasswd=no
@@ -44518,6 +39003,7 @@
 
 
 
+
 for ac_func in \
 	bcopy			\
 	closesocket		\
@@ -44527,17 +39013,18 @@
 	fcntl			\
 	flock			\
 	fstat			\
-	getdtablesize	\
+	getdtablesize		\
 	getgrgid		\
 	gethostname		\
 	getpass			\
-	getpassphrase	\
+	getpassphrase		\
 	getpwuid		\
 	getpwnam		\
 	getspnam		\
-	gettimeofday	\
+	gettimeofday		\
 	initgroups		\
 	inet_ntoa_b		\
+	ioctl			\
 	lockf			\
 	memcpy			\
 	memmove			\
@@ -44792,8 +39279,112 @@
 if test "$ac_cv_func_getopt" != yes; then
 	LIBSRCS="$LIBSRCS getopt.c"
 fi
+
 if test "$ac_cv_func_getpeereid" != yes; then
-	echo "$as_me:$LINENO: checking for struct msghdr.msg_accrightslen" >&5
+
+for ac_func in getpeerucred
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+	if test "$ac_cv_func_getpeerucred" != yes ; then
+		echo "$as_me:$LINENO: checking for struct msghdr.msg_accrightslen" >&5
 echo $ECHO_N "checking for struct msghdr.msg_accrightslen... $ECHO_C" >&6
 if test "${ac_cv_member_struct_msghdr_msg_accrightslen+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -44911,8 +39502,8 @@
 
 fi
 
-	if test "$ac_cv_member_struct_msghdr_msg_accrightslen" != yes; then
-		echo "$as_me:$LINENO: checking for struct msghdr.msg_control" >&5
+		if test "$ac_cv_member_struct_msghdr_msg_accrightslen" != yes; then
+			echo "$as_me:$LINENO: checking for struct msghdr.msg_control" >&5
 echo $ECHO_N "checking for struct msghdr.msg_control... $ECHO_C" >&6
 if test "${ac_cv_member_struct_msghdr_msg_control+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -45030,9 +39621,273 @@
 
 fi
 
+		fi
+		echo "$as_me:$LINENO: checking for struct stat.st_fstype" >&5
+echo $ECHO_N "checking for struct stat.st_fstype... $ECHO_C" >&6
+if test "${ac_cv_member_struct_stat_st_fstype+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_fstype)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_fstype=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_fstype)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_fstype=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_stat_st_fstype=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_fstype" >&5
+echo "${ECHO_T}$ac_cv_member_struct_stat_st_fstype" >&6
+if test $ac_cv_member_struct_stat_st_fstype = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_FSTYPE 1
+_ACEOF
+
+
+fi
+echo "$as_me:$LINENO: checking for struct stat.st_vfstype" >&5
+echo $ECHO_N "checking for struct stat.st_vfstype... $ECHO_C" >&6
+if test "${ac_cv_member_struct_stat_st_vfstype+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_vfstype)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_vfstype=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_vfstype)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_vfstype=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_stat_st_vfstype=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_vfstype" >&5
+echo "${ECHO_T}$ac_cv_member_struct_stat_st_vfstype" >&6
+if test $ac_cv_member_struct_stat_st_vfstype = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_VFSTYPE 1
+_ACEOF
+
+
+fi
+
+		if test "$ac_cv_member_struct_stat_st_fstype" = yes; then
+			cat >conftest.$ac_ext <<_ACEOF
+struct stat st; char *ptr=st.st_fstype;
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_STAT_ST_FSTYPE_CHAR 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_STAT_ST_FSTYPE_INT 1
+_ACEOF
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+		fi
 	fi
 	LIBSRCS="$LIBSRCS getpeereid.c"
 fi
+
 if test "$ac_cv_func_snprintf" != yes ||
    test "$ac_cv_func_vsnprintf" != yes; then
 	if test "$ac_cv_func_snprintf" != yes; then
@@ -45299,23 +40154,23 @@
 fi
 
 if test "$ol_enable_debug" != no ; then
+	if test "$ol_enable_debug" = traditional; then
 
 cat >>confdefs.h <<\_ACEOF
-#define LDAP_DEBUG 1
+#define OLD_DEBUG 1
 _ACEOF
 
-fi
-if test "$ol_enable_syslog" = yes ; then
+	fi
 
 cat >>confdefs.h <<\_ACEOF
-#define LDAP_SYSLOG 1
+#define LDAP_DEBUG 1
 _ACEOF
 
 fi
-if test "$ol_link_kbind" != no ; then
+if test "$ol_enable_syslog" = yes ; then
 
 cat >>confdefs.h <<\_ACEOF
-#define LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND LDAP_VENDOR_VERSION
+#define LDAP_SYSLOG 1
 _ACEOF
 
 fi
@@ -45368,13 +40223,6 @@
 _ACEOF
 
 fi
-if test "$ol_enable_multimaster" != no ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define SLAPD_MULTIMASTER 1
-_ACEOF
-
-fi
 if test "$ol_enable_rlookups" != no ; then
 
 cat >>confdefs.h <<\_ACEOF
@@ -45383,16 +40231,36 @@
 
 fi
 if test "$ol_enable_aci" != no ; then
+	if test $ol_enable_dynacl = no ; then
+		ol_enable_dynacl=yes
+		{ echo "$as_me:$LINENO: WARNING: ACIs need dynacl" >&5
+echo "$as_me: WARNING: ACIs need dynacl" >&2;}
+	fi
+	if test "$ol_enable_aci" = mod ; then
+		MFLAG=SLAPD_MOD_DYNAMIC
+				{ { echo "$as_me:$LINENO: error: ACI build as dynamic module not supported (yet)" >&5
+echo "$as_me: error: ACI build as dynamic module not supported (yet)" >&2;}
+   { (exit 1); exit 1; }; }
+	else
+		MFLAG=SLAPD_MOD_STATIC
+	fi
+	WITH_ACI_ENABLED=$ol_enable_aci
 
-cat >>confdefs.h <<\_ACEOF
-#define SLAPD_ACI_ENABLED 1
+cat >>confdefs.h <<_ACEOF
+#define SLAPD_ACI_ENABLED $MFLAG
 _ACEOF
 
-	WITH_ACI_ENABLED=yes
 else
 	WITH_ACI_ENABLED=no
 fi
+if test "$ol_enable_dynacl" != no ; then
 
+cat >>confdefs.h <<\_ACEOF
+#define SLAP_DYNACL 1
+_ACEOF
+
+fi
+
 if test "$ol_link_modules" != no ; then
 
 cat >>confdefs.h <<\_ACEOF
@@ -45414,6 +40282,23 @@
 _ACEOF
 
 
+if test "$ol_enable_monitor" != no ; then
+	BUILD_SLAPD=yes
+	BUILD_MONITOR=$ol_enable_monitor
+	if test "$ol_enable_monitor" = mod ; then
+		SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-monitor"
+		MFLAG=SLAPD_MOD_DYNAMIC
+	else
+		SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-monitor"
+		MFLAG=SLAPD_MOD_STATIC
+	fi
+
+cat >>confdefs.h <<_ACEOF
+#define SLAPD_MONITOR $MFLAG
+_ACEOF
+
+fi
+
 if test "$ol_enable_bdb" != no ; then
 	BUILD_SLAPD=yes
 	BUILD_BDB=$ol_enable_bdb
@@ -45482,23 +40367,6 @@
 
 fi
 
-if test "$ol_link_ldbm" != no && test $ol_enable_ldbm != no; then
-	BUILD_SLAPD=yes
-	BUILD_LDBM=$ol_enable_ldbm
-	if test "$ol_enable_ldbm" = mod ; then
-		SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-ldbm"
-		MFLAG=SLAPD_MOD_DYNAMIC
-	else
-		SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-ldbm"
-		MFLAG=SLAPD_MOD_STATIC
-	fi
-
-cat >>confdefs.h <<_ACEOF
-#define SLAPD_LDBM $MFLAG
-_ACEOF
-
-fi
-
 if test "$ol_enable_meta" != no ; then
 	BUILD_SLAPD=yes
 	BUILD_META=$ol_enable_meta
@@ -45517,23 +40385,6 @@
 
 fi
 
-if test "$ol_enable_monitor" != no ; then
-	BUILD_SLAPD=yes
-	BUILD_MONITOR=$ol_enable_monitor
-	if test "$ol_enable_monitor" = mod ; then
-		SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-monitor"
-		MFLAG=SLAPD_MOD_DYNAMIC
-	else
-		SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-monitor"
-		MFLAG=SLAPD_MOD_STATIC
-	fi
-
-cat >>confdefs.h <<_ACEOF
-#define SLAPD_MONITOR $MFLAG
-_ACEOF
-
-fi
-
 if test "$ol_enable_null" != no ; then
 	BUILD_SLAPD=yes
 	BUILD_NULL=$ol_enable_null
@@ -45672,22 +40523,38 @@
 
 fi
 
-if test "$ol_enable_denyop" != no ; then
-	BUILD_DENYOP=$ol_enable_denyop
-	if test "$ol_enable_denyop" = mod ; then
+if test "$ol_enable_constraint" != no ; then
+	BUILD_CONSTRAINT=$ol_enable_constraint
+	if test "$ol_enable_constraint" = mod ; then
 		MFLAG=SLAPD_MOD_DYNAMIC
-		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS denyop.la"
+		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS constraint.la"
 	else
 		MFLAG=SLAPD_MOD_STATIC
-		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS denyop.o"
+		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS constraint.o"
 	fi
 
 cat >>confdefs.h <<_ACEOF
-#define SLAPD_OVER_DENYOP $MFLAG
+#define SLAPD_OVER_CONSTRAINT $MFLAG
 _ACEOF
 
 fi
 
+if test "$ol_enable_dds" != no ; then
+	BUILD_DDS=$ol_enable_dds
+	if test "$ol_enable_dds" = mod ; then
+		MFLAG=SLAPD_MOD_DYNAMIC
+		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS dds.la"
+	else
+		MFLAG=SLAPD_MOD_STATIC
+		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS dds.o"
+	fi
+
+cat >>confdefs.h <<_ACEOF
+#define SLAPD_OVER_DDS $MFLAG
+_ACEOF
+
+fi
+
 if test "$ol_enable_dyngroup" != no ; then
 	BUILD_DYNGROUP=$ol_enable_dyngroup
 	if test "$ol_enable_dyngroup" = mod ; then
@@ -45720,18 +40587,18 @@
 
 fi
 
-if test "$ol_enable_lastmod" != no ; then
-	BUILD_LASTMOD=$ol_enable_lastmod
-	if test "$ol_enable_lastmod" = mod ; then
+if test "$ol_enable_memberof" != no ; then
+	BUILD_MEMBEROF=$ol_enable_memberof
+	if test "$ol_enable_memberof" = mod ; then
 		MFLAG=SLAPD_MOD_DYNAMIC
-		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS lastmod.la"
+		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS memberof.la"
 	else
 		MFLAG=SLAPD_MOD_STATIC
-		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS lastmod.o"
+		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS memberof.o"
 	fi
 
 cat >>confdefs.h <<_ACEOF
-#define SLAPD_OVER_LASTMOD $MFLAG
+#define SLAPD_OVER_MEMBEROF $MFLAG
 _ACEOF
 
 fi
@@ -45817,6 +40684,22 @@
 
 fi
 
+if test "$ol_enable_seqmod" != no ; then
+	BUILD_SEQMOD=$ol_enable_seqmod
+	if test "$ol_enable_seqmod" = mod ; then
+		MFLAG=SLAPD_MOD_DYNAMIC
+		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS seqmod.la"
+	else
+		MFLAG=SLAPD_MOD_STATIC
+		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS seqmod.o"
+	fi
+
+cat >>confdefs.h <<_ACEOF
+#define SLAPD_OVER_SEQMOD $MFLAG
+_ACEOF
+
+fi
+
 if test "$ol_enable_syncprov" != no ; then
 	BUILD_SYNCPROV=$ol_enable_syncprov
 	if test "$ol_enable_syncprov" = mod ; then
@@ -45881,12 +40764,6 @@
 
 fi
 
-if test "$ol_enable_slurpd" != no &&
-   test "$ol_link_threads" != no &&
-   test $BUILD_SLAPD = yes ; then
-	BUILD_SLURPD=yes
-fi
-
 if test "$ol_enable_rewrite" != no ; then
 
 cat >>confdefs.h <<\_ACEOF
@@ -45996,6 +40873,8 @@
 
 
 
+
+
 # Check whether --with-xxinstall or --without-xxinstall was given.
 if test "${with_xxinstall+set}" = set; then
   withval="$with_xxinstall"
@@ -46003,7 +40882,7 @@
 fi;
 
 
-                                                                                                                                                                                                                                                                                                                                                                                                                ac_config_files="$ac_config_files Makefile:build/top.mk:Makefile.in:build/dir.mk doc/Makefile:build/top.mk:doc/Makefile.in:build/dir.mk doc/man/Makefile:build/top.mk:doc/man/Makefile.in:build/dir.mk doc/man/man1/Makefile:build/top.mk:doc/man/man1/Makefile.in:build/man.mk doc/man/man3/Makefile:build/top.mk:doc/man/man3/Makefile.in:build/man.mk doc/man/man5/Makefile:build/top.mk:doc/man/man5/Makefile.in:build/man.mk doc/man/man8/Makefile:build/top.mk:doc/man/man8/Makefile.in:build/man.mk clients/Makefile:build/top.mk:clients/Makefile.in:build/dir.mk clients/tools/Makefile:build/top.mk:clients/tools/Makefile.in:build/rules.mk include/Makefile:build/top.mk:include/Makefile.in libraries/Makefile:build/top.mk:libraries/Makefile.in:build/dir.mk libraries/liblber/Makefile:build/top.mk:libraries/liblber/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap/Makefile:build/top.mk:libraries/libldap/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap_r/Makefile:build/top.mk:libraries/libldap_r/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/liblunicode/Makefile:build/top.mk:libraries/liblunicode/Makefile.in:build/lib.mk:build/lib-static.mk libraries/liblutil/Makefile:build/top.mk:libraries/liblutil/Makefile.in:build/lib.mk:build/lib-static.mk libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.mk servers/Makefile:build/top.mk:servers/Makefile.in:build/dir.mk servers/slapd/Makefile:build/top.mk:servers/slapd/Makefile.in:build/srv.mk servers/slapd/back-bdb/Makefile:build/top.mk:servers/slapd/back-bdb/Makefile.in:build/mod.mk servers/slapd/back-dnssrv/Makefile:build/top.mk:servers/slapd/back-dnssrv/Makefile.in:build/mod.mk servers/slapd/back-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/Makefile.in:build/mod.mk servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/mod.mk servers/slapd/back-ldbm/Makefile:build/top.mk:servers/slapd/back-ldbm/Makefile.in:build/mod.mk servers/slapd/back-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/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-relay/Makefile:build/top.mk:servers/slapd/back-relay/Makefile.in:build/mod.mk servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk servers/slapd/back-sql/Makefile:build/top.mk:servers/slapd/back-sql/Makefile.in:build/mod.mk servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk servers/slapd/overlays/Makefile:build/top.mk:servers/slapd/overlays/Makefile.in:build/lib.mk servers/slurpd/Makefile:build/top.mk:servers/slurpd/Makefile.in:build/srv.mk tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk tests/run tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk"
+                                                                                                                                                                                                                                                                                                                                                                                            ac_config_files="$ac_config_files Makefile:build/top.mk:Makefile.in:build/dir.mk doc/Makefile:build/top.mk:doc/Makefile.in:build/dir.mk doc/man/Makefile:build/top.mk:doc/man/Makefile.in:build/dir.mk doc/man/man1/Makefile:build/top.mk:doc/man/man1/Makefile.in:build/man.mk doc/man/man3/Makefile:build/top.mk:doc/man/man3/Makefile.in:build/man.mk doc/man/man5/Makefile:build/top.mk:doc/man/man5/Makefile.in:build/man.mk doc/man/man8/Makefile:build/top.mk:doc/man/man8/Makefile.in:build/man.mk clients/Makefile:build/top.mk:clients/Makefile.in:build/dir.mk clients/tools/Makefile:build/top.mk:clients/tools/Makefile.in:build/rules.mk include/Makefile:build/top.mk:include/Makefile.in libraries/Makefile:build/top.mk:libraries/Makefile.in:build/dir.mk libraries/liblber/Makefile:build/top.mk:libraries/liblber/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap/Makefile:build/top.mk:libraries/libldap/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap_r/Makefile:build/top.mk:libraries/libldap_r/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/liblunicode/Makefile:build/top.mk:libraries/liblunicode/Makefile.in:build/lib.mk:build/lib-static.mk libraries/liblutil/Makefile:build/top.mk:libraries/liblutil/Makefile.in:build/lib.mk:build/lib-static.mk libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.mk servers/Makefile:build/top.mk:servers/Makefile.in:build/dir.mk servers/slapd/Makefile:build/top.mk:servers/slapd/Makefile.in:build/srv.mk servers/slapd/back-bdb/Makefile:build/top.mk:servers/slapd/back-bdb/Makefile.in:build/mod.mk servers/slapd/back-dnssrv/Makefile:build/top.mk:servers/slapd/back-dnssrv/Makefile.in:build/mod.mk servers/slapd/back-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/Makefile.in:build/mod.mk servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/mod.mk servers/slapd/back-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/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-relay/Makefile:build/top.mk:servers/slapd/back-relay/Makefile.in:build/mod.mk servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk servers/slapd/back-sql/Makefile:build/top.mk:servers/slapd/back-sql/Makefile.in:build/mod.mk servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk servers/slapd/overlays/Makefile:build/top.mk:servers/slapd/overlays/Makefile.in:build/lib.mk tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk tests/run tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk"
 
 
           ac_config_commands="$ac_config_commands default"
@@ -46538,7 +41417,6 @@
   "servers/slapd/back-dnssrv/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/back-dnssrv/Makefile:build/top.mk:servers/slapd/back-dnssrv/Makefile.in:build/mod.mk" ;;
   "servers/slapd/back-hdb/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/back-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/Makefile.in:build/mod.mk" ;;
   "servers/slapd/back-ldap/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/mod.mk" ;;
-  "servers/slapd/back-ldbm/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/back-ldbm/Makefile:build/top.mk:servers/slapd/back-ldbm/Makefile.in:build/mod.mk" ;;
   "servers/slapd/back-ldif/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/back-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk" ;;
   "servers/slapd/back-meta/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/back-meta/Makefile:build/top.mk:servers/slapd/back-meta/Makefile.in:build/mod.mk" ;;
   "servers/slapd/back-monitor/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/back-monitor/Makefile:build/top.mk:servers/slapd/back-monitor/Makefile.in:build/mod.mk" ;;
@@ -46551,7 +41429,6 @@
   "servers/slapd/shell-backends/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk" ;;
   "servers/slapd/slapi/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk" ;;
   "servers/slapd/overlays/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slapd/overlays/Makefile:build/top.mk:servers/slapd/overlays/Makefile.in:build/lib.mk" ;;
-  "servers/slurpd/Makefile" ) CONFIG_FILES="$CONFIG_FILES servers/slurpd/Makefile:build/top.mk:servers/slurpd/Makefile.in:build/srv.mk" ;;
   "tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk" ;;
   "tests/run" ) CONFIG_FILES="$CONFIG_FILES tests/run" ;;
   "tests/progs/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk" ;;
@@ -46735,7 +41612,6 @@
 s, at BUILD_DNSSRV@,$BUILD_DNSSRV,;t t
 s, at BUILD_HDB@,$BUILD_HDB,;t t
 s, at BUILD_LDAP@,$BUILD_LDAP,;t t
-s, at BUILD_LDBM@,$BUILD_LDBM,;t t
 s, at BUILD_META@,$BUILD_META,;t t
 s, at BUILD_MONITOR@,$BUILD_MONITOR,;t t
 s, at BUILD_NULL@,$BUILD_NULL,;t t
@@ -46746,24 +41622,26 @@
 s, at BUILD_SQL@,$BUILD_SQL,;t t
 s, at BUILD_ACCESSLOG@,$BUILD_ACCESSLOG,;t t
 s, at BUILD_AUDITLOG@,$BUILD_AUDITLOG,;t t
+s, at BUILD_CONSTRAINT@,$BUILD_CONSTRAINT,;t t
+s, at BUILD_DDS@,$BUILD_DDS,;t t
 s, at BUILD_DENYOP@,$BUILD_DENYOP,;t t
 s, at BUILD_DYNGROUP@,$BUILD_DYNGROUP,;t t
 s, at BUILD_DYNLIST@,$BUILD_DYNLIST,;t t
 s, at BUILD_LASTMOD@,$BUILD_LASTMOD,;t t
+s, at BUILD_MEMBEROF@,$BUILD_MEMBEROF,;t t
 s, at BUILD_PPOLICY@,$BUILD_PPOLICY,;t t
 s, at BUILD_PROXYCACHE@,$BUILD_PROXYCACHE,;t t
 s, at BUILD_REFINT@,$BUILD_REFINT,;t t
 s, at BUILD_RETCODE@,$BUILD_RETCODE,;t t
 s, at BUILD_RWM@,$BUILD_RWM,;t t
+s, at BUILD_SEQMOD@,$BUILD_SEQMOD,;t t
 s, at BUILD_SYNCPROV@,$BUILD_SYNCPROV,;t t
 s, at BUILD_TRANSLUCENT@,$BUILD_TRANSLUCENT,;t t
 s, at BUILD_UNIQUE@,$BUILD_UNIQUE,;t t
 s, at BUILD_VALSORT@,$BUILD_VALSORT,;t t
-s, at BUILD_SLURPD@,$BUILD_SLURPD,;t t
 s, at LDAP_LIBS@,$LDAP_LIBS,;t t
 s, at SLAPD_LIBS@,$SLAPD_LIBS,;t t
-s, at SLURPD_LIBS@,$SLURPD_LIBS,;t t
-s, at LDBM_LIBS@,$LDBM_LIBS,;t t
+s, at BDB_LIBS@,$BDB_LIBS,;t t
 s, at LTHREAD_LIBS@,$LTHREAD_LIBS,;t t
 s, at LUTIL_LIBS@,$LUTIL_LIBS,;t t
 s, at WRAP_LIBS@,$WRAP_LIBS,;t t
@@ -46786,6 +41664,7 @@
 s, at LIBSLAPI@,$LIBSLAPI,;t t
 s, at LIBSLAPITOOLS@,$LIBSLAPITOOLS,;t t
 s, at AUTH_LIBS@,$AUTH_LIBS,;t t
+s, at ICU_LIBS@,$ICU_LIBS,;t t
 s, at SLAPD_SLP_LIBS@,$SLAPD_SLP_LIBS,;t t
 s, at SLAPD_GMP_LIBS@,$SLAPD_GMP_LIBS,;t t
 s, at SLAPD_SQL_LDFLAGS@,$SLAPD_SQL_LDFLAGS,;t t
@@ -47582,7 +42461,11 @@
 /* end of generated file */
 ENDX
 
-echo Please run \"make depend\" to build dependencies
+if test "${ol_cv_mkdep}" = no; then
+	echo '(Do not "make depend"; we do not know how to build dependencies)'
+else
+	echo 'Please run "make depend" to build dependencies'
+fi
  ;;
   esac
 done

Modified: openldap/trunk/configure.in
===================================================================
--- openldap/trunk/configure.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/configure.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-dnl $OpenLDAP: pkg/ldap/configure.in,v 1.560.2.33 2007/06/10 18:39:53 hallvard Exp $
+dnl $OpenLDAP: pkg/ldap/configure.in,v 1.631.2.7 2007/10/16 23:43:09 quanah Exp $
 dnl This work is part of OpenLDAP Software <http://www.openldap.org/>.
 dnl
 dnl Copyright 1998-2007 The OpenLDAP Foundation.
@@ -25,7 +25,7 @@
 dnl Configure.in for OpenLDAP
 AC_COPYRIGHT([[Copyright 1998-2007 The OpenLDAP Foundation. All rights reserved.
 Restrictions apply, see COPYRIGHT and LICENSE files.]])
-AC_REVISION([$OpenLDAP: pkg/ldap/configure.in,v 1.560.2.33 2007/06/10 18:39:53 hallvard Exp $])
+AC_REVISION([$OpenLDAP: pkg/ldap/configure.in,v 1.631.2.7 2007/10/16 23:43:09 quanah Exp $])
 AC_INIT([OpenLDAP],,[http://www.openldap.org/its/])
 m4_define([AC_PACKAGE_BUGREPORT],[<http://www.openldap.org/its/>])
 AC_CONFIG_SRCDIR(build/version.sh)dnl
@@ -50,8 +50,11 @@
 SHTOOL="$ac_cv_shtool"
 dnl AC_SUBST(SHTOOL)dnl
 
-TB="`$SHTOOL echo -e '%B' 2>/dev/null`"
-TN="`$SHTOOL echo -e '%b' 2>/dev/null`"
+TB="" TN=""
+if test -t 1; then
+	TB="`$SHTOOL echo -e '%B' 2>/dev/null`"
+	TN="`$SHTOOL echo -e '%b' 2>/dev/null`"
+fi
 
 OPENLDAP_CVS=""
 if test -d $ac_aux_dir/CVS; then
@@ -223,14 +226,13 @@
 
 dnl ----------------------------------------------------------------
 dnl General "enable" options
-OL_ARG_ENABLE(debug,[  --enable-debug 	  enable debugging], yes)dnl
+dnl set default to traditional to enable the original debug style
+OL_ARG_ENABLE(debug,[  --enable-debug 	  enable debugging], yes, [no yes traditional])dnl
 OL_ARG_ENABLE(dynamic,[  --enable-dynamic	  enable linking built binaries with dynamic libs], no)dnl
 OL_ARG_ENABLE(syslog,[  --enable-syslog	  enable syslog support], auto)dnl
 OL_ARG_ENABLE(proctitle,[  --enable-proctitle	  enable proctitle support], yes)dnl
 dnl OL_ARG_ENABLE(referrals,[  --enable-referrals	  enable LDAPv2+ Referrals (experimental)], no)dnl
 ol_enable_referrals=${ol_enable_referrals-no}
-dnl OL_ARG_ENABLE(kbind,[  --enable-kbind	  enable LDAPv2+ Kerberos IV bind (deprecated)], no)dnl
-ol_enable_kbind=${ol_enable_kbind-no}
 OL_ARG_ENABLE(ipv6,[  --enable-ipv6 	  enable IPv6 support], auto)dnl
 OL_ARG_ENABLE(local,[  --enable-local	  enable AF_LOCAL (AF_UNIX) socket support], auto)dnl
 
@@ -240,13 +242,10 @@
 	auto, [auto yes no] )
 OL_ARG_WITH(fetch,[  --with-fetch		  with fetch(3) URL support],
 	auto, [auto yes no] )
-dnl	OL_ARG_WITH(kerberos,[  --with-kerberos	  with Kerberos support],
-dnl		auto, [auto k5 k5only k425 kth k4 afs yes no])
-ol_with_kerberos=${ol_with_kerberos-auto}
 OL_ARG_WITH(threads,[  --with-threads	  with threads],
 	auto, [auto nt posix mach pth lwp yes no manual] )
-OL_ARG_WITH(tls,[  --with-tls		  with TLS/SSL support],
-	auto, [auto openssl yes no] )
+OL_ARG_WITH(tls,[  --with-tls		  with TLS/SSL support auto|openssl|gnutls],
+	auto, [auto openssl gnutls yes no] )
 OL_ARG_WITH(yielding_select,
 	[  --with-yielding-select  with implicitly yielding select],
 	auto, [auto yes no manual] )
@@ -266,14 +265,13 @@
 AC_ARG_ENABLE(xxslapdoptions,[
 SLAPD (Standalone LDAP Daemon) Options:])
 OL_ARG_ENABLE(slapd,[  --enable-slapd	  enable building slapd], yes)dnl
-OL_ARG_ENABLE(aci,[    --enable-aci	  enable per-object ACIs (experimental)], no)dnl
+OL_ARG_ENABLE(dynacl,[    --enable-dynacl	  enable run-time loadable ACL support (experimental)], no)dnl
+OL_ARG_ENABLE(aci,[    --enable-aci	  enable per-object ACIs (experimental)], no, [no yes mod])dnl
 OL_ARG_ENABLE(cleartext,[    --enable-cleartext	  enable cleartext passwords], yes)dnl
 OL_ARG_ENABLE(crypt,[    --enable-crypt	  enable crypt(3) passwords], no)dnl
 OL_ARG_ENABLE(lmpasswd,[    --enable-lmpasswd	  enable LAN Manager passwords], no)dnl
 OL_ARG_ENABLE(spasswd,[    --enable-spasswd	  enable (Cyrus) SASL password verification], no)dnl
 OL_ARG_ENABLE(modules,[    --enable-modules	  enable dynamic module support], no)dnl
-dnl OL_ARG_ENABLE(multimaster,[    --enable-multimaster  enable multimaster replication], no)dnl
-ol_enable_multimaster=${ol_enable_multimaster-no}
 OL_ARG_ENABLE(rewrite,[    --enable-rewrite	  enable DN rewriting in back-ldap and rwm overlay], auto)dnl
 OL_ARG_ENABLE(rlookups,[    --enable-rlookups	  enable reverse lookups of client hostnames], no)dnl
 OL_ARG_ENABLE(slapi,[    --enable-slapi        enable SLAPI support (experimental)], no)dnl
@@ -286,7 +284,6 @@
 	dnssrv \
 	hdb \
 	ldap \
-	ldbm \
 	meta \
 	monitor \
 	null \
@@ -309,18 +306,6 @@
 	yes, [no yes mod], ol_enable_backends)dnl
 OL_ARG_ENABLE(ldap,[    --enable-ldap	  enable ldap backend],
 	no, [no yes mod], ol_enable_backends)dnl
-OL_ARG_ENABLE(ldbm,[    --enable-ldbm	  enable ldbm backend],
-	no, [no yes mod], ol_enable_backends)dnl
-AC_ARG_WITH(ldbm_api,,[
-	AC_MSG_WARN([Please use --enable-ldbm-api instead of --with-ldbm-api])
-	enable_ldbm_api="$with_ldbm_api"])
-OL_ARG_ENABLE(ldbm_api,[      --enable-ldbm-api   use LDBM API],
-	auto, [auto berkeley bcompat mdbm gdbm])
-AC_ARG_WITH(ldbm_type,,[
-	AC_MSG_WARN([Please use --enable-ldbm-type instead of --with-ldbm-type])
-	enable_ldbm_type="$with_ldbm_type"])
-OL_ARG_ENABLE(ldbm_type,[      --enable-ldbm-type  use LDBM type],
-	auto, [auto btree hash])
 OL_ARG_ENABLE(meta,[    --enable-meta	  enable metadirectory backend],
 	no, [no yes mod], ol_enable_backends)dnl
 OL_ARG_ENABLE(monitor,[    --enable-monitor	  enable monitor backend],
@@ -342,15 +327,17 @@
 dnl SLAPD Overlay Options
 Overlays="accesslog \
 	auditlog \
-	denyop \
+	constraint \
+	dds \
 	dyngroup \
 	dynlist \
-	lastmod \
+	memberof \
 	ppolicy \
 	proxycache \
 	refint \
 	retcode \
 	rwm \
+	seqmod \
 	syncprov \
 	translucent \
 	unique \
@@ -365,13 +352,15 @@
 	no, [no yes mod], ol_enable_overlays)
 OL_ARG_ENABLE(auditlog,[    --enable-auditlog	  Audit Logging overlay],
 	no, [no yes mod], ol_enable_overlays)
-OL_ARG_ENABLE(denyop,[    --enable-denyop  	  Deny Operation overlay],
+OL_ARG_ENABLE(constraint,[    --enable-constraint	  Attribute Constraint overlay],
 	no, [no yes mod], ol_enable_overlays)
+OL_ARG_ENABLE(dds,[    --enable-dds  	  Dynamic Directory Services overlay],
+	no, [no yes mod], ol_enable_overlays)
 OL_ARG_ENABLE(dyngroup,[    --enable-dyngroup	  Dynamic Group overlay],
 	no, [no yes mod], ol_enable_overlays)
 OL_ARG_ENABLE(dynlist,[    --enable-dynlist	  Dynamic List overlay],
 	no, [no yes mod], ol_enable_overlays)
-OL_ARG_ENABLE(lastmod,[    --enable-lastmod	  Last Modification overlay],
+OL_ARG_ENABLE(memberof,[    --enable-memberof	  Reverse Group Membership overlay],
 	no, [no yes mod], ol_enable_overlays)
 OL_ARG_ENABLE(ppolicy,[    --enable-ppolicy	  Password Policy overlay],
 	no, [no yes mod], ol_enable_overlays)
@@ -383,6 +372,8 @@
 	no, [no yes mod], ol_enable_overlays)
 OL_ARG_ENABLE(rwm,[    --enable-rwm       	  Rewrite/Remap overlay],
 	no, [no yes mod], ol_enable_overlays)
+OL_ARG_ENABLE(seqmod,[    --enable-seqmod	  Sequential Modify overlay],
+	yes, [no yes mod], ol_enable_overlays)
 OL_ARG_ENABLE(syncprov,[    --enable-syncprov	  Syncrepl Provider overlay],
 	yes, [no yes mod], ol_enable_overlays)
 OL_ARG_ENABLE(translucent,[    --enable-translucent  Translucent Proxy overlay],
@@ -393,12 +384,6 @@
 	no, [no yes mod], ol_enable_overlays)
 
 dnl ----------------------------------------------------------------
-dnl SLURPD OPTIONS
-AC_ARG_ENABLE(xxslurpdoptions,[
-SLURPD (Replication Daemon) Options:])
-OL_ARG_ENABLE(slurpd,[  --enable-slurpd	  enable building slurpd], auto)dnl
-
-dnl ----------------------------------------------------------------
 AC_ARG_ENABLE(xxliboptions,[
 Library Generation & Linking Options])
 AC_ENABLE_STATIC
@@ -425,27 +410,18 @@
 	if test $ol_enable_modules = yes ; then
 		AC_MSG_WARN([slapd disabled, ignoring --enable-modules argument])
 	fi
-	if test $ol_enable_multimaster = yes ; then
-		AC_MSG_WARN([slapd disabled, ignoring --enable-multimaster argument])
-	fi
 	if test $ol_enable_wrappers = yes ; then
 		AC_MSG_WARN([slapd disabled, ignoring --enable-wrappers argument])
 	fi
 	if test $ol_enable_rlookups = yes ; then
 		AC_MSG_WARN([slapd disabled, ignoring --enable-rlookups argument])
 	fi
-	if test $ol_enable_aci = yes ; then
+	if test $ol_enable_dynacl = yes ; then
+		AC_MSG_WARN([slapd disabled, ignoring --enable-dynacl argument])
+	fi
+	if test $ol_enable_aci != no ; then
 		AC_MSG_WARN([slapd disabled, ignoring --enable-aci argument])
 	fi
-	if test $ol_enable_ldbm_api != auto ; then
-		AC_MSG_WARN([slapd disabled, ignoring --enable-ldbm-api argument])
-	fi
-	if test $ol_enable_ldbm_type != auto ; then
-		AC_MSG_WARN([slapd disabled, ignoring --enable-ldbm-type argument])
-	fi
-	if test $ol_enable_slurpd = yes ; then
-		AC_MSG_ERROR([slurpd requires slapd])
-	fi
 	if test $ol_enable_rewrite = yes ; then
 		AC_MSG_WARN([slapd disabled, ignoring --enable-rewrite argument])
 	fi
@@ -467,115 +443,46 @@
 	ol_enable_backends=
 	ol_enable_overlays=
 	ol_enable_modules=no
-	ol_enable_multimaster=no
 	ol_enable_rlookups=no
+	ol_enable_dynacl=no
 	ol_enable_aci=no
 	ol_enable_wrappers=no
 
-	ol_enable_ldbm_api=no
-	ol_enable_ldbm_type=no
-
-	ol_enable_slurpd=no
-
 	ol_enable_rewrite=no
 
-elif test $ol_enable_ldbm = no ; then
-	dnl SLAPD without LDBM
+elif test $ol_enable_modules != yes &&
+	test $ol_enable_bdb = no &&
+	test $ol_enable_dnssrv = no &&
+	test $ol_enable_hdb = no &&
+	test $ol_enable_ldap = no &&
+	test $ol_enable_meta = no &&
+	test $ol_enable_monitor = no &&
+	test $ol_enable_null = no &&
+	test $ol_enable_passwd = no &&
+	test $ol_enable_perl = no &&
+	test $ol_enable_relay = no &&
+	test $ol_enable_shell = no &&
+	test $ol_enable_sql = no ; then
+	dnl no slapd backend
 
-	if test $ol_enable_ldbm_api != auto ; then
-		AC_MSG_WARN([LDBM disabled, ignoring --enable-ldbm-api argument])
+	if test $ol_enable_slapd = yes ; then
+		AC_MSG_ERROR([slapd requires a backend])
+	else
+		AC_MSG_WARN([skipping slapd, no backend specified])
+		ol_enable_slapd=no
 	fi
-
-	if test $ol_enable_ldbm_type != auto ; then
-		AC_MSG_WARN([LDBM disabled, ignoring --enable-ldbm-type argument])
-	fi
-
-	if test $ol_enable_modules != yes &&
-	   test $ol_enable_bdb = no &&
-	   test $ol_enable_dnssrv = no &&
-	   test $ol_enable_hdb = no &&
-	   test $ol_enable_ldap = no &&
-	   test $ol_enable_meta = no &&
-	   test $ol_enable_monitor = no &&
-	   test $ol_enable_null = no &&
-	   test $ol_enable_passwd = no &&
-	   test $ol_enable_perl = no &&
-	   test $ol_enable_relay = no &&
-	   test $ol_enable_shell = no &&
-	   test $ol_enable_sql = no ; then
-
-		if test $ol_enable_slapd = yes ; then
-			AC_MSG_ERROR([slapd requires a backend])
-		else
-			AC_MSG_WARN([skipping slapd, no backend specified])
-			ol_enable_slapd=no
-		fi
-	fi
-
-	ol_enable_ldbm_api=no
-	ol_enable_ldbm_type=no
-
-	if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
-		ol_enable_ldbm_api=berkeley
-	fi
-
-else
-	dnl SLAPD with LDBM
-	if test $ol_enable_ldbm_api = gdbm &&
-	   test $ol_enable_ldbm_type = btree ; then
-		AC_MSG_ERROR([GDBM only supports LDBM type hash])
-	fi
-	if test $ol_enable_ldbm_api = mdbm &&
-	   test $ol_enable_ldbm_type = btree ; then
-		AC_MSG_ERROR([MDBM only supports LDBM type hash])
-	fi
-	if test $ol_enable_ldbm_api = ndbm &&
-	   test $ol_enable_ldbm_type = btree ; then
-		AC_MSG_ERROR([NDBM only supports LDBM type hash])
-	fi
-
-	if test $ol_enable_bdb/$ol_enable_hdb != no/no ; then
-		if test $ol_enable_ldbm_api = auto ; then
-			ol_enable_ldbm_api=berkeley
-		elif test $ol_enable_ldbm_api != berkeley ; then
-			AC_MSG_ERROR([LDBM API not compatible with BDB/HDB])
-		fi
-	fi
 fi
 
 if test $ol_enable_meta/$ol_enable_ldap = yes/no ; then
 	AC_MSG_ERROR([--enable-meta requires --enable-ldap])
 fi
 
-if test $ol_enable_slurpd = yes ; then
-	dnl SLURPD was specifically enabled
-	if test $ol_with_threads = no ; then
-		AC_MSG_ERROR([slurpd requires threads])
-	fi
-fi
-
 if test $ol_enable_lmpasswd = yes ; then
 	if test $ol_with_tls = no ; then
 		AC_MSG_ERROR([LAN Manager passwords require OpenSSL])
 	fi
 fi
 
-if test $ol_enable_kbind = yes ; then
-	if test $ol_with_kerberos = no ; then
-		AC_MSG_ERROR([options require --with-kerberos])
-	elif test $ol_with_kerberos = auto ; then
-		ol_with_kerberos=yes
-	fi
-
-elif test $ol_enable_kbind = no ; then
-	if test $ol_with_kerberos = auto ; then
-		ol_with_kerberos=no
-	elif test $ol_with_kerberos != no ; then
-		AC_MSG_WARN([Kerberos detection enabled unnecessarily]);
-		ol_with_kerberos=no
-	fi
-fi
-
 if test $ol_enable_spasswd = yes ; then
 	if test $ol_with_cyrus_sasl = no ; then
 		AC_MSG_ERROR([options require --with-cyrus-sasl])
@@ -588,15 +495,13 @@
 dnl ----------------------------------------------------------------
 dnl Initialize vars
 LDAP_LIBS=
-LDBM_LIBS=
+BDB_LIBS=
 LTHREAD_LIBS=
 LUTIL_LIBS=
 
 SLAPD_LIBS=
-SLURPD_LIBS=
 
 BUILD_SLAPD=no
-BUILD_SLURPD=no
 
 BUILD_THREAD=no
 
@@ -607,7 +512,6 @@
 BUILD_DNSSRV=no
 BUILD_HDB=no
 BUILD_LDAP=no
-BUILD_LDBM=no
 BUILD_META=no
 BUILD_MONITOR=no
 BUILD_NULL=no
@@ -619,15 +523,19 @@
 
 BUILD_ACCESSLOG=no
 BUILD_AUDITLOG=no
+BUILD_CONSTRAINT=no
+BUILD_DDS=no
 BUILD_DENYOP=no
 BUILD_DYNGROUP=no
 BUILD_DYNLIST=no
 BUILD_LASTMOD=no
+BUILD_MEMBEROF=no
 BUILD_PPOLICY=no
 BUILD_PROXYCACHE=no
 BUILD_REFINT=no
 BUILD_RETCODE=no
 BUILD_RWM=no
+BUILD_SEQMOD=no
 BUILD_SYNCPROV=no
 BUILD_TRANSLUCENT=no
 BUILD_UNIQUE=no
@@ -659,6 +567,7 @@
 LIBSLAPI=
 LIBSLAPITOOLS=
 AUTH_LIBS=
+ICU_LIBS=
 
 SLAPD_SLP_LIBS=
 SLAPD_GMP_LIBS=
@@ -891,9 +800,11 @@
 	sysexits.h		\
 	sys/file.h		\
 	sys/filio.h		\
+	sys/fstyp.h		\
 	sys/errno.h		\
 	sys/ioctl.h		\
 	sys/param.h		\
+	sys/privgrp.h	\
 	sys/resource.h	\
 	sys/select.h	\
 	sys/socket.h	\
@@ -902,6 +813,7 @@
 	sys/time.h		\
 	sys/types.h		\
 	sys/uio.h		\
+	sys/vmount.h	\
 	syslog.h		\
 	termios.h		\
 	unistd.h		\
@@ -1004,27 +916,50 @@
 
 dnl ----------------------------------------------------------------
 AC_CHECK_FUNCS( poll )
-AC_CHECK_HEADERS( poll.h )
+if test $ac_cv_func_poll = yes; then
+AC_CHECK_HEADERS( poll.h sys/poll.h )
+fi
 
 dnl ----------------------------------------------------------------
 AC_CHECK_HEADERS( sys/epoll.h )
 if test "${ac_cv_header_sys_epoll_h}" = yes; then
-AC_MSG_CHECKING(for epoll system call)
-AC_RUN_IFELSE([AC_LANG_SOURCE([[int main(int argc, char *argv)
+	AC_MSG_CHECKING(for epoll system call)
+	AC_RUN_IFELSE([AC_LANG_SOURCE([[int main(int argc, char **argv)
 {
 	int epfd = epoll_create(256);
 	exit (epfd == -1 ? 1 : 0);
 }]])],[AC_MSG_RESULT(yes)
-AC_DEFINE(HAVE_EPOLL,1, [define if your system supports epoll])],[AC_MSG_RESULT(no)],[AC_MSG_RESULT(no)])
+	AC_DEFINE(HAVE_EPOLL,1, [define if your system supports epoll])],[AC_MSG_RESULT(no)],[AC_MSG_RESULT(no)])
 fi
 
 dnl ----------------------------------------------------------------
+AC_CHECK_HEADERS( sys/devpoll.h )
+dnl "/dev/poll" needs <sys/poll.h> as well...
+if test "${ac_cv_header_sys_devpoll_h}" = yes \
+		-a "${ac_cv_header_poll_h}" = yes ; \
+then
+	AC_MSG_CHECKING(for /dev/poll)
+	AC_RUN_IFELSE([AC_LANG_SOURCE([[int main(int argc, char **argv)
+{
+	int devpollfd = open("/dev/poll", /* O_RDWR */ 2);
+	exit (devpollfd == -1 ? 1 : 0);
+}]])],[AC_MSG_RESULT(yes)
+	AC_DEFINE(HAVE_DEVPOLL,1, [define if your system supports /dev/poll])],[AC_MSG_RESULT(no)],[AC_MSG_RESULT(no)])
+fi
+
+dnl ----------------------------------------------------------------
 # strerror checks
 OL_STRERROR
 
 dnl ----------------------------------------------------------------
 dnl require POSIX regex
-AC_CHECK_HEADERS( regex.h )
+AC_CHECK_HEADERS( regex.h, [], [],
+[$ac_includes_default
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+])
+
 if test "$ac_cv_header_regex_h" != yes ; then
 	AC_MSG_ERROR([POSIX regex.h required.])
 fi
@@ -1043,7 +978,7 @@
 AC_CHECK_HEADERS(sys/uuid.h)
 if test $ac_cv_header_sys_uuid_h = yes ; then
 	save_LIBS="$LIBS"
-	AC_SEARCH_LIBS(uuid_to_str, uuid, [have_uuid=yes], :)
+	AC_SEARCH_LIBS([uuid_to_str], [uuid], [have_uuid=yes], :)
 	LIBS="$save_LIBS"
 
 	if test have_uuid = yes ; then
@@ -1055,6 +990,24 @@
 	fi
 fi
 
+dnl Look for uuid_generate
+if test $have_uuid = no ; then
+	AC_CHECK_HEADERS(uuid/uuid.h)
+	if test $ac_cv_header_uuid_uuid_h = yes ; then
+		save_LIBS="$LIBS"
+		AC_SEARCH_LIBS([uuid_generate], [uuid], [have_uuid=yes], :)
+		LIBS="$save_LIBS"
+
+		if test have_uuid = yes ; then
+			AC_DEFINE(HAVE_UUID_GENERATE,1,
+				[define if you have uuid_generate()])
+
+			test "$ac_cv_search_uuid_generate" = "none required" || \
+				SLAPD_LIBS="$SLAPD_LIBS $ac_cv_search_uuid_generate"
+		fi
+	fi
+fi
+
 dnl For windows, check for the need of RPCRT for UUID function support
 if test $have_uuid = no ; then
 	AC_MSG_CHECKING(to see if -lrpcrt4 is needed for win32 UUID support)
@@ -1153,178 +1106,14 @@
 fi
 
 dnl ----------------------------------------------------------------
-dnl Kerberos
-ol_link_kbind=no
-ol_link_krb5=no
-ol_link_krb4=no
-
-case $ol_with_kerberos in yes | auto | k5 | k5only | k425)
-
-	AC_CHECK_HEADERS(krb5.h)
-
-	if test $ac_cv_header_krb5_h = yes ; then
-		dnl lazy check for Heimdal Kerberos
-		AC_CHECK_HEADERS(heim_err.h)
-		if test $ac_cv_header_heim_err_h = yes ; then
-			krb5_impl=heimdal
-		else
-			krb5_impl=mit
-		fi
-
-		if test $krb5_impl = mit; then
-			AC_CHECK_LIB(k5crypto, main,
-				[krb5crypto=k5crypto],
-				[krb5crypto=crypto])
-
-			AC_CHECK_LIB(krb5, main,
-				[have_krb5=yes
-				KRB5_LIBS="-lkrb5 -l$krb5crypto -lcom_err"],
-				[have_krb5=no],
-				[-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 -l$krb5crypto -lasn1 -lroken -lcom_err"],
-				[have_krb5=no],
-				[-l$krb5crypto -lasn1 -lroken -lcom_err])
-
-			AC_DEFINE(HAVE_HEIMDAL_KERBEROS, 1,
-				[define if you have HEIMDAL Kerberos])
-
-		else
-			have_krb5=no
-			AC_MSG_WARN([Unrecognized Kerberos5 Implementation])
-		fi
-
-		if test $have_krb5 = yes ; then
-			ol_link_krb5=yes
-
-			AC_DEFINE(HAVE_KRB5, 1,
-				[define if you have Kerberos V])
-
-			if test $ol_with_kerberos = k5only ; then
-				ol_with_kerberos=found
-			fi
-
-		elif test $ol_with_kerberos != auto ; then
-			AC_MSG_ERROR([Required Kerberos 5 support not available])
-		fi
-
-	fi
-	;;
-esac
-
-if test $ol_link_krb5 = yes &&
-   { test $ol_with_kerberos = yes ||
-     test $ol_with_kerberos = auto ||
-     test $ol_with_kerberos = k425; }; then
-
-	AC_CHECK_HEADERS(kerberosIV/krb.h kerberosIV/des.h)
-
-	if test $ac_cv_header_kerberosIV_krb_h = yes ; then
-		if test $krb5_impl = mit; then
-			AC_CHECK_LIB(krb4, main, [have_k425=yes
-				KRB4_LIBS="-lkrb4 -ldes425"], [have_k425=no],
-				[-ldes425 -lkrb5 -l$krb5crypto -lcom_err])
-
-		elif test $krb5_impl = heimdal; then
-			AC_CHECK_LIB(krb4, main, [have_k425=yes
-				KRB4_LIBS="-lkrb4"], [have_k425=no],
-				[-lkrb5 -l$krb5crypto -lasn1 -lroken -lcom_err])
-
-		else
-			have_425=no
-			AC_MSG_WARN([Unrecongized Kerberos V Implementation])
-		fi
-
-		if test $have_k425 = yes ; then
-			ol_with_kerberos=found
-			ol_link_krb4=yes
-
-			AC_DEFINE(HAVE_KRB425, 1,
-				[define if you have Kerberos V with IV support])
-			AC_DEFINE(HAVE_KRB4, 1,
-				[define if you have Kerberos IV])
-
-			AC_CACHE_CHECK([for des_debug in Kerberos libraries],
-				[ol_cv_var_des_debug], [
-				dnl save the flags
-				save_LIBS="$LIBS"
-				LIBS="$KRB4_LIBS $KRB5_LIBS $LIBS"
-				AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-#include <kerberosIV/krb.h>
-#include <kerberosIV/des.h>
-extern int des_debug;
-]], [[
-des_debug = 1;
-]])],[ol_cv_var_des_debug=yes],[ol_cv_var_des_debug=no])
-				dnl restore the LIBS
-				LIBS="$save_LIBS"
-			])
-
-			if test $ol_cv_var_des_debug = yes ; then
-				AC_DEFINE(HAVE_DES_DEBUG,1,
-					[define if you have Kerberos des_debug])
-			fi
-
-			LIBS="$save_LIBS"
-		fi
-	fi
-fi
-
-if test $ol_link_krb5 = yes ; then
-	ol_with_kerberos=found
-fi
-
-case $ol_with_kerberos in yes | auto | k4 | kth)
-
-	AC_CHECK_HEADERS(krb.h des.h krb-archaeology.h )
-
-	if test $ac_cv_header_krb_h = yes ; then
-		AC_CHECK_LIB(krb, main, [have_k4=yes], [have_k4=no], [-ldes])
-
-		if test $have_k4 = yes ; then
-			ol_with_kerberos=found
-			ol_link_krb4=yes
-
-			AC_DEFINE(HAVE_KRB4, 1,
-				[define if you have Kerberos IV])
-
-			KRB4_LIBS="-lkrb -ldes"
-
-			if test $ac_cv_header_krb_archaeology_h = yes ; then
-				AC_DEFINE(HAVE_KTH_KERBEROS, 1,
-					[define if you have Kth Kerberos])
-			fi
-		fi
-	fi
-	;;
-esac
-
-if test $ol_link_krb4 = yes && test $ol_enable_kbind != no ; then
-	ol_link_kbind=yes
-
-elif test $ol_enable_kbind = yes ; then
-	AC_MSG_ERROR([Kerberos IV detection failed])
-fi
-
-if test $ol_link_krb4 = yes || test $ol_link_krb5 = yes ; then
-	AC_DEFINE(HAVE_KERBEROS, 1, [define if you have Kerberos])
-
-elif test $ol_with_kerberos != auto && test $ol_with_kerberos != no ; then
-	AC_MSG_ERROR([Kerberos detection failed])
-fi
-
-dnl ----------------------------------------------------------------
 dnl TLS/SSL
 	
+if test $ol_with_tls = yes ; then
+	ol_with_tls=auto
+fi
+
 ol_link_tls=no
-if test $ol_with_tls != no ; then
+if test $ol_with_tls = openssl || test $ol_with_tls = auto ; then
 	AC_CHECK_HEADERS(openssl/ssl.h)
 
 	if test $ac_cv_header_openssl_ssl_h = yes ; then
@@ -1341,7 +1130,7 @@
 		fi
 
 		if test $have_openssl = yes ; then
-			ol_with_tls=found
+			ol_with_tls=openssl
 			ol_link_tls=yes
 
 			AC_DEFINE(HAVE_OPENSSL, 1, 
@@ -1355,31 +1144,48 @@
 			else
 				TLS_LIBS="-lssl -lcrypto"
 			fi
+
+			OL_SSL_COMPAT
+			if test $ol_cv_ssl_crl_compat = yes ; then
+				AC_DEFINE(HAVE_OPENSSL_CRL, 1, 
+					[define if you have OpenSSL with CRL checking capability])
+			fi
 		fi
-		OL_SSL_COMPAT
-		if test $ol_cv_ssl_crl_compat = no ; then
-			ol_link_ssl=no
-                else 
-			AC_DEFINE(HAVE_OPENSSL_CRL, 1, 
-				[define if you have OpenSSL with CRL checking capability])
-		fi
 	fi
+fi
 
-else
-	AC_MSG_WARN([TLS data protection not supported!])
+if test $ol_link_tls = no ; then
+	if test $ol_with_tls = gnutls || test $ol_with_tls = auto ; then
+		AC_CHECK_HEADERS(gnutls/gnutls.h)
+
+		if test $ac_cv_header_gnutls_gnutls_h = yes ; then
+			AC_CHECK_LIB(gnutls, gnutls_init,
+				[have_gnutls=yes], [have_gnutls=no])
+
+			if test $have_gnutls = yes ; then
+				ol_with_tls=gnutls
+				ol_link_tls=yes
+
+				TLS_LIBS="-lgnutls"
+
+				AC_DEFINE(HAVE_GNUTLS, 1, 
+					[define if you have GNUtls])
+			fi
+		fi
+	fi
 fi
 
 WITH_TLS=no
 if test $ol_link_tls = yes ; then
 	AC_DEFINE(HAVE_TLS, 1, [define if you have TLS])
 	WITH_TLS=yes
-
 elif test $ol_with_tls = auto ; then
 	AC_MSG_WARN([Could not locate TLS/SSL package])
 	AC_MSG_WARN([TLS data protection not supported!])
-
 elif test $ol_with_tls != no ; then
 	AC_MSG_ERROR([Could not locate TLS/SSL package])
+else
+	AC_MSG_WARN([TLS data protection not supported!])
 fi
 
 dnl ----------------------------------------------------------------
@@ -1549,8 +1355,23 @@
 			fi
 
 			dnl Check functions for compatibility
-			AC_CHECK_FUNCS(pthread_kill pthread_rwlock_destroy)
+			AC_CHECK_FUNCS(pthread_kill)
 
+			dnl Check for pthread_rwlock_destroy with <pthread.h>
+			dnl as pthread_rwlock_t may not be defined.
+			AC_CACHE_CHECK([for pthread_rwlock_destroy with <pthread.h>],
+				[ol_cv_func_pthread_rwlock_destroy], [
+				dnl save the flags
+				AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <pthread.h>
+pthread_rwlock_t rwlock;
+]], [[pthread_rwlock_destroy(&rwlock);]])],[ol_cv_func_pthread_rwlock_destroy=yes],[ol_cv_func_pthread_rwlock_destroy=no])
+			])
+			if test $ol_cv_func_pthread_rwlock_destroy = yes ; then
+				AC_DEFINE(HAVE_PTHREAD_RWLOCK_DESTROY,1,
+					[define if you have pthread_rwlock_destroy function])
+			fi
+
 			dnl Check for pthread_detach with <pthread.h> inclusion
 			dnl as it's symbol may have been mangled.
 			AC_CACHE_CHECK([for pthread_detach with <pthread.h>],
@@ -1679,7 +1500,7 @@
 #endif
 
 	/* make sure task runs first */
-#if HAVE_THR_YIELD
+#ifdef HAVE_THR_YIELD
 	thr_yield();
 #elif defined( HAVE_SCHED_YIELD )
 	sched_yield();
@@ -1996,105 +1817,35 @@
 fi
 
 dnl ----------------------------------------------------------------
-ol_link_ldbm=no 
+ol_link_bdb=no 
 
-case $ol_enable_ldbm_api in auto | berkeley | bcompat)
-
-	if test $ol_enable_ldbm_api = bcompat; then \
-		OL_BERKELEY_COMPAT_DB
-	else
-		OL_BERKELEY_DB
-	fi
-
-	if test $ol_cv_berkeley_db != no ; then
-		AC_DEFINE(HAVE_BERKELEY_DB,1,
-			[define this if Berkeley DB is available])
-
-		ol_link_ldbm=berkeley
-		ol_enable_ldbm_api=berkeley
-
-		if test $ol_enable_ldbm_type = hash ; then
-			AC_DEFINE(LDBM_USE_DBHASH,1,
-				[define this to use DBHASH w/ LDBM backend])
-		else
-			AC_DEFINE(LDBM_USE_DBBTREE,1,
-				[define this to use DBBTREE w/ LDBM backend])
-		fi
-
-		dnl $ol_cv_lib_db should be yes or -ldb
-		dnl (it could be no, but that would be an error
-		if test $ol_cv_lib_db != yes ; then
-			LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_db"
-		fi
-	fi
-	;;
-esac
-
 if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
-	if test $ol_link_ldbm != berkeley ; then
-		AC_MSG_ERROR(BDB/HDB: BerkeleyDB not available)
-	else
-		OL_BDB_COMPAT
+	OL_BERKELEY_DB
 
-		if test $ol_cv_bdb_compat != yes ; then
-			AC_MSG_ERROR([BDB/HDB: BerkeleyDB version incompatible])
-		fi
+	if test $ol_cv_berkeley_db = no ; then
+		AC_MSG_ERROR(BDB/HDB: BerkeleyDB not available)
 	fi
-fi
 
-if test $ol_link_ldbm = no && test $ol_enable_ldbm_type = btree ; then
-	AC_MSG_WARN([Could not find LDBM with BTREE support])
-	ol_enable_ldbm_api=none
-fi
+	AC_DEFINE(HAVE_BERKELEY_DB,1,
+		[define this if Berkeley DB is available])
 
-if test $ol_enable_ldbm_api = auto || test $ol_enable_ldbm_api = mdbm ; then
-	OL_MDBM
-
-	if test $ol_cv_mdbm = yes ; then
-		ol_link_ldbm=mdbm
-		ol_enable_ldbm_api=mdbm
-		if test $ol_cv_lib_mdbm != yes ; then
-			LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_mdbm"
-		fi
+	dnl $ol_cv_lib_db should be yes or -ldb
+	dnl (it could be no, but that would be an error
+	if test $ol_cv_lib_db != yes ; then
+		BDB_LIBS="$BDB_LIBS $ol_cv_lib_db"
 	fi
-fi
 
-if test $ol_enable_ldbm_api = auto || test $ol_enable_ldbm_api = gdbm ; then
-	OL_GDBM
+	OL_BDB_COMPAT
 
-	if test $ol_cv_gdbm = yes ; then
-		ol_link_ldbm=gdbm
-		ol_enable_ldbm_api=gdbm
-
-		if test $ol_cv_lib_gdbm != yes ; then
-			LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_gdbm"
-		fi
+	if test $ol_cv_bdb_compat != yes ; then
+		AC_MSG_ERROR([BDB/HDB: BerkeleyDB version incompatible])
 	fi
-fi
 
-if test $ol_enable_ldbm_api = ndbm ; then
-	OL_NDBM
+	SLAPD_LIBS="$SLAPD_LIBS \$(BDB_LIBS)"
 
-	if test $ol_cv_ndbm = yes ; then
-		ol_link_ldbm=ndbm
-		ol_enable_ldbm_api=ndbm
-
-		if test $ol_cv_lib_ndbm != yes ; then
-			LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_ndbm"
-		fi
-	fi
+	ol_link_bdb=yes 
 fi
 
-if test $ol_link_ldbm = no && test $ol_enable_ldbm != no ; then
-	AC_MSG_ERROR([could not find suitable LDBM backend])
-fi
-
-if test $ol_enable_bdb = yes ||
-   test $ol_enable_hdb = yes ||
-   test $ol_enable_ldbm = yes ; then
-	SLAPD_LIBS="$SLAPD_LIBS \$(LDBM_LIBS)"
-fi
-
 dnl ----------------------------------------------------------------
 
 if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then
@@ -2211,6 +1962,14 @@
 fi
 
 dnl ----------------------------------------------------------------
+dnl International Components for Unicode
+OL_ICU
+if test "$ol_icu" = no ; then
+	AC_MSG_WARN([ICU not available])
+else
+	ICU_LIBS="$ol_icu"
+fi
+dnl ----------------------------------------------------------------
 dnl
 dnl Check for Cyrus SASL
 dnl
@@ -2539,7 +2298,7 @@
 	AC_CHECK_FUNCS(snprintf vsnprintf)
 fi
 
-AC_CHECK_FUNCS(		\
+AC_CHECK_FUNCS(			\
 	bcopy			\
 	closesocket		\
 	chroot			\
@@ -2548,17 +2307,18 @@
 	fcntl			\
 	flock			\
 	fstat			\
-	getdtablesize	\
+	getdtablesize		\
 	getgrgid		\
 	gethostname		\
 	getpass			\
-	getpassphrase	\
+	getpassphrase		\
 	getpwuid		\
 	getpwnam		\
 	getspnam		\
-	gettimeofday	\
+	gettimeofday		\
 	initgroups		\
 	inet_ntoa_b		\
+	ioctl			\
 	lockf			\
 	memcpy			\
 	memmove			\
@@ -2602,21 +2362,32 @@
 if test "$ac_cv_func_getopt" != yes; then
 	LIBSRCS="$LIBSRCS getopt.c"
 fi
+
 if test "$ac_cv_func_getpeereid" != yes; then
-	AC_CHECK_MEMBERS([struct msghdr.msg_accrightslen],,,
-		[$ac_includes_default
+	AC_CHECK_FUNCS( getpeerucred )
+	if test "$ac_cv_func_getpeerucred" != yes ; then
+		AC_CHECK_MEMBERS([struct msghdr.msg_accrightslen],,,
+			[$ac_includes_default
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif])
-	if test "$ac_cv_member_struct_msghdr_msg_accrightslen" != yes; then
-		AC_CHECK_MEMBERS([struct msghdr.msg_control],,,
-			[$ac_includes_default
+		if test "$ac_cv_member_struct_msghdr_msg_accrightslen" != yes; then
+			AC_CHECK_MEMBERS([struct msghdr.msg_control],,,
+				[$ac_includes_default
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif])
+		fi
+		AC_CHECK_MEMBERS([struct stat.st_fstype, struct stat.st_vfstype])
+		if test "$ac_cv_member_struct_stat_st_fstype" = yes; then
+			AC_COMPILE_IFELSE([struct stat st; char *ptr=st.st_fstype;],
+				AC_DEFINE([HAVE_STRUCT_STAT_ST_FSTYPE_CHAR],1,[define to 1 if st_fstype is char *]),
+				AC_DEFINE([HAVE_STRUCT_STAT_ST_FSTYPE_INT],1,[define to 1 if st_fstype is int]))
+		fi
 	fi
 	LIBSRCS="$LIBSRCS getpeereid.c"
 fi
+
 if test "$ac_cv_func_snprintf" != yes ||
    test "$ac_cv_func_vsnprintf" != yes; then
 	if test "$ac_cv_func_snprintf" != yes; then
@@ -2649,6 +2420,10 @@
 fi
 
 if test "$ol_enable_debug" != no ; then
+	if test "$ol_enable_debug" = traditional; then
+		AC_DEFINE(OLD_DEBUG,1,
+			[define to use the original debug style])
+	fi
 	AC_DEFINE(LDAP_DEBUG,1,
 		[define this to add debugging code])
 fi
@@ -2656,10 +2431,6 @@
 	AC_DEFINE(LDAP_SYSLOG,1,
 		[define this to add syslog code])
 fi
-if test "$ol_link_kbind" != no ; then
-	AC_DEFINE(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND,LDAP_VENDOR_VERSION,
-		[define to LDAP VENDOR VERSION])
-fi
 if test "$ol_enable_proctitle" != no ; then
 	AC_DEFINE(LDAP_PROCTITLE,1,
 		[define this for LDAP process title support])
@@ -2683,18 +2454,29 @@
 if test "$ol_link_spasswd" != no ; then
 	AC_DEFINE(SLAPD_SPASSWD,1,[define to support SASL passwords])
 fi
-if test "$ol_enable_multimaster" != no ; then
-	AC_DEFINE(SLAPD_MULTIMASTER,1,[define to support multimaster replication])
-fi
 if test "$ol_enable_rlookups" != no ; then
 	AC_DEFINE(SLAPD_RLOOKUPS,1,[define to support reverse lookups])
 fi
 if test "$ol_enable_aci" != no ; then
-	AC_DEFINE(SLAPD_ACI_ENABLED,1,[define to support per-object ACIs])
-	WITH_ACI_ENABLED=yes
+	if test $ol_enable_dynacl = no ; then
+		ol_enable_dynacl=yes
+		AC_MSG_WARN([ACIs need dynacl])
+	fi
+	if test "$ol_enable_aci" = mod ; then
+		MFLAG=SLAPD_MOD_DYNAMIC
+		dnl remove this after moving servers/slapd/aci.c in contrib/slapd-modules/acl
+		AC_MSG_ERROR([ACI build as dynamic module not supported (yet)])
+	else 
+		MFLAG=SLAPD_MOD_STATIC
+	fi
+	WITH_ACI_ENABLED=$ol_enable_aci
+	AC_DEFINE_UNQUOTED(SLAPD_ACI_ENABLED,$MFLAG,[define to support per-object ACIs])
 else
 	WITH_ACI_ENABLED=no
 fi
+if test "$ol_enable_dynacl" != no ; then
+	AC_DEFINE(SLAP_DYNACL,1,[define to support run-time loadable ACL])
+fi
 
 if test "$ol_link_modules" != no ; then
 	AC_DEFINE(SLAPD_MODULES,1,[define to support modules])
@@ -2705,6 +2487,20 @@
 AC_DEFINE(SLAPD_MOD_STATIC,1,[statically linked module])
 AC_DEFINE(SLAPD_MOD_DYNAMIC,2,[dynamically linked module])
 
+dnl back-monitor goes first (well, after back-config)
+if test "$ol_enable_monitor" != no ; then
+	BUILD_SLAPD=yes
+	BUILD_MONITOR=$ol_enable_monitor
+	if test "$ol_enable_monitor" = mod ; then
+		SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-monitor"
+		MFLAG=SLAPD_MOD_DYNAMIC
+	else
+		SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-monitor"
+		MFLAG=SLAPD_MOD_STATIC
+	fi
+	AC_DEFINE_UNQUOTED(SLAPD_MONITOR,$MFLAG,[define to support cn=Monitor backend])
+fi
+
 if test "$ol_enable_bdb" != no ; then
 	BUILD_SLAPD=yes
 	BUILD_BDB=$ol_enable_bdb
@@ -2757,19 +2553,6 @@
 	AC_DEFINE_UNQUOTED(SLAPD_LDAP,$MFLAG,[define to support LDAP backend])
 fi
 
-if test "$ol_link_ldbm" != no && test $ol_enable_ldbm != no; then
-	BUILD_SLAPD=yes
-	BUILD_LDBM=$ol_enable_ldbm
-	if test "$ol_enable_ldbm" = mod ; then
-		SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-ldbm"
-		MFLAG=SLAPD_MOD_DYNAMIC
-	else
-		SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-ldbm"
-		MFLAG=SLAPD_MOD_STATIC
-	fi
-	AC_DEFINE_UNQUOTED(SLAPD_LDBM,$MFLAG,[define to support LDBM backend])
-fi
-
 if test "$ol_enable_meta" != no ; then
 	BUILD_SLAPD=yes
 	BUILD_META=$ol_enable_meta
@@ -2784,19 +2567,6 @@
 	AC_DEFINE_UNQUOTED(SLAPD_META,$MFLAG,[define to support LDAP Metadirectory backend])
 fi
 
-if test "$ol_enable_monitor" != no ; then
-	BUILD_SLAPD=yes
-	BUILD_MONITOR=$ol_enable_monitor
-	if test "$ol_enable_monitor" = mod ; then
-		SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-monitor"
-		MFLAG=SLAPD_MOD_DYNAMIC
-	else
-		SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-monitor"
-		MFLAG=SLAPD_MOD_STATIC
-	fi
-	AC_DEFINE_UNQUOTED(SLAPD_MONITOR,$MFLAG,[define to support cn=Monitor backend])
-fi
-
 if test "$ol_enable_null" != no ; then
 	BUILD_SLAPD=yes
 	BUILD_NULL=$ol_enable_null
@@ -2902,18 +2672,30 @@
 	AC_DEFINE_UNQUOTED(SLAPD_OVER_AUDITLOG,$MFLAG,[define for Audit Logging overlay])
 fi
 
-if test "$ol_enable_denyop" != no ; then
-	BUILD_DENYOP=$ol_enable_denyop
-	if test "$ol_enable_denyop" = mod ; then
+if test "$ol_enable_constraint" != no ; then
+	BUILD_CONSTRAINT=$ol_enable_constraint
+	if test "$ol_enable_constraint" = mod ; then
 		MFLAG=SLAPD_MOD_DYNAMIC
-		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS denyop.la"
+		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS constraint.la"
 	else
 		MFLAG=SLAPD_MOD_STATIC
-		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS denyop.o"
+		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS constraint.o"
 	fi
-	AC_DEFINE_UNQUOTED(SLAPD_OVER_DENYOP,$MFLAG,[define for Deny Operation overlay])
+	AC_DEFINE_UNQUOTED(SLAPD_OVER_CONSTRAINT,$MFLAG,[define for Attribute Constraint overlay])
 fi
 
+if test "$ol_enable_dds" != no ; then
+	BUILD_DDS=$ol_enable_dds
+	if test "$ol_enable_dds" = mod ; then
+		MFLAG=SLAPD_MOD_DYNAMIC
+		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS dds.la"
+	else
+		MFLAG=SLAPD_MOD_STATIC
+		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS dds.o"
+	fi
+	AC_DEFINE_UNQUOTED(SLAPD_OVER_DDS,$MFLAG,[define for Dynamic Directory Services overlay])
+fi
+
 if test "$ol_enable_dyngroup" != no ; then
 	BUILD_DYNGROUP=$ol_enable_dyngroup
 	if test "$ol_enable_dyngroup" = mod ; then
@@ -2938,16 +2720,16 @@
 	AC_DEFINE_UNQUOTED(SLAPD_OVER_DYNLIST,$MFLAG,[define for Dynamic List overlay])
 fi
 
-if test "$ol_enable_lastmod" != no ; then
-	BUILD_LASTMOD=$ol_enable_lastmod
-	if test "$ol_enable_lastmod" = mod ; then
+if test "$ol_enable_memberof" != no ; then
+	BUILD_MEMBEROF=$ol_enable_memberof
+	if test "$ol_enable_memberof" = mod ; then
 		MFLAG=SLAPD_MOD_DYNAMIC
-		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS lastmod.la"
+		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS memberof.la"
 	else
 		MFLAG=SLAPD_MOD_STATIC
-		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS lastmod.o"
+		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS memberof.o"
 	fi
-	AC_DEFINE_UNQUOTED(SLAPD_OVER_LASTMOD,$MFLAG,[define for Last Modification overlay])
+	AC_DEFINE_UNQUOTED(SLAPD_OVER_MEMBEROF,$MFLAG,[define for Reverse Group Membership overlay])
 fi
 
 if test "$ol_enable_ppolicy" != no ; then
@@ -3011,6 +2793,18 @@
 	AC_DEFINE_UNQUOTED(SLAPD_OVER_RWM,$MFLAG,[define for Rewrite/Remap overlay])
 fi
 
+if test "$ol_enable_seqmod" != no ; then
+	BUILD_SEQMOD=$ol_enable_seqmod
+	if test "$ol_enable_seqmod" = mod ; then
+		MFLAG=SLAPD_MOD_DYNAMIC
+		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS seqmod.la"
+	else
+		MFLAG=SLAPD_MOD_STATIC
+		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS seqmod.o"
+	fi
+	AC_DEFINE_UNQUOTED(SLAPD_OVER_SEQMOD,$MFLAG,[define for Sequential Modify overlay])
+fi
+
 if test "$ol_enable_syncprov" != no ; then
 	BUILD_SYNCPROV=$ol_enable_syncprov
 	if test "$ol_enable_syncprov" = mod ; then
@@ -3059,12 +2853,6 @@
 	AC_DEFINE_UNQUOTED(SLAPD_OVER_VALSORT,$MFLAG,[define for Value Sorting overlay])
 fi
 
-if test "$ol_enable_slurpd" != no &&
-   test "$ol_link_threads" != no &&
-   test $BUILD_SLAPD = yes ; then
-	BUILD_SLURPD=yes
-fi
-
 if test "$ol_enable_rewrite" != no ; then
 	AC_DEFINE(ENABLE_REWRITE,1,[define to enable rewriting in back-ldap and back-meta])
 	BUILD_REWRITE=yes
@@ -3108,7 +2896,6 @@
   AC_SUBST(BUILD_DNSSRV)
   AC_SUBST(BUILD_HDB)
   AC_SUBST(BUILD_LDAP)
-  AC_SUBST(BUILD_LDBM)
   AC_SUBST(BUILD_META)
   AC_SUBST(BUILD_MONITOR)
   AC_SUBST(BUILD_NULL)
@@ -3120,25 +2907,27 @@
 dnl overlays
   AC_SUBST(BUILD_ACCESSLOG)
   AC_SUBST(BUILD_AUDITLOG)
+  AC_SUBST(BUILD_CONSTRAINT)
+  AC_SUBST(BUILD_DDS)
   AC_SUBST(BUILD_DENYOP)
   AC_SUBST(BUILD_DYNGROUP)
   AC_SUBST(BUILD_DYNLIST)
   AC_SUBST(BUILD_LASTMOD)
+  AC_SUBST(BUILD_MEMBEROF)
   AC_SUBST(BUILD_PPOLICY)
   AC_SUBST(BUILD_PROXYCACHE)
   AC_SUBST(BUILD_REFINT)
   AC_SUBST(BUILD_RETCODE)
   AC_SUBST(BUILD_RWM)
+  AC_SUBST(BUILD_SEQMOD)
   AC_SUBST(BUILD_SYNCPROV)
   AC_SUBST(BUILD_TRANSLUCENT)
   AC_SUBST(BUILD_UNIQUE)
   AC_SUBST(BUILD_VALSORT)
-AC_SUBST(BUILD_SLURPD)
 
 AC_SUBST(LDAP_LIBS)
 AC_SUBST(SLAPD_LIBS)
-AC_SUBST(SLURPD_LIBS)
-AC_SUBST(LDBM_LIBS)
+AC_SUBST(BDB_LIBS)
 AC_SUBST(LTHREAD_LIBS)
 AC_SUBST(LUTIL_LIBS)
 AC_SUBST(WRAP_LIBS)
@@ -3165,6 +2954,7 @@
 AC_SUBST(LIBSLAPI)
 AC_SUBST(LIBSLAPITOOLS)
 AC_SUBST(AUTH_LIBS)
+AC_SUBST(ICU_LIBS)
 
 AC_SUBST(SLAPD_SLP_LIBS)
 AC_SUBST(SLAPD_GMP_LIBS)
@@ -3205,7 +2995,6 @@
 [servers/slapd/back-dnssrv/Makefile:build/top.mk:servers/slapd/back-dnssrv/Makefile.in:build/mod.mk]
 [servers/slapd/back-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/Makefile.in:build/mod.mk]
 [servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/mod.mk]
-[servers/slapd/back-ldbm/Makefile:build/top.mk:servers/slapd/back-ldbm/Makefile.in:build/mod.mk]
 [servers/slapd/back-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/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]
@@ -3218,7 +3007,6 @@
 [servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk]
 [servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk]
 [servers/slapd/overlays/Makefile:build/top.mk:servers/slapd/overlays/Makefile.in:build/lib.mk]
-[servers/slurpd/Makefile:build/top.mk:servers/slurpd/Makefile.in:build/srv.mk]
 [tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk]
 [tests/run]
 [tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk])
@@ -3331,7 +3119,11 @@
 /* end of generated file */
 ENDX
 
-echo Please run \"make depend\" to build dependencies
+if test "${ol_cv_mkdep}" = no; then
+	echo '(Do not "make depend"; we do not know how to build dependencies)'
+else
+	echo 'Please run "make depend" to build dependencies'
+fi
 ]],[[
 STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS"
 STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS"

Copied: openldap/trunk/contrib/ConfigOIDs (from rev 891, openldap/vendor/openldap-2.4.7/contrib/ConfigOIDs)
===================================================================
--- openldap/trunk/contrib/ConfigOIDs	                        (rev 0)
+++ openldap/trunk/contrib/ConfigOIDs	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,3 @@
+List of OpenLDAP Configuration OIDs allocated to contrib modules
+
+OLcfgCt{Oc|At}:1	smbk5pwd

Modified: openldap/trunk/contrib/README
===================================================================
--- openldap/trunk/contrib/README	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/README	2007-12-15 10:25:31 UTC (rev 892)
@@ -11,8 +11,12 @@
 		LDAP C++ API
 		Contributed by SuSE Gmbh.
 
+	ldaptcl
+		LDAP TCL API
+		Contributed by NeoSoft
+
 	slapd-modules
-		Native modules
+		Native-API modules
 
 	slapd-tools
 		Tools to use with slapd
@@ -24,4 +28,4 @@
 OpenLDAP Contributing Guidelines are available at:
   <http://www.openldap.org/devel/contributing.html>.
 
-$OpenLDAP: pkg/ldap/contrib/README,v 1.14.2.6 2005/04/29 21:28:59 kurt Exp $
+$OpenLDAP: pkg/ldap/contrib/README,v 1.19 2006/01/25 21:13:14 kurt Exp $

Modified: openldap/trunk/contrib/ldapc++/Makefile.in
===================================================================
--- openldap/trunk/contrib/ldapc++/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# Makefile.in generated by automake 1.10 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -16,15 +16,11 @@
 
 # Copyright 2000-2003, OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT file
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = .
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
 install_sh_SCRIPT = $(install_sh) -c
@@ -38,28 +34,30 @@
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
+subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS TODO \
-	acconfig.h config.guess config.sub depcomp install-sh \
-	ltmain.sh missing mkinstalldirs
-subdir = .
+	config.guess config.sub depcomp install-sh ltmain.sh missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
- configure.lineno configure.status.lineno
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/src/config.h
 CONFIG_CLEAN_FILES =
 SOURCES =
 DIST_SOURCES =
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
 	html-recursive info-recursive install-data-recursive \
-	install-exec-recursive install-info-recursive \
-	install-recursive installcheck-recursive installdirs-recursive \
-	pdf-recursive ps-recursive uninstall-info-recursive \
-	uninstall-recursive
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = $(SUBDIRS)
@@ -75,8 +73,6 @@
 distuninstallcheck_listfiles = find . -type f -print
 distcleancheck_listfiles = find . -type f -print
 ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
@@ -103,6 +99,8 @@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FFLAGS = @FFLAGS@
+GREP = @GREP@
+INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -114,6 +112,7 @@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -123,20 +122,18 @@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
-ac_ct_AR = @ac_ct_AR@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
 ac_ct_F77 = @ac_ct_F77@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -148,28 +145,39 @@
 build_cpu = @build_cpu@
 build_os = @build_os@
 build_vendor = @build_vendor@
+builddir = @builddir@
 datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
 host_os = @host_os@
 host_vendor = @host_vendor@
+htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
 libdir = @libdir@
 libexecdir = @libexecdir@
+localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
+psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
 EXTRA_DIST = BUGS
 SUBDIRS = src examples
 all: all-recursive
@@ -217,7 +225,6 @@
 
 distclean-libtool:
 	-rm -f libtool
-uninstall-info-am:
 
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run `make' without going through this Makefile.
@@ -250,8 +257,7 @@
 	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
 	fi; test -z "$$fail"
 
-mostlyclean-recursive clean-recursive distclean-recursive \
-maintainer-clean-recursive:
+$(RECURSIVE_CLEAN_TARGETS):
 	@failcom='exit 1'; \
 	for f in x $$MAKEFLAGS; do \
 	  case $$f in \
@@ -353,23 +359,22 @@
 
 distdir: $(DISTFILES)
 	$(am__remove_distdir)
-	mkdir $(distdir)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
+	test -d $(distdir) || mkdir $(distdir)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
 	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
 	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
 	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
 	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
 	    fi; \
@@ -383,7 +388,7 @@
 	list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
 	  if test "$$subdir" = .; then :; else \
 	    test -d "$(distdir)/$$subdir" \
-	    || $(mkdir_p) "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
 	    || exit 1; \
 	    distdir=`$(am__cd) $(distdir) && pwd`; \
 	    top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
@@ -391,6 +396,8 @@
 	      $(MAKE) $(AM_MAKEFLAGS) \
 	        top_distdir="$$top_distdir" \
 	        distdir="$$distdir/$$subdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
 	        distdir) \
 	      || exit 1; \
 	  fi; \
@@ -398,7 +405,7 @@
 	-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
 	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
 	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
-	  ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
 	|| chmod -R a+r $(distdir)
 dist-gzip: distdir
 	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
@@ -473,7 +480,7 @@
 	$(am__remove_distdir)
 	@(echo "$(distdir) archives ready for distribution: "; \
 	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
-	  sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
 distuninstallcheck:
 	@cd $(distuninstallcheck_dir) \
 	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
@@ -543,12 +550,20 @@
 
 install-data-am:
 
+install-dvi: install-dvi-recursive
+
 install-exec-am:
 
+install-html: install-html-recursive
+
 install-info: install-info-recursive
 
 install-man:
 
+install-pdf: install-pdf-recursive
+
+install-ps: install-ps-recursive
+
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
@@ -569,24 +584,26 @@
 
 ps-am:
 
-uninstall-am: uninstall-info-am
+uninstall-am:
 
-uninstall-info: uninstall-info-recursive
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+	install-strip
 
-.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
-	check-am clean clean-generic clean-libtool clean-recursive \
-	ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
-	dist-shar dist-tarZ dist-zip distcheck distclean \
-	distclean-generic distclean-libtool distclean-recursive \
-	distclean-tags distcleancheck distdir distuninstallcheck dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-exec install-exec-am \
-	install-info install-info-am install-man install-strip \
-	installcheck installcheck-am installdirs installdirs-am \
-	maintainer-clean maintainer-clean-generic \
-	maintainer-clean-recursive mostlyclean mostlyclean-generic \
-	mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \
-	tags tags-recursive uninstall uninstall-am uninstall-info-am
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am am--refresh check check-am clean clean-generic \
+	clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
+	dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
+	distclean-generic distclean-libtool distclean-tags \
+	distcleancheck distdir distuninstallcheck dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+	uninstall uninstall-am
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.

Deleted: openldap/trunk/contrib/ldapc++/acconfig.h
===================================================================
--- openldap/trunk/contrib/ldapc++/acconfig.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/acconfig.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,2 +0,0 @@
-#undef WITH_DEBUG
-

Modified: openldap/trunk/contrib/ldapc++/aclocal.m4
===================================================================
--- openldap/trunk/contrib/ldapc++/aclocal.m4	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/aclocal.m4	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,7 @@
-# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
+# generated automatically by aclocal 1.10 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005  Free Software Foundation, Inc.
+# 2005, 2006  Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,9 +11,14 @@
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
+m4_if(m4_PACKAGE_VERSION, [2.61],,
+[m4_fatal([this file was generated for autoconf 2.61.
+You have another version of autoconf.  If you want to use that,
+you should regenerate the build system entirely.], [63])])
+
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 
-# serial 47 AC_PROG_LIBTOOL
+# serial 51 AC_PROG_LIBTOOL
 
 
 # AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
@@ -143,7 +148,7 @@
 default_ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a `.a' archive for static linking (except M$VC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 ltmain="$ac_aux_dir/ltmain.sh"
@@ -163,6 +168,7 @@
 test -z "$AS" && AS=as
 test -z "$CC" && CC=cc
 test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
 test -z "$DLLTOOL" && DLLTOOL=dlltool
 test -z "$LD" && LD=ld
 test -z "$LN_S" && LN_S="ln -s"
@@ -175,17 +181,17 @@
 test -z "$ac_objext" && ac_objext=o
 
 # Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
 old_postinstall_cmds='chmod 644 $oldlib'
 old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
   case $host_os in
   openbsd*)
-    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
     ;;
   *)
-    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
     ;;
   esac
   old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
@@ -233,6 +239,9 @@
 # If no C compiler was specified, use CC.
 LTCC=${LTCC-"$CC"}
 
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
 # Allow CC to be a program name with arguments.
 compiler=$CC
 ])# _LT_AC_SYS_COMPILER
@@ -259,9 +268,10 @@
 # Check for compiler boilerplate output or warnings with
 # the simple compiler test code.
 AC_DEFUN([_LT_COMPILER_BOILERPLATE],
-[ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+[AC_REQUIRE([LT_AC_PROG_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_compiler_boilerplate=`cat conftest.err`
 $rm conftest*
 ])# _LT_COMPILER_BOILERPLATE
@@ -272,9 +282,10 @@
 # Check for linker boilerplate output or warnings with
 # the simple link test code.
 AC_DEFUN([_LT_LINKER_BOILERPLATE],
-[ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+[AC_REQUIRE([LT_AC_PROG_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_linker_boilerplate=`cat conftest.err`
 $rm conftest*
 ])# _LT_LINKER_BOILERPLATE
@@ -289,12 +300,20 @@
 # If we don't find anything, use the default library path according
 # to the aix ld manual.
 AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
-[AC_LINK_IFELSE(AC_LANG_PROGRAM,[
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
+[AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
 # Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`; fi],[])
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi],[])
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 ])# _LT_AC_SYS_LIBPATH_AIX
 
@@ -359,8 +378,8 @@
 # find a string as large as possible, as long as the shell can cope with it
   for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
     # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
-    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
-       echo_test_string="`eval $cmd`" &&
+    if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+       echo_test_string=`eval $cmd` &&
        (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
     then
       break
@@ -525,13 +544,17 @@
   rm -rf conftest*
   ;;
 
-x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|sparc*-*linux*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
-    case "`/usr/bin/file conftest.o`" in
+    case `/usr/bin/file conftest.o` in
     *32-bit*)
       case $host in
+        x86_64-*kfreebsd*-gnu)
+          LD="${LD-ld} -m elf_i386_fbsd"
+          ;;
         x86_64-*linux*)
           LD="${LD-ld} -m elf_i386"
           ;;
@@ -548,6 +571,9 @@
       ;;
     *64-bit*)
       case $host in
+        x86_64-*kfreebsd*-gnu)
+          LD="${LD-ld} -m elf_x86_64_fbsd"
+          ;;
         x86_64-*linux*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
@@ -580,6 +606,22 @@
     CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)    LD="${LD-ld} -64" ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
 AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
 [*-*-cygwin* | *-*-mingw* | *-*-pw32*)
   AC_CHECK_TOOL(DLLTOOL, dlltool, false)
@@ -603,7 +645,7 @@
 AC_CACHE_CHECK([$1], [$2],
   [$2=no
   ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
    lt_compiler_flag="$3"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
@@ -611,7 +653,7 @@
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    # The option is referenced via a variable to avoid confusing sed.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
@@ -622,9 +664,9 @@
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp
-     $SED '/^$/d' conftest.err >conftest.er2
-     if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        $2=yes
      fi
    fi
@@ -644,19 +686,20 @@
 # ------------------------------------------------------------
 # Check whether the given compiler option works
 AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
-[AC_CACHE_CHECK([$1], [$2],
+[AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
   [$2=no
    save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $3"
-   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
-     # The compiler can only warn and ignore the option if not recognized
+     # The linker can only warn and ignore the option if not recognized
      # So say no if there are warnings
      if test -s conftest.err; then
        # Append any errors to the config.log.
        cat conftest.err 1>&AS_MESSAGE_LOG_FD
-       $echo "X$_lt_linker_boilerplate" | $Xsed > conftest.exp
-       $SED '/^$/d' conftest.err >conftest.er2
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
        if diff conftest.exp conftest.er2 >/dev/null; then
          $2=yes
        fi
@@ -725,44 +768,64 @@
     elif test -x /usr/sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
     else
-      lt_cv_sys_max_cmd_len=65536 # usable default for *BSD
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
     fi
     # And add a safety zone
     lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
     lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
     ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
   osf*)
     # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
     # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
     # nice to cause kernel panics so lets avoid the loop below.
     # First set a reasonable default.
     lt_cv_sys_max_cmd_len=16384
-    # 
+    #
     if test -x /sbin/sysconfig; then
       case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
         *1*) lt_cv_sys_max_cmd_len=-1 ;;
       esac
     fi
     ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ 	]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
   *)
-    # If test is not a shell built-in, we'll probably end up computing a
-    # maximum length that is only half of the actual maximum length, but
-    # we can't tell.
-    SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
-    while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
 	       = "XX$teststring") >/dev/null 2>&1 &&
-	    new_result=`expr "X$teststring" : ".*" 2>&1` &&
-	    lt_cv_sys_max_cmd_len=$new_result &&
-	    test $i != 17 # 1/2 MB should be enough
-    do
-      i=`expr $i + 1`
-      teststring=$teststring$teststring
-    done
-    teststring=
-    # Add a significant safety factor because C++ compilers can tack on massive
-    # amounts of additional arguments before passing them to the linker.
-    # It appears as though 1/2 is a usable value.
-    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+	      new_result=`expr "X$teststring" : ".*" 2>&1` &&
+	      lt_cv_sys_max_cmd_len=$new_result &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on massive
+      # amounts of additional arguments before passing them to the linker.
+      # It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
     ;;
   esac
 ])
@@ -775,7 +838,7 @@
 
 
 # _LT_AC_CHECK_DLFCN
-# --------------------
+# ------------------
 AC_DEFUN([_LT_AC_CHECK_DLFCN],
 [AC_CHECK_HEADERS(dlfcn.h)dnl
 ])# _LT_AC_CHECK_DLFCN
@@ -783,7 +846,7 @@
 
 # _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
 #                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
-# ------------------------------------------------------------------
+# ---------------------------------------------------------------------
 AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
 [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
 if test "$cross_compiling" = yes; then :
@@ -849,17 +912,19 @@
       else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
       /* dlclose (self); */
     }
+  else
+    puts (dlerror ());
 
     exit (status);
 }]
 EOF
   if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
-    (./conftest; exit; ) 2>/dev/null
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
     lt_status=$?
     case x$lt_status in
       x$lt_dlno_uscore) $1 ;;
       x$lt_dlneed_uscore) $2 ;;
-      x$lt_unknown|x*) $3 ;;
+      x$lt_dlunknown|x*) $3 ;;
     esac
   else :
     # compilation failed
@@ -871,7 +936,7 @@
 
 
 # AC_LIBTOOL_DLOPEN_SELF
-# -------------------
+# ----------------------
 AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
 [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
 if test "x$enable_dlopen" != xyes; then
@@ -942,7 +1007,7 @@
     test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
     save_LDFLAGS="$LDFLAGS"
-    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
 
     save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
@@ -955,7 +1020,7 @@
     ])
 
     if test "x$lt_cv_dlopen_self" = xyes; then
-      LDFLAGS="$LDFLAGS $link_static_flag"
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
       AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
     	  lt_cv_dlopen_self_static, [dnl
 	  _LT_AC_TRY_DLOPEN_SELF(
@@ -987,7 +1052,8 @@
 # ---------------------------------
 # Check to see if options -c and -o are simultaneously supported by compiler
 AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
-[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+[AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
 AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
   [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
   [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
@@ -995,7 +1061,7 @@
    mkdir conftest
    cd conftest
    mkdir out
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
    lt_compiler_flag="-o out/conftest2.$ac_objext"
    # Insert the option either (1) after the last *FLAGS variable, or
@@ -1003,7 +1069,7 @@
    # Note that $ac_compile itself does not contain backslashes and begins
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
@@ -1015,13 +1081,13 @@
    then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
-     $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp
-     $SED '/^$/d' out/conftest.err >out/conftest.er2
-     if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
        _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
      fi
    fi
-   chmod u+w .
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
    $rm conftest*
    # SGI C++ compiler will create directory out/ii_files/ for
    # template instantiation
@@ -1135,6 +1201,7 @@
    darwin*)
        if test -n "$STRIP" ; then
          striplib="$STRIP -x"
+         old_striplib="$STRIP -S"
          AC_MSG_RESULT([yes])
        else
   AC_MSG_RESULT([no])
@@ -1152,7 +1219,8 @@
 # -----------------------------
 # PORTME Fill in your ld.so characteristics
 AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
-[AC_MSG_CHECKING([dynamic linker characteristics])
+[AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
@@ -1166,20 +1234,58 @@
 version_type=none
 dynamic_linker="$host_os ld.so"
 sys_lib_dlsearch_path_spec="/lib /usr/lib"
+m4_if($1,[],[
 if test "$GCC" = yes; then
-  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then
     # if the path contains ";" then we assume it to be the separator
     # otherwise default to the standard path separator (i.e. ":") - it is
     # assumed that no part of a normal pathname contains ";" but that should
     # okay in the real world where ";" in dirpaths is itself problematic.
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+    lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'`
   else
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+    lt_search_path_spec=`echo "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
   fi
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  sys_lib_search_path_spec=`echo $lt_search_path_spec`
 else
   sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
+fi])
 need_lib_prefix=unknown
 hardcode_into_libs=no
 
@@ -1281,7 +1387,8 @@
       dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
-      $install_prog $dir/$dlname \$dldir/$dlname'
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
     postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
       dlpath=$dir/\$dldll~
        $rm \$dlpath'
@@ -1334,13 +1441,9 @@
   soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
-  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
-  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
-  if test "$GCC" = yes; then
-    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
-  else
-    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
-  fi
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) 
   sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
   ;;
 
@@ -1357,22 +1460,17 @@
   dynamic_linker=no
   ;;
 
-kfreebsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
-  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[123]]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
@@ -1394,10 +1492,15 @@
     shlibpath_overrides_runpath=yes
     hardcode_into_libs=yes
     ;;
-  *) # from 3.2 on
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
     shlibpath_overrides_runpath=no
     hardcode_into_libs=yes
     ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
   esac
   ;;
 
@@ -1417,7 +1520,7 @@
   version_type=sunos
   need_lib_prefix=no
   need_version=no
-  case "$host_cpu" in
+  case $host_cpu in
   ia64*)
     shrext_cmds='.so'
     hardcode_into_libs=yes
@@ -1457,6 +1560,18 @@
   postinstall_cmds='chmod 555 $lib'
   ;;
 
+interix[[3-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
 irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
@@ -1500,7 +1615,7 @@
   ;;
 
 # This must be Linux ELF.
-linux*)
+linux* | k*bsd*-gnu)
   version_type=linux
   need_lib_prefix=no
   need_version=no
@@ -1516,7 +1631,7 @@
 
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ 	]*hwcap[ 	]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
   fi
 
@@ -1529,18 +1644,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-knetbsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -1578,6 +1681,7 @@
 
 openbsd*)
   version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
   # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
   case $host_os in
@@ -1621,11 +1725,8 @@
   sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
-sco3.2v5*)
-  version_type=osf
-  soname_spec='${libname}${release}${shared_ext}$major'
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  shlibpath_var=LD_LIBRARY_PATH
+rdos*)
+  dynamic_linker=no
   ;;
 
 solaris*)
@@ -1653,7 +1754,7 @@
   need_version=yes
   ;;
 
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
@@ -1686,6 +1787,29 @@
   fi
   ;;
 
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
 uts4*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -1699,13 +1823,19 @@
 esac
 AC_MSG_RESULT([$dynamic_linker])
 test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
 ])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
 
 
 # _LT_AC_TAGCONFIG
 # ----------------
 AC_DEFUN([_LT_AC_TAGCONFIG],
-[AC_ARG_WITH([tags],
+[AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_ARG_WITH([tags],
     [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@],
         [include additional configurations @<:@automatic@:>@])],
     [tagnames="$withval"])
@@ -1723,6 +1853,9 @@
       AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
     fi
   fi
+  if test -z "$LTCFLAGS"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
+  fi
 
   # Extract list of available tagged configurations in $ofile.
   # Note that this assumes the entire list is on one line.
@@ -1813,7 +1946,7 @@
 
 # AC_LIBTOOL_WIN32_DLL
 # --------------------
-# declare package support for building win32 dll's
+# declare package support for building win32 DLLs
 AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
 [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
 ])# AC_LIBTOOL_WIN32_DLL
@@ -1851,7 +1984,7 @@
 
 # AC_DISABLE_SHARED
 # -----------------
-#- set the default shared flag to --disable-shared
+# set the default shared flag to --disable-shared
 AC_DEFUN([AC_DISABLE_SHARED],
 [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
 AC_ENABLE_SHARED(no)
@@ -1963,7 +2096,7 @@
 
 # AC_PATH_TOOL_PREFIX
 # -------------------
-# find a file program which can recognise shared library
+# find a file program which can recognize shared library
 AC_DEFUN([AC_PATH_TOOL_PREFIX],
 [AC_REQUIRE([AC_PROG_EGREP])dnl
 AC_MSG_CHECKING([for $1])
@@ -1987,7 +2120,7 @@
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
-	  file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
 	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
@@ -2026,7 +2159,7 @@
 
 # AC_PATH_MAGIC
 # -------------
-# find a file program which can recognise a shared library
+# find a file program which can recognize a shared library
 AC_DEFUN([AC_PATH_MAGIC],
 [AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
 if test -z "$lt_cv_path_MAGIC_CMD"; then
@@ -2097,7 +2230,7 @@
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
       lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some GNU ld's only accept -v.
+      # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
@@ -2129,7 +2262,7 @@
 AC_DEFUN([AC_PROG_LD_GNU],
 [AC_REQUIRE([AC_PROG_EGREP])dnl
 AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
 case `$LD -v 2>&1 </dev/null` in
 *GNU* | *'with BFD'*)
   lt_cv_prog_gnu_ld=yes
@@ -2159,7 +2292,7 @@
 case $host_os in
   darwin*)
     if test "$GCC" = yes; then
-      reload_cmds='$CC -nostdlib ${wl}-r -o $output$reload_objs'
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
     else
       reload_cmds='$LD$reload_flag -o $output$reload_objs'
     fi
@@ -2173,7 +2306,7 @@
 # how to check for library dependencies
 #  -- PORTME fill in with the dynamic library characteristics
 AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
-[AC_CACHE_CHECK([how to recognise dependent libraries],
+[AC_CACHE_CHECK([how to recognize dependent libraries],
 lt_cv_deplibs_check_method,
 [lt_cv_file_magic_cmd='$MAGIC_CMD'
 lt_cv_file_magic_test_file=
@@ -2212,16 +2345,22 @@
 
 mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
-  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
-  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
-  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
   ;;
 
 darwin* | rhapsody*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-freebsd* | kfreebsd*-gnu | dragonfly*)
+freebsd* | dragonfly*)
   if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
     case $host_cpu in
     i*86 )
@@ -2243,7 +2382,7 @@
 
 hpux10.20* | hpux11*)
   lt_cv_file_magic_cmd=/usr/bin/file
-  case "$host_cpu" in
+  case $host_cpu in
   ia64*)
     lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
     lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
@@ -2259,6 +2398,11 @@
   esac
   ;;
 
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
 irix5* | irix6* | nonstopux*)
   case $LD in
   *-32|*"-32 ") libmagic=32-bit;;
@@ -2270,7 +2414,7 @@
   ;;
 
 # This must be Linux ELF.
-linux*)
+linux* | k*bsd*-gnu)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
@@ -2304,7 +2448,7 @@
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-sco3.2v5*)
+rdos*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
@@ -2312,7 +2456,7 @@
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
   case $host_vendor in
   motorola)
     lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
@@ -2333,10 +2477,13 @@
   siemens)
     lt_cv_deplibs_check_method=pass_all
     ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
   esac
   ;;
 
-sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*)
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 esac
@@ -2356,36 +2503,43 @@
   # Let the user override the test.
   lt_cv_path_NM="$NM"
 else
-  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
-    IFS="$lt_save_ifs"
-    test -z "$ac_dir" && ac_dir=.
-    tmp_nm="$ac_dir/${ac_tool_prefix}nm"
-    if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
-      # Check to see if the nm accepts a BSD-compat flag.
-      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
-      #   nm: unknown option "B" ignored
-      # Tru64's nm complains that /dev/null is an invalid object file
-      case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
-      */dev/null* | *'Invalid file or object type'*)
-	lt_cv_path_NM="$tmp_nm -B"
-	break
-        ;;
-      *)
-	case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
-	*/dev/null*)
-	  lt_cv_path_NM="$tmp_nm -p"
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
 	  break
 	  ;;
 	*)
-	  lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
-	  continue # so that we can try to find one that supports BSD flags
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
 	  ;;
 	esac
-      esac
-    fi
+      fi
+    done
+    IFS="$lt_save_ifs"
   done
-  IFS="$lt_save_ifs"
   test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
 fi])
 NM="$lt_cv_path_NM"
@@ -2417,13 +2571,13 @@
 # -----------------------------------
 # sets LIBLTDL to the link flags for the libltdl convenience library and
 # LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-convenience to the configure arguments.  Note that LIBLTDL
-# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
-# DIRECTORY is not provided, it is assumed to be `libltdl'.  LIBLTDL will
-# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with
-# '${top_srcdir}/' (note the single quotes!).  If your package is not
-# flat and you're not using automake, define top_builddir and
-# top_srcdir appropriately in the Makefiles.
+# --enable-ltdl-convenience to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# it is assumed to be `libltdl'.  LIBLTDL will be prefixed with
+# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
+# (note the single quotes!).  If your package is not flat and you're not
+# using automake, define top_builddir and top_srcdir appropriately in
+# the Makefiles.
 AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
 [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
   case $enable_ltdl_convenience in
@@ -2442,13 +2596,13 @@
 # -----------------------------------
 # sets LIBLTDL to the link flags for the libltdl installable library and
 # LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-install to the configure arguments.  Note that LIBLTDL
-# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
-# DIRECTORY is not provided and an installed libltdl is not found, it is
-# assumed to be `libltdl'.  LIBLTDL will be prefixed with '${top_builddir}/'
-# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
-# quotes!).  If your package is not flat and you're not using automake,
-# define top_builddir and top_srcdir appropriately in the Makefiles.
+# --enable-ltdl-install to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# and an installed libltdl is not found, it is assumed to be `libltdl'.
+# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and top_srcdir
+# appropriately in the Makefiles.
 # In the future, this macro may have to be called after AC_PROG_LIBTOOL.
 AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
 [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
@@ -2491,7 +2645,7 @@
 ])# _LT_AC_LANG_CXX
 
 # _LT_AC_PROG_CXXCPP
-# ---------------
+# ------------------
 AC_DEFUN([_LT_AC_PROG_CXXCPP],
 [
 AC_REQUIRE([AC_PROG_CXX])
@@ -2540,7 +2694,7 @@
 
 
 # AC_LIBTOOL_RC
-# --------------
+# -------------
 # enable support for Windows resource files
 AC_DEFUN([AC_LIBTOOL_RC],
 [AC_REQUIRE([LT_AC_PROG_RC])
@@ -2566,10 +2720,10 @@
 _LT_AC_TAGVAR(objext, $1)=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;\n"
+lt_simple_compile_test_code="int some_variable = 0;"
 
 # Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}\n'
+lt_simple_link_test_code='int main(){return(0);}'
 
 _LT_AC_SYS_COMPILER
 
@@ -2577,37 +2731,6 @@
 _LT_COMPILER_BOILERPLATE
 _LT_LINKER_BOILERPLATE
 
-#
-# Check for any special shared library compilation flags.
-#
-_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)=
-if test "$GCC" = no; then
-  case $host_os in
-  sco3.2v5*)
-    _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf'
-    ;;
-  esac
-fi
-if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then
-  AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries])
-  if echo "$old_CC $old_CFLAGS " | grep "[[ 	]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ 	]]" >/dev/null; then :
-  else
-    AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure])
-    _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no
-  fi
-fi
-
-
-#
-# Check to make sure the static flag actually works.
-#
-AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works],
-  _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
-  $_LT_AC_TAGVAR(lt_prog_compiler_static, $1),
-  [],
-  [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
-
-
 AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
 AC_LIBTOOL_PROG_COMPILER_PIC($1)
 AC_LIBTOOL_PROG_CC_C_O($1)
@@ -2616,9 +2739,9 @@
 AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
 AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
 AC_LIBTOOL_SYS_LIB_STRIP
-AC_LIBTOOL_DLOPEN_SELF($1)
+AC_LIBTOOL_DLOPEN_SELF
 
-# Report which librarie types wil actually be built
+# Report which library types will actually be built
 AC_MSG_CHECKING([if libtool supports shared libraries])
 AC_MSG_RESULT([$can_build_shared])
 
@@ -2627,7 +2750,7 @@
 
 # On AIX, shared libraries and static libraries use the same namespace, and
 # are all built from PIC.
-case "$host_os" in
+case $host_os in
 aix3*)
   test "$enable_shared" = yes && enable_static=no
   if test -n "$RANLIB"; then
@@ -2677,6 +2800,7 @@
 _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
 _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
 _LT_AC_TAGVAR(hardcode_automatic, $1)=no
 _LT_AC_TAGVAR(module_cmds, $1)=
 _LT_AC_TAGVAR(module_expsym_cmds, $1)=
@@ -2694,17 +2818,17 @@
 _LT_AC_TAGVAR(compiler_lib_search_path, $1)=
 
 # Source file extension for C++ test sources.
-ac_ext=cc
+ac_ext=cpp
 
 # Object file extension for compiled C++ test sources.
 objext=o
 _LT_AC_TAGVAR(objext, $1)=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;\n"
+lt_simple_compile_test_code="int some_variable = 0;"
 
 # Code to be used in simple link tests
-lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
+lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 _LT_AC_SYS_COMPILER
@@ -2723,12 +2847,12 @@
 if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
   lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
 else
-  unset lt_cv_prog_gnu_ld
+  $as_unset lt_cv_prog_gnu_ld
 fi
 if test -n "${lt_cv_path_LDCXX+set}"; then
   lt_cv_path_LD=$lt_cv_path_LDCXX
 else
-  unset lt_cv_path_LD
+  $as_unset lt_cv_path_LD
 fi
 test -z "${LDCXX+set}" || LD=$LDCXX
 CC=${CXX-"c++"}
@@ -2823,6 +2947,7 @@
 	    ;;
 	  esac
 	done
+	;;
       esac
 
       exp_sym_flag='-bexport'
@@ -2849,7 +2974,7 @@
 	   strings "$collect2name" | grep resolve_lib_name >/dev/null
 	then
 	  # We have reworked collect2
-	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	  :
 	else
 	  # We have old collect2
 	  _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
@@ -2860,6 +2985,7 @@
 	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
 	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
 	fi
+	;;
       esac
       shared_flag='-shared'
       if test "$aix_use_runtimelinking" = yes; then
@@ -2891,12 +3017,12 @@
       _LT_AC_SYS_LIBPATH_AIX
       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-      _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
      else
       if test "$host_cpu" = ia64; then
 	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	_LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
       else
 	# Determine the default libpath from the value encoded in an empty executable.
 	_LT_AC_SYS_LIBPATH_AIX
@@ -2905,16 +3031,26 @@
 	# -berok will link without error, but may produce a broken library.
 	_LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
 	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
-	# -bexpall does not export symbols beginning with underscore (_)
-	_LT_AC_TAGVAR(always_export_symbols, $1)=yes
 	# Exported symbols can be pulled into shared objects from archives
-	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
-	# This is similar to how AIX traditionally builds it's shared libraries.
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	# This is similar to how AIX traditionally builds its shared libraries.
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
       fi
     fi
     ;;
+
+  beos*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+    ;;
+
   chorus*)
     case $cc_basename in
       *)
@@ -2924,7 +3060,6 @@
     esac
     ;;
 
-
   cygwin* | mingw* | pw32*)
     # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
     # as there is no search path for DLLs.
@@ -2934,7 +3069,7 @@
     _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 
     if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
-      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       # If the export-symbols file already is a .def file (1st line
       # is EXPORTS), use it as is; otherwise, prepend...
       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -2943,13 +3078,13 @@
 	echo EXPORTS > $output_objdir/$soname.def;
 	cat $export_symbols >> $output_objdir/$soname.def;
       fi~
-      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
     else
       _LT_AC_TAGVAR(ld_shlibs, $1)=no
     fi
   ;;
       darwin* | rhapsody*)
-        case "$host_os" in
+        case $host_os in
         rhapsody* | darwin1.[[012]])
          _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
          ;;
@@ -2987,7 +3122,7 @@
           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
         fi
         _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
           if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
             _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           else
@@ -2998,10 +3133,10 @@
       case $cc_basename in
         xlc*)
          output_verbose_link_cmd='echo'
-          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
           _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
-          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           ;;
        *)
@@ -3035,7 +3170,7 @@
   freebsd-elf*)
     _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
     ;;
-  freebsd* | kfreebsd*-gnu | dragonfly*)
+  freebsd* | dragonfly*)
     # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
     # conventions
     _LT_AC_TAGVAR(ld_shlibs, $1)=yes
@@ -3080,34 +3215,21 @@
     ;;
   hpux10*|hpux11*)
     if test $with_gnu_ld = no; then
-      case "$host_cpu" in
-      hppa*64*)
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-        ;;
-      ia64*)
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-        ;;
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+      case $host_cpu in
+      hppa*64*|ia64*) ;;
       *)
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
 	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
         ;;
       esac
     fi
-    case "$host_cpu" in
-    hppa*64*)
+    case $host_cpu in
+    hppa*64*|ia64*)
       _LT_AC_TAGVAR(hardcode_direct, $1)=no
       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
       ;;
-    ia64*)
-      _LT_AC_TAGVAR(hardcode_direct, $1)=no
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
-					      # but as the default
-					      # location of the library.
-      ;;
     *)
       _LT_AC_TAGVAR(hardcode_direct, $1)=yes
       _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
@@ -3122,10 +3244,13 @@
 	_LT_AC_TAGVAR(ld_shlibs, $1)=no
 	;;
       aCC*)
-	case "$host_cpu" in
-	hppa*64*|ia64*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+	case $host_cpu in
+	hppa*64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	  ;;
+	ia64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
 	*)
 	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	  ;;
@@ -3143,10 +3268,13 @@
       *)
 	if test "$GXX" = yes; then
 	  if test $with_gnu_ld = no; then
-	    case "$host_cpu" in
-	    ia64*|hppa*64*)
-	      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+	    case $host_cpu in
+	    hppa*64*)
+	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	      ;;
+	    ia64*)
+	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
 	    *)
 	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	      ;;
@@ -3159,6 +3287,20 @@
 	;;
     esac
     ;;
+  interix[[3-9]]*)
+    _LT_AC_TAGVAR(hardcode_direct, $1)=no
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+    # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+    # Instead, shared libraries are loaded at an image base (0x10000000 by
+    # default) and relocated if they conflict, which is a slow very memory
+    # consuming and fragmenting process.  To avoid this, we pick a random,
+    # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+    # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    ;;
   irix5* | irix6*)
     case $cc_basename in
       CC*)
@@ -3185,7 +3327,7 @@
     _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
     _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
     ;;
-  linux*)
+  linux* | k*bsd*-gnu)
     case $cc_basename in
       KCC*)
 	# Kuck and Associates, Inc. (KAI) C++ Compiler
@@ -3244,7 +3386,7 @@
 
 	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
 	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
         ;;
       cxx*)
 	# Compaq C++
@@ -3265,6 +3407,29 @@
 	# dependencies.
 	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
 	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C++ 5.9
+	  _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+
+	  # Not sure whether something based on
+	  # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	  # would be better.
+	  output_verbose_link_cmd='echo'
+
+	  # Archives containing C++ object files must be created using
+	  # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	  # necessary to make sure instantiated templates are included
+	  # in the archive.
+	  _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	  ;;
+	esac
+	;;
     esac
     ;;
   lynxos*)
@@ -3303,16 +3468,20 @@
     _LT_AC_TAGVAR(ld_shlibs, $1)=no
     ;;
   openbsd*)
-    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-    if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
-      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    if test -f /usr/libexec/ld.so; then
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      fi
+      output_verbose_link_cmd='echo'
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
     fi
-    output_verbose_link_cmd='echo'
     ;;
   osf3*)
     case $cc_basename in
@@ -3441,19 +3610,6 @@
     # FIXME: insert proper C++ library support
     _LT_AC_TAGVAR(ld_shlibs, $1)=no
     ;;
-  sco*)
-    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-    case $cc_basename in
-      CC*)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-      *)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-    esac
-    ;;
   sunos4*)
     case $cc_basename in
       CC*)
@@ -3476,38 +3632,26 @@
     case $cc_basename in
       CC*)
 	# Sun C++ 4.2, 5.x and Centerline C++
+        _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes
 	_LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-	$CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+	$CC -G${allow_undefined_flag}  ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
 
 	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
 	_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
 	case $host_os in
 	  solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
 	  *)
-	    # The C++ compiler is used as linker so we must use $wl
-	    # flag to pass the commands to the underlying system
-	    # linker. We must also pass each convience library through
-	    # to the system linker between allextract/defaultextract.
-	    # The C++ compiler will combine linker options so we
-	    # cannot just pass the convience library names through
-	    # without $wl.
+	    # The compiler driver will combine and reorder linker options,
+	    # but understands `-z linker_flag'.
 	    # Supported since Solaris 2.6 (maybe 2.5.1?)
-	    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
+	    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	    ;;
 	esac
 	_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
 
-	# Commands to make compiler produce verbose output that lists
-	# what "hidden" libraries, object files and flags are used when
-	# linking a shared library.
-	#
-	# There doesn't appear to be a way to prevent this compiler from
-	# explicitly linking system object files so we need to strip them
-	# from the output so that they don't get included in the library
-	# dependencies.
-	output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	output_verbose_link_cmd='echo'
 
 	# Archives containing C++ object files must be created using
 	# "CC -xar", where "CC" is the Sun C++ compiler.  This is
@@ -3549,13 +3693,70 @@
 	  fi
 
 	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	  case $host_os in
+	  solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	  *)
+	    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	    ;;
+	  esac
 	fi
 	;;
     esac
     ;;
-  sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*)
+  sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+    _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
     _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      *)
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+    esac
     ;;
+  sysv5* | sco3.2v5* | sco5v6*)
+    # Note: We can NOT use -z defs as we might desire, because we do not
+    # link with -lc, and that would cause any symbols used from libc to
+    # always be unresolved, which means just about no library would
+    # ever link correctly.  If we're not using GNU ld we use -z text
+    # though, which does catch some bad symbols but isn't as heavy-handed
+    # as -z defs.
+    # For security reasons, it is highly recommended that you always
+    # use absolute paths for naming shared libraries, and exclude the
+    # DT_RUNPATH tag from executables and libraries.  But doing so
+    # requires that you compile everything twice, which is a pain.
+    # So that behaviour is only enabled if SCOABSPATH is set to a
+    # non-empty value in the environment.  Most likely only useful for
+    # creating official distributions of packages.
+    # This is a hack until libtool officially supports absolute path
+    # names for shared libraries.
+    _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+    _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      *)
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+    esac
+    ;;
   tandem*)
     case $cc_basename in
       NCC*)
@@ -3591,8 +3792,6 @@
 AC_LIBTOOL_PROG_LD_SHLIBS($1)
 AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
 AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-AC_LIBTOOL_SYS_LIB_STRIP
-AC_LIBTOOL_DLOPEN_SELF($1)
 
 AC_LIBTOOL_CONFIG($1)
 
@@ -3610,7 +3809,7 @@
 ])# AC_LIBTOOL_LANG_CXX_CONFIG
 
 # AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
-# ------------------------
+# ------------------------------------
 # Figure out "hidden" library dependencies from verbose
 # compiler output when linking a shared library.
 # Parse the compiler output and extract the necessary
@@ -3664,7 +3863,7 @@
   # The `*' in the case matches for architectures that use `case' in
   # $output_verbose_cmd can trigger glob expansion during the loop
   # eval without this substitution.
-  output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+  output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
 
   for p in `eval $output_verbose_link_cmd`; do
     case $p in
@@ -3740,13 +3939,70 @@
 
 $rm -f confest.$objext
 
+# PORTME: override above test on systems where it is broken
+ifelse([$1],[CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_AC_TAGVAR(predep_objects,$1)=
+  _LT_AC_TAGVAR(postdep_objects,$1)=
+  _LT_AC_TAGVAR(postdeps,$1)=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+    #
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+])
+
 case " $_LT_AC_TAGVAR(postdeps, $1) " in
 *" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
 esac
 ])# AC_LIBTOOL_POSTDEP_PREDEP
 
 # AC_LIBTOOL_LANG_F77_CONFIG
-# ------------------------
+# --------------------------
 # Ensure that the configuration vars for the C compiler are
 # suitably defined.  Those variables are subsequently used by
 # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
@@ -3782,10 +4038,17 @@
 _LT_AC_TAGVAR(objext, $1)=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
 
 # Code to be used in simple link tests
-lt_simple_link_test_code="      program t\n      end\n"
+lt_simple_link_test_code="\
+      program t
+      end
+"
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 _LT_AC_SYS_COMPILER
@@ -3809,7 +4072,7 @@
 
 # On AIX, shared libraries and static libraries use the same namespace, and
 # are all built from PIC.
-case "$host_os" in
+case $host_os in
 aix3*)
   test "$enable_shared" = yes && enable_static=no
   if test -n "$RANLIB"; then
@@ -3830,8 +4093,6 @@
 test "$enable_shared" = yes || enable_static=yes
 AC_MSG_RESULT([$enable_static])
 
-test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-
 _LT_AC_TAGVAR(GCC, $1)="$G77"
 _LT_AC_TAGVAR(LD, $1)="$LD"
 
@@ -3841,9 +4102,7 @@
 AC_LIBTOOL_PROG_LD_SHLIBS($1)
 AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
 AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-AC_LIBTOOL_SYS_LIB_STRIP
 
-
 AC_LIBTOOL_CONFIG($1)
 
 AC_LANG_POP
@@ -3868,10 +4127,10 @@
 _LT_AC_TAGVAR(objext, $1)=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code="class foo {}\n"
+lt_simple_compile_test_code="class foo {}"
 
 # Code to be used in simple link tests
-lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n'
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 _LT_AC_SYS_COMPILER
@@ -3899,8 +4158,6 @@
 AC_LIBTOOL_PROG_LD_SHLIBS($1)
 AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
 AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-AC_LIBTOOL_SYS_LIB_STRIP
-AC_LIBTOOL_DLOPEN_SELF($1)
 
 AC_LIBTOOL_CONFIG($1)
 
@@ -3910,7 +4167,7 @@
 
 
 # AC_LIBTOOL_LANG_RC_CONFIG
-# --------------------------
+# -------------------------
 # Ensure that the configuration vars for the Windows resource compiler are
 # suitably defined.  Those variables are subsequently used by
 # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
@@ -3926,7 +4183,7 @@
 _LT_AC_TAGVAR(objext, $1)=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
 
 # Code to be used in simple link tests
 lt_simple_link_test_code="$lt_simple_compile_test_code"
@@ -3973,7 +4230,7 @@
   # Now quote all the things that may contain metacharacters while being
   # careful not to overquote the AC_SUBSTed values.  We take copies of the
   # variables and quote the copies for generation of the libtool script.
-  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
     SED SHELL STRIP \
     libname_spec library_names_spec soname_spec extract_expsyms_cmds \
     old_striplib striplib file_magic_cmd finish_cmds finish_eval \
@@ -4015,6 +4272,7 @@
     _LT_AC_TAGVAR(module_cmds, $1) \
     _LT_AC_TAGVAR(module_expsym_cmds, $1) \
     _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
+    _LT_AC_TAGVAR(fix_srcfile_path, $1) \
     _LT_AC_TAGVAR(exclude_expsyms, $1) \
     _LT_AC_TAGVAR(include_expsyms, $1); do
 
@@ -4061,7 +4319,7 @@
 # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 #
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
 # Free Software Foundation, Inc.
 #
 # This file is part of GNU Libtool:
@@ -4142,6 +4400,9 @@
 # A C compiler.
 LTCC=$lt_LTCC
 
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
 # A language-specific compiler.
 CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
 
@@ -4383,7 +4644,7 @@
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
 
 # Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)"
+fix_srcfile_path=$lt_fix_srcfile_path
 
 # Set to yes if exported symbols are required.
 always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
@@ -4466,6 +4727,7 @@
 # ---------------------------------
 AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
 [AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([LT_AC_PROG_SED])
 AC_REQUIRE([AC_PROG_NM])
 AC_REQUIRE([AC_OBJEXT])
 # Check for command to grab the raw symbol name followed by C symbol from nm.
@@ -4502,7 +4764,7 @@
   lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
   lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
   ;;
-linux*)
+linux* | k*bsd*-gnu)
   if test "$host_cpu" = ia64; then
     symcode='[[ABCDGIRSTW]]'
     lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
@@ -4515,9 +4777,18 @@
 osf*)
   symcode='[[BCDEGQRST]]'
   ;;
-solaris* | sysv5*)
+solaris*)
   symcode='[[BDRT]]'
   ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
 sysv4)
   symcode='[[DFNSTU]]'
   ;;
@@ -4683,12 +4954,14 @@
       # like `-m68040'.
       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
       ;;
-    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
       # PIC is the default for these OSes.
       ;;
-    mingw* | os2* | pw32*)
+    mingw* | cygwin* | os2* | pw32*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
       ;;
     darwin* | rhapsody*)
@@ -4700,6 +4973,10 @@
       # DJGPP does not support shared libraries at all
       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
       ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
     sysv4*MP*)
       if test -d /usr/nec; then
 	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
@@ -4708,7 +4985,7 @@
     hpux*)
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	;;
       *)
@@ -4762,22 +5039,22 @@
 	    ;;
 	esac
 	;;
-      freebsd* | kfreebsd*-gnu | dragonfly*)
+      freebsd* | dragonfly*)
 	# FreeBSD uses GNU C++
 	;;
       hpux9* | hpux10* | hpux11*)
 	case $cc_basename in
 	  CC*)
 	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
 	    if test "$host_cpu" != ia64; then
 	      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
 	    fi
 	    ;;
 	  aCC*)
 	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
-	    case "$host_cpu" in
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
 	    hppa*64*|ia64*)
 	      # +Z the default
 	      ;;
@@ -4790,6 +5067,10 @@
 	    ;;
 	esac
 	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
       irix5* | irix6* | nonstopux*)
 	case $cc_basename in
 	  CC*)
@@ -4801,7 +5082,7 @@
 	    ;;
 	esac
 	;;
-      linux*)
+      linux* | k*bsd*-gnu)
 	case $cc_basename in
 	  KCC*)
 	    # KAI C++ Compiler
@@ -4818,7 +5099,7 @@
 	    # Portland Group C++ compiler.
 	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	    ;;
 	  cxx*)
 	    # Compaq C++
@@ -4828,6 +5109,14 @@
 	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
 	    ;;
 	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
 	    ;;
 	esac
 	;;
@@ -4869,15 +5158,6 @@
 	;;
       psos*)
 	;;
-      sco*)
-	case $cc_basename in
-	  CC*)
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-	    ;;
-	  *)
-	    ;;
-	esac
-	;;
       solaris*)
 	case $cc_basename in
 	  CC*)
@@ -4919,7 +5199,14 @@
 	    ;;
 	esac
 	;;
-      unixware*)
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
 	;;
       vxworks*)
 	;;
@@ -4950,13 +5237,15 @@
       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
       ;;
 
-    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
       # PIC is the default for these OSes.
       ;;
 
-    mingw* | pw32* | os2*)
+    mingw* | cygwin* | pw32* | os2*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
       ;;
 
@@ -4966,6 +5255,11 @@
       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
       ;;
 
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
     msdosdjgpp*)
       # Just because we use GCC doesn't mean we suddenly get shared libraries
       # on systems that don't support them.
@@ -4982,7 +5276,7 @@
     hpux*)
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	# +Z the default
 	;;
@@ -5019,7 +5313,7 @@
        esac
        ;;
 
-    mingw* | pw32* | os2*)
+    mingw* | cygwin* | pw32* | os2*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
@@ -5029,7 +5323,7 @@
       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	# +Z the default
 	;;
@@ -5052,25 +5346,41 @@
       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       ;;
 
-    linux*)
+    linux* | k*bsd*-gnu)
       case $cc_basename in
       icc* | ecc*)
 	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
 	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
         ;;
-      pgcc* | pgf77* | pgf90*)
+      pgcc* | pgf77* | pgf90* | pgf95*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
 	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
-	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
         ;;
       ccc*)
         _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
         # All Alpha code is PIC.
         _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
         ;;
+      *)
+        case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	esac
+	;;
       esac
       ;;
 
@@ -5080,9 +5390,8 @@
       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
       ;;
 
-    sco3.2v5*)
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic'
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn'
+    rdos*)
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
       ;;
 
     solaris*)
@@ -5102,7 +5411,7 @@
       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       ;;
 
-    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    sysv4 | sysv4.2uw2* | sysv4.3*)
       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
@@ -5115,6 +5424,12 @@
       fi
       ;;
 
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
     unicos*)
       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
       _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
@@ -5147,7 +5462,7 @@
     [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
 fi
-case "$host_os" in
+case $host_os in
   # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
@@ -5156,6 +5471,16 @@
     _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
     ;;
 esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\"
+AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
 ])
 
 
@@ -5163,7 +5488,8 @@
 # ------------------------------------
 # See if the linker supports building shared libraries.
 AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
-[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+[AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
 ifelse([$1],[CXX],[
   _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
   case $host_os in
@@ -5180,7 +5506,7 @@
     _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
   ;;
   cygwin* | mingw*)
-    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
   ;;
   *)
     _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
@@ -5234,6 +5560,10 @@
       with_gnu_ld=no
     fi
     ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
   openbsd*)
     with_gnu_ld=no
     ;;
@@ -5243,7 +5573,7 @@
   if test "$with_gnu_ld" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
     wlarc='${wl}'
-    
+
     # Set some defaults for GNU ld with shared library support. These
     # are reset later if shared libraries are not supported. Putting them
     # here allows them to be overridden if necessary.
@@ -5264,7 +5594,7 @@
       *\ 2.11.*) ;; # other 2.11 versions
       *) supports_anon_versioning=yes ;;
     esac
-    
+
     # See if GNU ld supports shared libraries.
     case $host_os in
     aix3* | aix4* | aix5*)
@@ -5315,10 +5645,10 @@
       _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
       _LT_AC_TAGVAR(always_export_symbols, $1)=no
       _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
 
       if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
-        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	# If the export-symbols file already is a .def file (1st line
 	# is EXPORTS), use it as is; otherwise, prepend...
 	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -5327,22 +5657,37 @@
 	  echo EXPORTS > $output_objdir/$soname.def;
 	  cat $export_symbols >> $output_objdir/$soname.def;
 	fi~
-	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	_LT_AC_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
 
-    linux*)
+    interix[[3-9]]*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | k*bsd*-gnu)
       if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
 	tmp_addflag=
 	case $cc_basename,$host_cpu in
 	pgcc*)				# Portland Group C compiler
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
-	pgf77* | pgf90* )			# Portland Group f77 and f90 compilers
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)		# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -5351,13 +5696,22 @@
 	ifc* | ifort*)			# Intel Fortran compiler
 	  tmp_addflag=' -nofor_main' ;;
 	esac
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	*)
+	  tmp_sharedflag='-shared' ;;
+	esac
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
 	if test $supports_anon_versioning = yes; then
 	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
   cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
   $echo "local: *; };" >> $output_objdir/$libname.ver~
-	  $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	  $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	fi
       else
 	_LT_AC_TAGVAR(ld_shlibs, $1)=no
@@ -5374,7 +5728,7 @@
       fi
       ;;
 
-    solaris* | sysv5*)
+    solaris*)
       if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
 	_LT_AC_TAGVAR(ld_shlibs, $1)=no
 	cat <<EOF 1>&2
@@ -5395,6 +5749,33 @@
       fi
       ;;
 
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+	    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+	  else
+	    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
     sunos4*)
       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
       wlarc=
@@ -5428,7 +5809,7 @@
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-      if test "$GCC" = yes && test -z "$link_static_flag"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	_LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
@@ -5462,6 +5843,7 @@
   	    break
   	  fi
 	  done
+	  ;;
 	esac
 
 	exp_sym_flag='-bexport'
@@ -5488,7 +5870,7 @@
   	   strings "$collect2name" | grep resolve_lib_name >/dev/null
 	  then
   	  # We have reworked collect2
-  	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+  	  :
 	  else
   	  # We have old collect2
   	  _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
@@ -5499,6 +5881,7 @@
   	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
   	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
 	  fi
+	  ;;
 	esac
 	shared_flag='-shared'
 	if test "$aix_use_runtimelinking" = yes; then
@@ -5511,11 +5894,11 @@
   	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-  	if test "$aix_use_runtimelinking" = yes; then
+	  if test "$aix_use_runtimelinking" = yes; then
 	    shared_flag='${wl}-G'
 	  else
 	    shared_flag='${wl}-bM:SRE'
-  	fi
+	  fi
 	fi
       fi
 
@@ -5529,12 +5912,12 @@
        # Determine the default libpath from the value encoded in an empty executable.
        _LT_AC_SYS_LIBPATH_AIX
        _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
        else
 	if test "$host_cpu" = ia64; then
 	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	  _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an empty executable.
 	 _LT_AC_SYS_LIBPATH_AIX
@@ -5543,13 +5926,11 @@
 	  # -berok will link without error, but may produce a broken library.
 	  _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
 	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
-	  # -bexpall does not export symbols beginning with underscore (_)
-	  _LT_AC_TAGVAR(always_export_symbols, $1)=yes
 	  # Exported symbols can be pulled into shared objects from archives
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
-	  # This is similar to how AIX traditionally builds it's shared libraries.
-	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -5582,13 +5963,13 @@
       # The linker will automatically build a .lib file if we build a DLL.
       _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
       # FIXME: Should let the user specify the lib program.
-      _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      _LT_AC_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
       _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
       _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
       ;;
 
     darwin* | rhapsody*)
-      case "$host_os" in
+      case $host_os in
         rhapsody* | darwin1.[[012]])
          _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
          ;;
@@ -5617,17 +5998,17 @@
     	output_verbose_link_cmd='echo'
         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
       _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
       _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
     else
       case $cc_basename in
         xlc*)
          output_verbose_link_cmd='echo'
-         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
          _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
-         _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           ;;
        *)
@@ -5667,7 +6048,7 @@
       ;;
 
     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
-    freebsd* | kfreebsd*-gnu | dragonfly*)
+    freebsd* | dragonfly*)
       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
       _LT_AC_TAGVAR(hardcode_direct, $1)=yes
@@ -5690,47 +6071,62 @@
       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
       ;;
 
-    hpux10* | hpux11*)
+    hpux10*)
       if test "$GCC" = yes -a "$with_gnu_ld" = no; then
-	case "$host_cpu" in
-	hppa*64*|ia64*)
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	_LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
 	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
+	ia64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
 	*)
 	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
-	case "$host_cpu" in
-	hppa*64*|ia64*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+	case $host_cpu in
+	hppa*64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
+	ia64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
 	*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       fi
       if test "$with_gnu_ld" = no; then
-	case "$host_cpu" in
-	hppa*64*)
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
 	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
-	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
 	  _LT_AC_TAGVAR(hardcode_direct, $1)=no
 	  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
 	  ;;
-	ia64*)
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	  _LT_AC_TAGVAR(hardcode_direct, $1)=no
-	  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-
-	  # hardcode_minus_L: Not really in the search PATH,
-	  # but as the default location of the library.
-	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-	  ;;
 	*)
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
 	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
 	  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 
@@ -5774,24 +6170,28 @@
       ;;
 
     openbsd*)
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      if test -f /usr/libexec/ld.so; then
+	_LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+	if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+        fi
       else
-       case $host_os in
-	 openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
-	   _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-	   _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-	   ;;
-	 *)
-	   _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	   _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-	   ;;
-       esac
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
 
@@ -5832,14 +6232,6 @@
       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
       ;;
 
-    sco3.2v5*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
-      runpath_var=LD_RUN_PATH
-      hardcode_runpath_var=yes
-      ;;
-
     solaris*)
       _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
       if test "$GCC" = yes; then
@@ -5858,17 +6250,16 @@
       case $host_os in
       solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
       *)
- 	# The compiler driver will combine linker options so we
- 	# cannot just pass the convience library names through
- 	# without $wl, iff we do not link with $LD.
- 	# Luckily, gcc supports the same syntax we need for Sun Studio.
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
  	# Supported since Solaris 2.6 (maybe 2.5.1?)
- 	case $wlarc in
- 	'')
- 	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
- 	*)
- 	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
- 	esac ;;
+	if test "$GCC" = yes; then
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
       esac
       _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
       ;;
@@ -5925,36 +6316,45 @@
       fi
       ;;
 
-    sysv4.2uw2*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      hardcode_runpath_var=yes
-      runpath_var=LD_RUN_PATH
-      ;;
+      runpath_var='LD_RUN_PATH'
 
-   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[[78]]* | unixware7*)
-      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text'
       if test "$GCC" = yes; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
-      runpath_var='LD_RUN_PATH'
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
       ;;
 
-    sysv5*)
-      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
-      # $CC -shared without GNU ld will not create a library from C++
-      # object files and a static libstdc++, better avoid it by now
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-  		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
       ;;
 
     uts4*)
@@ -5972,11 +6372,6 @@
 AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
 test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
-  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
 #
 # Do we need to explicitly link libc?
 #
@@ -5996,7 +6391,7 @@
       # to ld, don't add -lc before -lgcc.
       AC_MSG_CHECKING([whether -lc should be explicitly linked in])
       $rm conftest*
-      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
       if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
         soname=conftest
@@ -6004,6 +6399,7 @@
         libobjs=conftest.$ac_objext
         deplibs=
         wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+	pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
         compiler_flags=-v
         linker_flags=-v
         verstring=
@@ -6098,6 +6494,30 @@
 [AC_CHECK_TOOL(RC, windres, no)
 ])
 
+
+# Cheap backport of AS_EXECUTABLE_P and required macros
+# from Autoconf 2.59; we should not use $as_executable_p directly.
+
+# _AS_TEST_PREPARE
+# ----------------
+m4_ifndef([_AS_TEST_PREPARE],
+[m4_defun([_AS_TEST_PREPARE],
+[if test -x / >/dev/null 2>&1; then
+  as_executable_p='test -x'
+else
+  as_executable_p='test -f'
+fi
+])])# _AS_TEST_PREPARE
+
+# AS_EXECUTABLE_P
+# ---------------
+# Check whether a file is executable.
+m4_ifndef([AS_EXECUTABLE_P],
+[m4_defun([AS_EXECUTABLE_P],
+[AS_REQUIRE([_AS_TEST_PREPARE])dnl
+$as_executable_p $1[]dnl
+])])# AS_EXECUTABLE_P
+
 # NOTE: This macro has been submitted for inclusion into   #
 #  GNU Autoconf as AC_PROG_SED.  When it is available in   #
 #  a released version of Autoconf we should remove this    #
@@ -6118,12 +6538,13 @@
   test -z "$as_dir" && as_dir=.
   for lt_ac_prog in sed gsed; do
     for ac_exec_ext in '' $ac_executable_extensions; do
-      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+      if AS_EXECUTABLE_P(["$as_dir/$lt_ac_prog$ac_exec_ext"]); then
         lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
       fi
     done
   done
 done
+IFS=$as_save_IFS
 lt_ac_max=0
 lt_ac_count=0
 # Add /usr/xpg4/bin/sed as it is typically found on Solaris
@@ -6156,10 +6577,11 @@
 done
 ])
 SED=$lt_cv_path_SED
+AC_SUBST([SED])
 AC_MSG_RESULT([$SED])
 ])
 
-# Copyright (C) 2002, 2003, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2005, 2006  Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -6169,14 +6591,29 @@
 # ----------------------------
 # Automake X.Y traces this macro to ensure aclocal.m4 has been
 # generated from the m4 files accompanying Automake X.Y.
-AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.10'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.10], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
 
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
 # AM_SET_CURRENT_AUTOMAKE_VERSION
 # -------------------------------
-# Call AM_AUTOMAKE_VERSION so it can be traced.
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-	 [AM_AUTOMAKE_VERSION([1.9.6])])
+[AM_AUTOMAKE_VERSION([1.10])dnl
+_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
@@ -6233,14 +6670,14 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006
 # Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 7
+# serial 8
 
 # AM_CONDITIONAL(NAME, SHELL-CONDITION)
 # -------------------------------------
@@ -6249,8 +6686,10 @@
 [AC_PREREQ(2.52)dnl
  ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
 	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
-AC_SUBST([$1_TRUE])
-AC_SUBST([$1_FALSE])
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
 if $2; then
   $1_TRUE=
   $1_FALSE='#'
@@ -6264,15 +6703,14 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
 # Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 8
+# serial 9
 
 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
 # written in clear, in which case automake, when reading aclocal.m4,
@@ -6300,6 +6738,7 @@
 ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
        [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
        [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], UPC,  [depcc="$UPC"  am_compiler_list=],
        [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
                    [depcc="$$1"   am_compiler_list=])
 
@@ -6365,6 +6804,7 @@
        depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
        $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
          >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
        grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
        grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
        ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
@@ -6417,7 +6857,8 @@
   AMDEPBACKSLASH='\'
 fi
 AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
-AC_SUBST([AMDEPBACKSLASH])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
 ])
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
@@ -6442,8 +6883,9 @@
   # some people rename them; so instead we look at the file content.
   # Grep'ing the first line is not enough: some people post-process
   # each Makefile.in and add a new line on top of each file to say so.
-  # So let's grep whole file.
-  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+  # Grep'ing the whole file is not good either: AIX grep has a line
+  # limit of 2048, but all sed's we know have understand at least 4000.
+  if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
     dirpart=`AS_DIRNAME("$mf")`
   else
     continue
@@ -6502,8 +6944,8 @@
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -6526,16 +6968,20 @@
 # arguments mandatory, and then we can depend on a new Autoconf
 # release and drop the old call support.
 AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.58])dnl
+[AC_PREREQ([2.60])dnl
 dnl Autoconf wants to disallow AM_ names.  We explicitly allow
 dnl the ones we care about.
 m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
 AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
 AC_REQUIRE([AC_PROG_INSTALL])dnl
-# test to see if srcdir already configured
-if test "`cd $srcdir && pwd`" != "`pwd`" &&
-   test -f $srcdir/config.status; then
-  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
 fi
 
 # test whether we have cygpath
@@ -6555,6 +7001,9 @@
  AC_SUBST([PACKAGE], [$1])dnl
  AC_SUBST([VERSION], [$2])],
 [_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
  AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
  AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
 
@@ -6590,6 +7039,10 @@
                   [_AM_DEPENDENCIES(CXX)],
                   [define([AC_PROG_CXX],
                           defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+                  [_AM_DEPENDENCIES(OBJC)],
+                  [define([AC_PROG_OBJC],
+                          defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
 ])
 ])
 
@@ -6625,7 +7078,7 @@
 # Define $install_sh.
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-install_sh=${install_sh-"$am_aux_dir/install-sh"}
+install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
 AC_SUBST(install_sh)])
 
 # Copyright (C) 2003, 2005  Free Software Foundation, Inc.
@@ -6703,14 +7156,14 @@
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
 # Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 4
+# serial 5
 
 # AM_MISSING_PROG(NAME, PROGRAM)
 # ------------------------------
@@ -6726,6 +7179,7 @@
 # If it does, set am_missing_run to use it, otherwise, to nothing.
 AC_DEFUN([AM_MISSING_HAS_RUN],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
 test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
 # Use eval to expand $SHELL
 if eval "$MISSING --run true"; then
@@ -6736,7 +7190,7 @@
 fi
 ])
 
-# Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -6744,60 +7198,23 @@
 
 # AM_PROG_MKDIR_P
 # ---------------
-# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
-#
-# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
-# created by `make install' are always world readable, even if the
-# installer happens to have an overly restrictive umask (e.g. 077).
-# This was a mistake.  There are at least two reasons why we must not
-# use `-m 0755':
-#   - it causes special bits like SGID to be ignored,
-#   - it may be too restrictive (some setups expect 775 directories).
-#
-# Do not use -m 0755 and let people choose whatever they expect by
-# setting umask.
-#
-# We cannot accept any implementation of `mkdir' that recognizes `-p'.
-# Some implementations (such as Solaris 8's) are not thread-safe: if a
-# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
-# concurrently, both version can detect that a/ is missing, but only
-# one can create it and the other will error out.  Consequently we
-# restrict ourselves to GNU make (using the --version option ensures
-# this.)
+# Check for `mkdir -p'.
 AC_DEFUN([AM_PROG_MKDIR_P],
-[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
-  # We used to keeping the `.' as first argument, in order to
-  # allow $(mkdir_p) to be used without argument.  As in
-  #   $(mkdir_p) $(somedir)
-  # where $(somedir) is conditionally defined.  However this is wrong
-  # for two reasons:
-  #  1. if the package is installed by a user who cannot write `.'
-  #     make install will fail,
-  #  2. the above comment should most certainly read
-  #     $(mkdir_p) $(DESTDIR)$(somedir)
-  #     so it does not work when $(somedir) is undefined and
-  #     $(DESTDIR) is not.
-  #  To support the latter case, we have to write
-  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
-  #  so the `.' trick is pointless.
-  mkdir_p='mkdir -p --'
-else
-  # On NextStep and OpenStep, the `mkdir' command does not
-  # recognize any option.  It will interpret all options as
-  # directories to create, and then abort because `.' already
-  # exists.
-  for d in ./-p ./--version;
-  do
-    test -d $d && rmdir $d
-  done
-  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
-  if test -f "$ac_aux_dir/mkinstalldirs"; then
-    mkdir_p='$(mkinstalldirs)'
-  else
-    mkdir_p='$(install_sh) -d'
-  fi
-fi
-AC_SUBST([mkdir_p])])
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+  [[\\/$]]* | ?:[[\\/]]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
@@ -6909,9 +7326,21 @@
 if test "$cross_compiling" != no; then
   AC_CHECK_TOOL([STRIP], [strip], :)
 fi
-INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
+# Copyright (C) 2006  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
 # Check how to create a tarball.                            -*- Autoconf -*-
 
 # Copyright (C) 2004, 2005  Free Software Foundation, Inc.

Modified: openldap/trunk/contrib/ldapc++/configure
===================================================================
--- openldap/trunk/contrib/ldapc++/configure	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/configure	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,26 +1,55 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59.
+# Generated by GNU Autoconf 2.61 for ldapcpplib 0.0.5.
 #
-# Copyright (C) 2003 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
 ## --------------------- ##
 ## M4sh Initialization.  ##
 ## --------------------- ##
 
-# Be Bourne compatible
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   emulate sh
   NULLCMD=:
   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
-  set -o posix
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
 fi
-DUALCASE=1; export DUALCASE # for MKS sh
 
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
 # Support unset when possible.
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
@@ -29,8 +58,43 @@
 fi
 
 
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
 # Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
 PS1='$ '
 PS2='> '
 PS4='+ '
@@ -44,18 +108,19 @@
   if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
-    $as_unset $as_var
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
   fi
 done
 
 # Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
@@ -63,157 +128,388 @@
 
 
 # Name of the executable.
-as_me=`$as_basename "$0" ||
+as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)$' \| \
-	 .     : '\(.\)' 2>/dev/null ||
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
 echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
-  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\/\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
 
+# CDPATH.
+$as_unset CDPATH
 
-# PATH needs CR, and LINENO needs CR and PATH.
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
+if test "x$CONFIG_SHELL" = x; then
+  if (eval ":") 2>/dev/null; then
+  as_have_required=yes
+else
+  as_have_required=no
 fi
 
+  if test $as_have_required = yes && 	 (eval ":
+(as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
 
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
-  # Find who we are.  Look in the path if we contain no path at all
-  # relative or not.
-  case $0 in
-    *[\\/]* ) as_myself=$0 ;;
-    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
 
-       ;;
-  esac
-  # We did not find ourselves, most probably we were run as `sh COMMAND'
-  # in which case we are not to be found in the path.
-  if test "x$as_myself" = x; then
-    as_myself=$0
-  fi
-  if test ! -f "$as_myself"; then
-    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
-   { (exit 1); exit 1; }; }
-  fi
-  case $CONFIG_SHELL in
-  '')
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=\$LINENO
+  as_lineno_2=\$LINENO
+  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+  :
+else
+  as_candidate_shells=
     as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for as_base in sh bash ksh sh5; do
-	 case $as_dir in
+  case $as_dir in
 	 /*)
-	   if ("$as_dir/$as_base" -c '
+	   for as_base in sh bash ksh sh5; do
+	     as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+	   done;;
+       esac
+done
+IFS=$as_save_IFS
+
+
+      for as_shell in $as_candidate_shells $SHELL; do
+	 # Try only shells that exist, to save several forks.
+	 if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		{ ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+  CONFIG_SHELL=$as_shell
+	       as_have_required=yes
+	       if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+  (exit $1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
   as_lineno_1=$LINENO
   as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
   test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
-	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
-	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
-	     CONFIG_SHELL=$as_dir/$as_base
-	     export CONFIG_SHELL
-	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
-	   fi;;
-	 esac
-       done
-done
-;;
-  esac
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
 
+_ASEOF
+}; then
+  break
+fi
+
+fi
+
+      done
+
+      if test "x$CONFIG_SHELL" != x; then
+  for as_var in BASH_ENV ENV
+        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+        done
+        export CONFIG_SHELL
+        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+    if test $as_have_required = no; then
+  echo This script requires a shell more modern than all the
+      echo shells that I found on your system.  Please install a
+      echo modern shell, or manually run the script under such a
+      echo shell if you do have one.
+      { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+  echo No shell found that supports shell functions.
+  echo Please tell autoconf at gnu.org about your system,
+  echo including any error possibly output before this
+  echo message
+}
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
   # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
   # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line before each line; the second 'sed' does the real
-  # work.  The second script uses 'N' to pair each line-number line
-  # with the numbered line, and appends trailing '-' during
-  # substitution so that $LINENO is not a special case at line end.
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
   # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
-  sed '=' <$as_myself |
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
     sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
       N
-      s,$,-,
-      : loop
-      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
       t loop
-      s,-$,,
-      s,^['$as_cr_digits']*\n,,
+      s/-\n.*//
     ' >$as_me.lineno &&
-  chmod +x $as_me.lineno ||
+  chmod +x "$as_me.lineno" ||
     { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
    { (exit 1); exit 1; }; }
 
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensible to this).
-  . ./$as_me.lineno
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
   # Exit status is that of the last command.
   exit
 }
 
 
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
-  *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T='	' ;;
-  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
-  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1; then
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
   as_expr=expr
 else
   as_expr=false
 fi
 
 rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
 echo >conf$$.file
 if ln -s conf$$.file conf$$ 2>/dev/null; then
-  # We could just check for DJGPP; but this test a) works b) is more generic
-  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
-  if test -f conf$$.exe; then
-    # Don't use ln at all; we don't have any links
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
     as_ln_s='cp -p'
-  else
-    as_ln_s='ln -s'
-  fi
 elif ln conf$$.file conf$$ 2>/dev/null; then
   as_ln_s=ln
 else
   as_ln_s='cp -p'
 fi
-rm -f conf$$ conf$$.exe conf$$.file
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
 
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
@@ -222,7 +518,28 @@
   as_mkdir_p=false
 fi
 
-as_executable_p="test -f"
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+        test -d "$1/.";
+      else
+	case $1 in
+        -*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -231,17 +548,8 @@
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" 	$as_nl"
 
-# CDPATH.
-$as_unset CDPATH
 
-
-
 # Check that we are running under the correct shell.
 SHELL=${CONFIG_SHELL-/bin/sh}
 
@@ -285,8 +593,8 @@
 # find a string as large as possible, as long as the shell can cope with it
   for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
     # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
-    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
-       echo_test_string="`eval $cmd`" &&
+    if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+       echo_test_string=`eval $cmd` &&
        (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
     then
       break
@@ -395,77 +703,192 @@
 
 tagnames=${tagnames+${tagnames},}F77
 
+exec 7<&0 </dev/null 6>&1
+
 # Name of the host.
 # hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
-exec 6>&1
-
 #
 # Initializations.
 #
 ac_default_prefix=/usr/local
+ac_clean_files=
 ac_config_libobj_dir=.
+LIBOBJS=
 cross_compiling=no
 subdirs=
 MFLAGS=
 MAKEFLAGS=
 SHELL=${CONFIG_SHELL-/bin/sh}
 
-# Maximum number of lines to put in a shell here document.
-# This variable seems obsolete.  It should probably be removed, and
-# only ac_max_sed_lines should be used.
-: ${ac_max_here_lines=38}
-
 # Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
+PACKAGE_NAME='ldapcpplib'
+PACKAGE_TARNAME='ldapcpplib'
+PACKAGE_VERSION='0.0.5'
+PACKAGE_STRING='ldapcpplib 0.0.5'
+PACKAGE_BUGREPORT=''
 
-ac_unique_file="examples/main.cpp"
+ac_unique_file="src/LDAPConnection.h"
 # Factoring default headers for most tests.
 ac_includes_default="\
 #include <stdio.h>
-#if HAVE_SYS_TYPES_H
+#ifdef HAVE_SYS_TYPES_H
 # include <sys/types.h>
 #endif
-#if HAVE_SYS_STAT_H
+#ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
 #endif
-#if STDC_HEADERS
+#ifdef STDC_HEADERS
 # include <stdlib.h>
 # include <stddef.h>
 #else
-# if HAVE_STDLIB_H
+# ifdef HAVE_STDLIB_H
 #  include <stdlib.h>
 # endif
 #endif
-#if HAVE_STRING_H
-# if !STDC_HEADERS && HAVE_MEMORY_H
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
 #  include <memory.h>
 # endif
 # include <string.h>
 #endif
-#if HAVE_STRINGS_H
+#ifdef HAVE_STRINGS_H
 # include <strings.h>
 #endif
-#if HAVE_INTTYPES_H
+#ifdef HAVE_INTTYPES_H
 # include <inttypes.h>
-#else
-# if HAVE_STDINT_H
-#  include <stdint.h>
-# endif
 #endif
-#if HAVE_UNISTD_H
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS ac_ct_CC CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+INSTALL_PROGRAM
+INSTALL_SCRIPT
+INSTALL_DATA
+am__isrc
+CYGPATH_W
+PACKAGE
+VERSION
+ACLOCAL
+AUTOCONF
+AUTOMAKE
+AUTOHEADER
+MAKEINFO
+install_sh
+STRIP
+INSTALL_STRIP_PROGRAM
+mkdir_p
+AWK
+SET_MAKE
+am__leading_dot
+AMTAR
+am__tar
+am__untar
+CXX
+CXXFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CXX
+EXEEXT
+OBJEXT
+DEPDIR
+am__include
+am__quote
+AMDEP_TRUE
+AMDEP_FALSE
+AMDEPBACKSLASH
+CXXDEPMODE
+am__fastdepCXX_TRUE
+am__fastdepCXX_FALSE
+build
+build_cpu
+build_vendor
+build_os
+host
+host_cpu
+host_vendor
+host_os
+CC
+CFLAGS
+ac_ct_CC
+CCDEPMODE
+am__fastdepCC_TRUE
+am__fastdepCC_FALSE
+SED
+GREP
+EGREP
+LN_S
+ECHO
+AR
+RANLIB
+CPP
+CXXCPP
+F77
+FFLAGS
+ac_ct_F77
+LIBTOOL
+LIBOBJS
+LTLIBOBJS'
 ac_subst_files=''
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CXX
+CXXFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CCC
+CC
+CFLAGS
+CPP
+CXXCPP
+F77
+FFLAGS'
 
+
 # Initialize some variables set by options.
 ac_init_help=
 ac_init_version=false
@@ -491,34 +914,48 @@
 # and all the variables that are supposed to be based on exec_prefix
 # by default will actually change.
 # Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
 bindir='${exec_prefix}/bin'
 sbindir='${exec_prefix}/sbin'
 libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
 
 ac_prev=
+ac_dashdash=
 for ac_option
 do
   # If the previous option needs an argument, assign it.
   if test -n "$ac_prev"; then
-    eval "$ac_prev=\$ac_option"
+    eval $ac_prev=\$ac_option
     ac_prev=
     continue
   fi
 
-  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
 
-  case $ac_option in
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
 
   -bindir | --bindir | --bindi | --bind | --bin | --bi)
     ac_prev=bindir ;;
@@ -540,33 +977,45 @@
   --config-cache | -C)
     cache_file=config.cache ;;
 
-  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+  -datadir | --datadir | --datadi | --datad)
     ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
-  | --da=*)
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
     datadir=$ac_optarg ;;
 
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
   -disable-* | --disable-*)
     ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
       { echo "$as_me: error: invalid feature name: $ac_feature" >&2
    { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    eval "enable_$ac_feature=no" ;;
+    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+    eval enable_$ac_feature=no ;;
 
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
   -enable-* | --enable-*)
     ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
       { echo "$as_me: error: invalid feature name: $ac_feature" >&2
    { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    case $ac_option in
-      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "enable_$ac_feature='$ac_optarg'" ;;
+    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+    eval enable_$ac_feature=\$ac_optarg ;;
 
   -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
   | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -593,6 +1042,12 @@
   -host=* | --host=* | --hos=* | --ho=*)
     host_alias=$ac_optarg ;;
 
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
   -includedir | --includedir | --includedi | --included | --include \
   | --includ | --inclu | --incl | --inc)
     ac_prev=includedir ;;
@@ -617,13 +1072,16 @@
   | --libexe=* | --libex=* | --libe=*)
     libexecdir=$ac_optarg ;;
 
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
   -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst \
-  | --locals | --local | --loca | --loc | --lo)
+  | --localstate | --localstat | --localsta | --localst | --locals)
     ac_prev=localstatedir ;;
   -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
-  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
     localstatedir=$ac_optarg ;;
 
   -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
@@ -688,6 +1146,16 @@
   | --progr-tra=* | --program-tr=* | --program-t=*)
     program_transform_name=$ac_optarg ;;
 
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
@@ -740,24 +1208,20 @@
   -with-* | --with-*)
     ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
       { echo "$as_me: error: invalid package name: $ac_package" >&2
    { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package| sed 's/-/_/g'`
-    case $ac_option in
-      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "with_$ac_package='$ac_optarg'" ;;
+    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+    eval with_$ac_package=\$ac_optarg ;;
 
   -without-* | --without-*)
     ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
       { echo "$as_me: error: invalid package name: $ac_package" >&2
    { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package | sed 's/-/_/g'`
-    eval "with_$ac_package=no" ;;
+    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+    eval with_$ac_package=no ;;
 
   --x)
     # Obsolete; use --with-x.
@@ -788,8 +1252,7 @@
     expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
       { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
    { (exit 1); exit 1; }; }
-    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
-    eval "$ac_envvar='$ac_optarg'"
+    eval $ac_envvar=\$ac_optarg
     export $ac_envvar ;;
 
   *)
@@ -809,29 +1272,21 @@
    { (exit 1); exit 1; }; }
 fi
 
-# Be sure to have absolute paths.
-for ac_var in exec_prefix prefix
+# Be sure to have absolute directory names.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
 do
-  eval ac_val=$`echo $ac_var`
+  eval ac_val=\$$ac_var
   case $ac_val in
-    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
-    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; };;
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
   esac
+  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; }
 done
 
-# Be sure to have absolute paths.
-for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
-	      localstatedir libdir includedir oldincludedir infodir mandir
-do
-  eval ac_val=$`echo $ac_var`
-  case $ac_val in
-    [\\/$]* | ?:[\\/]* ) ;;
-    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; };;
-  esac
-done
-
 # There might be people who depend on the old broken behavior: `$host'
 # used to hold the argument of --host etc.
 # FIXME: To remove some day.
@@ -856,94 +1311,76 @@
 test "$silent" = yes && exec 6>/dev/null
 
 
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  { echo "$as_me: error: Working directory cannot be determined" >&2
+   { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  { echo "$as_me: error: pwd does not report name of working directory" >&2
+   { (exit 1); exit 1; }; }
+
+
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
   ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then its parent.
-  ac_confdir=`(dirname "$0") 2>/dev/null ||
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$0" ||
 $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 	 X"$0" : 'X\(//\)[^/]' \| \
 	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
 echo X"$0" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
   srcdir=$ac_confdir
-  if test ! -r $srcdir/$ac_unique_file; then
+  if test ! -r "$srcdir/$ac_unique_file"; then
     srcdir=..
   fi
 else
   ac_srcdir_defaulted=no
 fi
-if test ! -r $srcdir/$ac_unique_file; then
-  if test "$ac_srcdir_defaulted" = yes; then
-    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
    { (exit 1); exit 1; }; }
-  else
-    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
-   { (exit 1); exit 1; }; }
-  fi
 fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
-  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
    { (exit 1); exit 1; }; }
-srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
-ac_env_build_alias_set=${build_alias+set}
-ac_env_build_alias_value=$build_alias
-ac_cv_env_build_alias_set=${build_alias+set}
-ac_cv_env_build_alias_value=$build_alias
-ac_env_host_alias_set=${host_alias+set}
-ac_env_host_alias_value=$host_alias
-ac_cv_env_host_alias_set=${host_alias+set}
-ac_cv_env_host_alias_value=$host_alias
-ac_env_target_alias_set=${target_alias+set}
-ac_env_target_alias_value=$target_alias
-ac_cv_env_target_alias_set=${target_alias+set}
-ac_cv_env_target_alias_value=$target_alias
-ac_env_CXX_set=${CXX+set}
-ac_env_CXX_value=$CXX
-ac_cv_env_CXX_set=${CXX+set}
-ac_cv_env_CXX_value=$CXX
-ac_env_CXXFLAGS_set=${CXXFLAGS+set}
-ac_env_CXXFLAGS_value=$CXXFLAGS
-ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
-ac_cv_env_CXXFLAGS_value=$CXXFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_CPP_set=${CPP+set}
-ac_env_CPP_value=$CPP
-ac_cv_env_CPP_set=${CPP+set}
-ac_cv_env_CPP_value=$CPP
-ac_env_CXXCPP_set=${CXXCPP+set}
-ac_env_CXXCPP_value=$CXXCPP
-ac_cv_env_CXXCPP_set=${CXXCPP+set}
-ac_cv_env_CXXCPP_value=$CXXCPP
-ac_env_F77_set=${F77+set}
-ac_env_F77_value=$F77
-ac_cv_env_F77_set=${F77+set}
-ac_cv_env_F77_value=$F77
-ac_env_FFLAGS_set=${FFLAGS+set}
-ac_env_FFLAGS_value=$FFLAGS
-ac_cv_env_FFLAGS_set=${FFLAGS+set}
-ac_cv_env_FFLAGS_value=$FFLAGS
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
 
 #
 # Report the --help message.
@@ -952,7 +1389,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
+\`configure' configures ldapcpplib 0.0.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -972,9 +1409,6 @@
   -n, --no-create         do not create output files
       --srcdir=DIR        find the sources in DIR [configure dir or \`..']
 
-_ACEOF
-
-  cat <<_ACEOF
 Installation directories:
   --prefix=PREFIX         install architecture-independent files in PREFIX
 			  [$ac_default_prefix]
@@ -992,15 +1426,22 @@
   --bindir=DIR           user executables [EPREFIX/bin]
   --sbindir=DIR          system admin executables [EPREFIX/sbin]
   --libexecdir=DIR       program executables [EPREFIX/libexec]
-  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
   --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
   --libdir=DIR           object code libraries [EPREFIX/lib]
   --includedir=DIR       C header files [PREFIX/include]
   --oldincludedir=DIR    C header files for non-gcc [/usr/include]
-  --infodir=DIR          info documentation [PREFIX/info]
-  --mandir=DIR           man documentation [PREFIX/man]
+  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR          info documentation [DATAROOTDIR/info]
+  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR           man documentation [DATAROOTDIR/man]
+  --docdir=DIR           documentation root [DATAROOTDIR/doc/ldapcpplib]
+  --htmldir=DIR          html documentation [DOCDIR]
+  --dvidir=DIR           dvi documentation [DOCDIR]
+  --pdfdir=DIR           pdf documentation [DOCDIR]
+  --psdir=DIR            ps documentation [DOCDIR]
 _ACEOF
 
   cat <<\_ACEOF
@@ -1017,7 +1458,9 @@
 fi
 
 if test -n "$ac_init_help"; then
-
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of ldapcpplib 0.0.5:";;
+   esac
   cat <<\_ACEOF
 
 Optional Features:
@@ -1025,10 +1468,8 @@
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --disable-dependency-tracking  speeds up one-time build
   --enable-dependency-tracking   do not reject slow dependency extractors
-  --enable-shared[=PKGS]
-                          build shared libraries [default=yes]
-  --enable-static[=PKGS]
-                          build static libraries [default=yes]
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
   --enable-fast-install[=PKGS]
                           optimize for fast installation [default=yes]
   --disable-libtool-lock  avoid locking (might break parallel builds)
@@ -1040,8 +1481,7 @@
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-pic              try to use only PIC/non-PIC objects [default=use
                           both]
-  --with-tags[=TAGS]
-                          include additional configurations [automatic]
+  --with-tags[=TAGS]      include additional configurations [automatic]
   --with-libldap=DIR          Path to the libldap library /usr/local/lib
   --with-ldap-includes=DIR    Path to the libldap include files /usr/local/include
 
@@ -1050,8 +1490,9 @@
   CXXFLAGS    C++ compiler flags
   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
               nonstandard directory <lib dir>
-  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
-              headers in a nonstandard directory <include dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
   CC          C compiler command
   CFLAGS      C compiler flags
   CPP         C preprocessor
@@ -1063,118 +1504,86 @@
 it to find libraries and programs with nonstandard names/locations.
 
 _ACEOF
+ac_status=$?
 fi
 
 if test "$ac_init_help" = "recursive"; then
   # If there are subdirs, report their specific --help.
-  ac_popdir=`pwd`
   for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d $ac_dir || continue
+    test -d "$ac_dir" || continue
     ac_builddir=.
 
-if test "$ac_dir" != .; then
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
   ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A "../" for each directory in $ac_dir_suffix.
-  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
-  ac_dir_suffix= ac_top_builddir=
-fi
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
 
 case $srcdir in
-  .)  # No --srcdir option.  We are building in place.
+  .)  # We are building in place.
     ac_srcdir=.
-    if test -z "$ac_top_builddir"; then
-       ac_top_srcdir=.
-    else
-       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
-    fi ;;
-  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
     ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir ;;
-  *) # Relative path.
-    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
 esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
-  case "$ac_dir" in
-  .) ac_abs_builddir=`pwd`;;
-  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
-  *) ac_abs_builddir=`pwd`/"$ac_dir";;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
-  case ${ac_top_builddir}. in
-  .) ac_abs_top_builddir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
-  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
-  case $ac_srcdir in
-  .) ac_abs_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
-  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
-  case $ac_top_srcdir in
-  .) ac_abs_top_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
-  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
-  esac;;
-esac
-
-    cd $ac_dir
-    # Check for guested configure; otherwise get Cygnus style configure.
-    if test -f $ac_srcdir/configure.gnu; then
-      echo
-      $SHELL $ac_srcdir/configure.gnu  --help=recursive
-    elif test -f $ac_srcdir/configure; then
-      echo
-      $SHELL $ac_srcdir/configure  --help=recursive
-    elif test -f $ac_srcdir/configure.ac ||
-	   test -f $ac_srcdir/configure.in; then
-      echo
-      $ac_configure --help
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi
-    cd $ac_popdir
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
   done
 fi
 
-test -n "$ac_init_help" && exit 0
+test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
+ldapcpplib configure 0.0.5
+generated by GNU Autoconf 2.61
 
-Copyright (C) 2003 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
-  exit 0
+  exit
 fi
-exec 5>config.log
-cat >&5 <<_ACEOF
+cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by $as_me, which was
-generated by GNU Autoconf 2.59.  Invocation command line was
+It was created by ldapcpplib $as_me 0.0.5, which was
+generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
 
 _ACEOF
+exec 5>>config.log
 {
 cat <<_ASUNAME
 ## --------- ##
@@ -1193,7 +1602,7 @@
 /bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
 /usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
 /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
 /bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
 /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
 /bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
@@ -1207,6 +1616,7 @@
   test -z "$as_dir" && as_dir=.
   echo "PATH: $as_dir"
 done
+IFS=$as_save_IFS
 
 } >&5
 
@@ -1228,7 +1638,6 @@
 ac_configure_args=
 ac_configure_args0=
 ac_configure_args1=
-ac_sep=
 ac_must_keep_next=false
 for ac_pass in 1 2
 do
@@ -1239,7 +1648,7 @@
     -q | -quiet | --quiet | --quie | --qui | --qu | --q \
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
-    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+    *\'*)
       ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
@@ -1261,9 +1670,7 @@
 	  -* ) ac_must_keep_next=true ;;
 	esac
       fi
-      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
-      # Get rid of the leading space.
-      ac_sep=" "
+      ac_configure_args="$ac_configure_args '$ac_arg'"
       ;;
     esac
   done
@@ -1274,8 +1681,8 @@
 # When interrupted or exit'd, cleanup temporary files, and complete
 # config.log.  We remove comments because anyway the quotes in there
 # would cause problems or look ugly.
-# WARNING: Be sure not to use single quotes in there, as some shells,
-# such as our DU 5.0 friend, will then `close' the trap.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
 trap 'exit_status=$?
   # Save into config.log some information that might help in debugging.
   {
@@ -1288,20 +1695,34 @@
 _ASBOX
     echo
     # The following way of writing the cache mishandles newlines in values,
-{
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
   (set) 2>&1 |
-    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
-    *ac_space=\ *)
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
       sed -n \
-	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
-      ;;
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
     *)
-      sed -n \
-	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
       ;;
-    esac;
-}
+    esac |
+    sort
+)
     echo
 
     cat <<\_ASBOX
@@ -1312,22 +1733,28 @@
     echo
     for ac_var in $ac_subst_vars
     do
-      eval ac_val=$`echo $ac_var`
-      echo "$ac_var='"'"'$ac_val'"'"'"
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      echo "$ac_var='\''$ac_val'\''"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
       cat <<\_ASBOX
-## ------------- ##
-## Output files. ##
-## ------------- ##
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
 _ASBOX
       echo
       for ac_var in $ac_subst_files
       do
-	eval ac_val=$`echo $ac_var`
-	echo "$ac_var='"'"'$ac_val'"'"'"
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	echo "$ac_var='\''$ac_val'\''"
       done | sort
       echo
     fi
@@ -1339,26 +1766,24 @@
 ## ----------- ##
 _ASBOX
       echo
-      sed "/^$/d" confdefs.h | sort
+      cat confdefs.h
       echo
     fi
     test "$ac_signal" != 0 &&
       echo "$as_me: caught signal $ac_signal"
     echo "$as_me: exit $exit_status"
   } >&5
-  rm -f core *.core &&
-  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
     exit $exit_status
-     ' 0
+' 0
 for ac_signal in 1 2 13 15; do
   trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
 done
 ac_signal=0
 
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo >confdefs.h
+rm -f -r conftest* confdefs.h
 
 # Predefined preprocessor variables.
 
@@ -1389,14 +1814,17 @@
 
 # Let the site file select an alternate cache file if it wants to.
 # Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
-  if test "x$prefix" != xNONE; then
-    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-  else
-    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
-  fi
+if test -n "$CONFIG_SITE"; then
+  set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+  set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+  set x "$ac_default_prefix/share/config.site" \
+	"$ac_default_prefix/etc/config.site"
 fi
-for ac_site_file in $CONFIG_SITE; do
+shift
+for ac_site_file
+do
   if test -r "$ac_site_file"; then
     { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
 echo "$as_me: loading site script $ac_site_file" >&6;}
@@ -1412,8 +1840,8 @@
     { echo "$as_me:$LINENO: loading cache $cache_file" >&5
 echo "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
-      [\\/]* | ?:[\\/]* ) . $cache_file;;
-      *)                      . ./$cache_file;;
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
     esac
   fi
 else
@@ -1425,12 +1853,11 @@
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
-for ac_var in `(set) 2>&1 |
-	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+for ac_var in $ac_precious_vars; do
   eval ac_old_set=\$ac_cv_env_${ac_var}_set
   eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
-  eval ac_new_val="\$ac_env_${ac_var}_value"
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
   case $ac_old_set,$ac_new_set in
     set,)
       { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
@@ -1455,8 +1882,7 @@
   # Pass precious variables to config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
-    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
-      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
     *) ac_arg=$ac_var=$ac_new_val ;;
     esac
     case " $ac_configure_args " in
@@ -1473,11 +1899,6 @@
    { (exit 1); exit 1; }; }
 fi
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
@@ -1497,32 +1918,52 @@
 
 
 
-am__api_version="1.9"
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+am__api_version='1.10'
+
 ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
-  if test -f $ac_dir/install-sh; then
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
     ac_aux_dir=$ac_dir
     ac_install_sh="$ac_aux_dir/install-sh -c"
     break
-  elif test -f $ac_dir/install.sh; then
+  elif test -f "$ac_dir/install.sh"; then
     ac_aux_dir=$ac_dir
     ac_install_sh="$ac_aux_dir/install.sh -c"
     break
-  elif test -f $ac_dir/shtool; then
+  elif test -f "$ac_dir/shtool"; then
     ac_aux_dir=$ac_dir
     ac_install_sh="$ac_aux_dir/shtool install -c"
     break
   fi
 done
 if test -z "$ac_aux_dir"; then
-  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
-echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
    { (exit 1); exit 1; }; }
 fi
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"
-ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
 
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
 # incompatible versions:
@@ -1536,8 +1977,8 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
-echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
-echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
 if test -z "$INSTALL"; then
 if test "${ac_cv_path_install+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1559,7 +2000,7 @@
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
 	  if test $ac_prog = install &&
 	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # AIX install.  It has an incompatible calling convention.
@@ -1578,21 +2019,22 @@
     ;;
 esac
 done
+IFS=$as_save_IFS
 
 
 fi
   if test "${ac_cv_path_install+set}" = set; then
     INSTALL=$ac_cv_path_install
   else
-    # As a last resort, use the slow shell script.  We don't cache a
-    # path for INSTALL within a source directory, because that will
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
     # break other packages using the cache if that directory is
-    # removed, or if the path is relative.
+    # removed, or if the value is a relative name.
     INSTALL=$ac_install_sh
   fi
 fi
-echo "$as_me:$LINENO: result: $INSTALL" >&5
-echo "${ECHO_T}$INSTALL" >&6
+{ echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6; }
 
 # Use test -z because SunOS4 sh mishandles braces in ${var-val}.
 # It thinks the first close brace ends the variable substitution.
@@ -1602,8 +2044,8 @@
 
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
-echo "$as_me:$LINENO: checking whether build environment is sane" >&5
-echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; }
 # Just in case
 sleep 1
 echo timestamp > conftest.file
@@ -1645,20 +2087,20 @@
 Check your system clock" >&2;}
    { (exit 1); exit 1; }; }
 fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
 test "$program_prefix" != NONE &&
-  program_transform_name="s,^,$program_prefix,;$program_transform_name"
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
 # Use a double $ so make ignores it.
 test "$program_suffix" != NONE &&
-  program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
 # Double any \ or $.  echo might interpret backslashes.
 # By default was `s,x,x', remove it if useless.
 cat <<\_ACEOF >conftest.sed
 s/[\\$]/&&/g;s/;s,x,x,$//
 _ACEOF
 program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
-rm conftest.sed
+rm -f conftest.sed
 
 # expand $ac_aux_dir to an absolute path
 am_aux_dir=`cd $ac_aux_dir && pwd`
@@ -1673,45 +2115,60 @@
 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
 fi
 
-if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
-  # We used to keeping the `.' as first argument, in order to
-  # allow $(mkdir_p) to be used without argument.  As in
-  #   $(mkdir_p) $(somedir)
-  # where $(somedir) is conditionally defined.  However this is wrong
-  # for two reasons:
-  #  1. if the package is installed by a user who cannot write `.'
-  #     make install will fail,
-  #  2. the above comment should most certainly read
-  #     $(mkdir_p) $(DESTDIR)$(somedir)
-  #     so it does not work when $(somedir) is undefined and
-  #     $(DESTDIR) is not.
-  #  To support the latter case, we have to write
-  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
-  #  so the `.' trick is pointless.
-  mkdir_p='mkdir -p --'
+{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5
+echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; }
+if test -z "$MKDIR_P"; then
+  if test "${ac_cv_path_mkdir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  # On NextStep and OpenStep, the `mkdir' command does not
-  # recognize any option.  It will interpret all options as
-  # directories to create, and then abort because `.' already
-  # exists.
-  for d in ./-p ./--version;
-  do
-    test -d $d && rmdir $d
-  done
-  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
-  if test -f "$ac_aux_dir/mkinstalldirs"; then
-    mkdir_p='$(mkinstalldirs)'
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+done
+IFS=$as_save_IFS
+
+fi
+
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
   else
-    mkdir_p='$(install_sh) -d'
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    test -d ./--version && rmdir ./--version
+    MKDIR_P="$ac_install_sh -d"
   fi
 fi
+{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5
+echo "${ECHO_T}$MKDIR_P" >&6; }
 
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+  [\\/$]* | ?:[\\/]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
 for ac_prog in gawk mawk nawk awk
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_AWK+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1724,54 +2181,57 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_AWK="$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 AWK=$ac_cv_prog_AWK
 if test -n "$AWK"; then
-  echo "$as_me:$LINENO: result: $AWK" >&5
-echo "${ECHO_T}$AWK" >&6
+  { echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
   test -n "$AWK" && break
 done
 
-echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
-if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; }
+set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
 all:
-	@echo 'ac_maketemp="$(MAKE)"'
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
 _ACEOF
 # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
-if test -n "$ac_maketemp"; then
-  eval ac_cv_prog_make_${ac_make}_set=yes
-else
-  eval ac_cv_prog_make_${ac_make}_set=no
-fi
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
 rm -f conftest.make
 fi
-if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
-  echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
   SET_MAKE=
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
   SET_MAKE="MAKE=${MAKE-make}"
 fi
 
@@ -1784,12 +2244,16 @@
 fi
 rmdir .tst 2>/dev/null
 
-# test to see if srcdir already configured
-if test "`cd $srcdir && pwd`" != "`pwd`" &&
-   test -f $srcdir/config.status; then
-  { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
    { (exit 1); exit 1; }; }
+  fi
 fi
 
 # test whether we have cygpath
@@ -1803,8 +2267,8 @@
 
 
 # Define the identity of the package.
- PACKAGE=main
- VERSION=0.0.1
+ PACKAGE='ldapcpplib'
+ VERSION='0.0.5'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -1832,7 +2296,7 @@
 
 MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
-install_sh=${install_sh-"$am_aux_dir/install-sh"}
+install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
 
 # Installed binaries are usually stripped using `strip' when the user
 # run `make install-strip'.  However `strip' might not be the right
@@ -1842,8 +2306,8 @@
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
 set dummy ${ac_tool_prefix}strip; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_STRIP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1856,32 +2320,34 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_STRIP="${ac_tool_prefix}strip"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 STRIP=$ac_cv_prog_STRIP
 if test -n "$STRIP"; then
-  echo "$as_me:$LINENO: result: $STRIP" >&5
-echo "${ECHO_T}$STRIP" >&6
+  { echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
 fi
 if test -z "$ac_cv_prog_STRIP"; then
   ac_ct_STRIP=$STRIP
   # Extract the first word of "strip", so it can be a program name with args.
 set dummy strip; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1894,33 +2360,47 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_STRIP="strip"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
-  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
 fi
 fi
 ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
 if test -n "$ac_ct_STRIP"; then
-  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
-echo "${ECHO_T}$ac_ct_STRIP" >&6
+  { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-  STRIP=$ac_ct_STRIP
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
 else
   STRIP="$ac_cv_prog_STRIP"
 fi
 
 fi
-INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 
 # We need awk for the "check" target.  The system "awk" is bad on
 # some platforms.
@@ -1934,7 +2414,7 @@
 
 
 
-          ac_config_headers="$ac_config_headers src/config.h"
+ac_config_headers="$ac_config_headers src/config.h"
 
 
 
@@ -1951,8 +2431,8 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
-echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
-echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
 if test -z "$INSTALL"; then
 if test "${ac_cv_path_install+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -1974,7 +2454,7 @@
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
 	  if test $ac_prog = install &&
 	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # AIX install.  It has an incompatible calling convention.
@@ -1993,21 +2473,22 @@
     ;;
 esac
 done
+IFS=$as_save_IFS
 
 
 fi
   if test "${ac_cv_path_install+set}" = set; then
     INSTALL=$ac_cv_path_install
   else
-    # As a last resort, use the slow shell script.  We don't cache a
-    # path for INSTALL within a source directory, because that will
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
     # break other packages using the cache if that directory is
-    # removed, or if the path is relative.
+    # removed, or if the value is a relative name.
     INSTALL=$ac_install_sh
   fi
 fi
-echo "$as_me:$LINENO: result: $INSTALL" >&5
-echo "${ECHO_T}$INSTALL" >&6
+{ echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6; }
 
 # Use test -z because SunOS4 sh mishandles braces in ${var-val}.
 # It thinks the first close brace ends the variable substitution.
@@ -2017,18 +2498,22 @@
 
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
-ac_ext=cc
+ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_CXX+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2041,36 +2526,38 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 CXX=$ac_cv_prog_CXX
 if test -n "$CXX"; then
-  echo "$as_me:$LINENO: result: $CXX" >&5
-echo "${ECHO_T}$CXX" >&6
+  { echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
     test -n "$CXX" && break
   done
 fi
 if test -z "$CXX"; then
   ac_ct_CXX=$CXX
-  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2083,49 +2570,79 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_CXX="$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
 if test -n "$ac_ct_CXX"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
-echo "${ECHO_T}$ac_ct_CXX" >&6
+  { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
   test -n "$ac_ct_CXX" && break
 done
-test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
 
-  CXX=$ac_ct_CXX
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
 fi
 
-
+  fi
+fi
 # Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
-     "checking for C++ compiler version" >&5
+echo "$as_me:$LINENO: checking for C++ compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-  (eval $ac_compiler --version </dev/null >&5) 2>&5
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
-  (eval $ac_compiler -v </dev/null >&5) 2>&5
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
-  (eval $ac_compiler -V </dev/null >&5) 2>&5
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
@@ -2150,47 +2667,77 @@
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5
-echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5
+echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6; }
 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
-  (eval $ac_link_default) 2>&5
+#
+# List of possible output files, starting from the most likely.
+# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
+# only as a last resort.  b.out is created by i960 compilers.
+ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+#
+# The IRIX 6 linker writes into existing files which may not be
+# executable, retaining their permissions.  Remove them first so a
+# subsequent execution test works.
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link_default") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  # Find the output, starting from the most likely.  This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
-
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
 do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
 	;;
-    conftest.$ac_ext )
-	# This is the source file.
-	;;
     [ab].out )
 	# We found the default executable, but exeext='' is most
 	# certainly right.
 	break;;
     *.* )
-	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	# FIXME: I believe we export ac_cv_exeext for Libtool,
-	# but it would be cool to find out if it's true.  Does anybody
-	# maintain Libtool? --akim.
-	export ac_cv_exeext
+        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
 	break;;
     * )
 	break;;
   esac
 done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
 else
+  ac_file=''
+fi
+
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+if test -z "$ac_file"; then
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
@@ -2202,19 +2749,21 @@
 fi
 
 ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
 
-# Check the compiler produces executables we can run.  If not, either
+# Check that the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5
-echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5
+echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6; }
 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0
 # If not cross compiling, check that we can run a simple program.
 if test "$cross_compiling" != yes; then
   if { ac_try='./$ac_file'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -2233,22 +2782,27 @@
     fi
   fi
 fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
 
 rm -f a.out a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run.  If not, either
+# Check that the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
+{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6; }
 
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
+{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
@@ -2259,9 +2813,8 @@
 for ac_file in conftest.exe conftest conftest.*; do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
     *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	  export ac_cv_exeext
 	  break;;
     * ) break;;
   esac
@@ -2275,14 +2828,14 @@
 fi
 
 rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6; }
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
 ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
 if test "${ac_cv_objext+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2302,14 +2855,20 @@
 }
 _ACEOF
 rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
     *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
        break;;
   esac
@@ -2327,12 +2886,12 @@
 
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6; }
 OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; }
 if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2355,50 +2914,49 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_compiler_gnu=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_compiler_gnu=no
+	ac_compiler_gnu=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
 
 fi
-echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; }
 GXX=`test $ac_compiler_gnu = yes && echo yes`
 ac_test_CXXFLAGS=${CXXFLAGS+set}
 ac_save_CXXFLAGS=$CXXFLAGS
-CXXFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
-echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; }
 if test "${ac_cv_prog_cxx_g+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -2414,159 +2972,133 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_cv_prog_cxx_g=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_prog_cxx_g=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
-if test "$ac_test_CXXFLAGS" = set; then
-  CXXFLAGS=$ac_save_CXXFLAGS
-elif test $ac_cv_prog_cxx_g = yes; then
-  if test "$GXX" = yes; then
-    CXXFLAGS="-g -O2"
-  else
-    CXXFLAGS="-g"
-  fi
-else
-  if test "$GXX" = yes; then
-    CXXFLAGS="-O2"
-  else
-    CXXFLAGS=
-  fi
-fi
-for ac_declaration in \
-   '' \
-   'extern "C" void std::exit (int) throw (); using std::exit;' \
-   'extern "C" void std::exit (int); using std::exit;' \
-   'extern "C" void exit (int) throw ();' \
-   'extern "C" void exit (int);' \
-   'void exit (int);'
-do
-  cat >conftest.$ac_ext <<_ACEOF
+	CXXFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_declaration
-#include <stdlib.h>
+
 int
 main ()
 {
-exit (42);
+
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   :
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-continue
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
+	ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_declaration
+
 int
 main ()
 {
-exit (42);
+
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  break
+  (exit $ac_status); } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cxx_g=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
-  echo '#ifdef __cplusplus' >>confdefs.h
-  echo $ac_declaration      >>confdefs.h
-  echo '#endif'             >>confdefs.h
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2574,7 +3106,7 @@
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 DEPDIR="${am__leading_dot}deps"
 
-          ac_config_commands="$ac_config_commands depfiles"
+ac_config_commands="$ac_config_commands depfiles"
 
 
 am_make=${MAKE-make}
@@ -2584,8 +3116,8 @@
 .PHONY: am__doit
 END
 # If we don't find an include directive, just comment out the code.
-echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
-echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; }
 am__include="#"
 am__quote=
 _am_result=none
@@ -2612,22 +3144,20 @@
 fi
 
 
-echo "$as_me:$LINENO: result: $_am_result" >&5
-echo "${ECHO_T}$_am_result" >&6
+{ echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6; }
 rm -f confinc confmf
 
-# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+# Check whether --enable-dependency-tracking was given.
 if test "${enable_dependency_tracking+set}" = set; then
-  enableval="$enable_dependency_tracking"
+  enableval=$enable_dependency_tracking;
+fi
 
-fi;
 if test "x$enable_dependency_tracking" != xno; then
   am_depcomp="$ac_aux_dir/depcomp"
   AMDEPBACKSLASH='\'
 fi
-
-
-if test "x$enable_dependency_tracking" != xno; then
+ if test "x$enable_dependency_tracking" != xno; then
   AMDEP_TRUE=
   AMDEP_FALSE='#'
 else
@@ -2637,11 +3167,10 @@
 
 
 
-
 depcc="$CXX"  am_compiler_list=
 
-echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
-echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; }
 if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2705,6 +3234,7 @@
        depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
        $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
          >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
        grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
        grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
        ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
@@ -2730,13 +3260,11 @@
 fi
 
 fi
-echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
-echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6
+{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; }
 CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
 
-
-
-if
+ if
   test "x$enable_dependency_tracking" != xno \
   && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
   am__fastdepCXX_TRUE=
@@ -2747,10 +3275,9 @@
 fi
 
 
-# Check whether --enable-shared or --disable-shared was given.
+# Check whether --enable-shared was given.
 if test "${enable_shared+set}" = set; then
-  enableval="$enable_shared"
-  p=${PACKAGE-default}
+  enableval=$enable_shared; p=${PACKAGE-default}
     case $enableval in
     yes) enable_shared=yes ;;
     no) enable_shared=no ;;
@@ -2769,12 +3296,12 @@
     esac
 else
   enable_shared=yes
-fi;
+fi
 
-# Check whether --enable-static or --disable-static was given.
+
+# Check whether --enable-static was given.
 if test "${enable_static+set}" = set; then
-  enableval="$enable_static"
-  p=${PACKAGE-default}
+  enableval=$enable_static; p=${PACKAGE-default}
     case $enableval in
     yes) enable_static=yes ;;
     no) enable_static=no ;;
@@ -2793,12 +3320,12 @@
     esac
 else
   enable_static=yes
-fi;
+fi
 
-# Check whether --enable-fast-install or --disable-fast-install was given.
+
+# Check whether --enable-fast-install was given.
 if test "${enable_fast_install+set}" = set; then
-  enableval="$enable_fast_install"
-  p=${PACKAGE-default}
+  enableval=$enable_fast_install; p=${PACKAGE-default}
     case $enableval in
     yes) enable_fast_install=yes ;;
     no) enable_fast_install=no ;;
@@ -2817,60 +3344,90 @@
     esac
 else
   enable_fast_install=yes
-fi;
+fi
 
+
 # Make sure we can run config.sub.
-$ac_config_sub sun4 >/dev/null 2>&1 ||
-  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
-echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
    { (exit 1); exit 1; }; }
 
-echo "$as_me:$LINENO: checking build system type" >&5
-echo $ECHO_N "checking build system type... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
 if test "${ac_cv_build+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_build_alias=$build_alias
-test -z "$ac_cv_build_alias" &&
-  ac_cv_build_alias=`$ac_config_guess`
-test -z "$ac_cv_build_alias" &&
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
   { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
 echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
    { (exit 1); exit 1; }; }
-ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
-  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
    { (exit 1); exit 1; }; }
 
 fi
-echo "$as_me:$LINENO: result: $ac_cv_build" >&5
-echo "${ECHO_T}$ac_cv_build" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+echo "$as_me: error: invalid value of canonical build" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
 build=$ac_cv_build
-build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
 
 
-echo "$as_me:$LINENO: checking host system type" >&5
-echo $ECHO_N "checking host system type... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6; }
 if test "${ac_cv_host+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_host_alias=$host_alias
-test -z "$ac_cv_host_alias" &&
-  ac_cv_host_alias=$ac_cv_build_alias
-ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
-  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
    { (exit 1); exit 1; }; }
+fi
 
 fi
-echo "$as_me:$LINENO: result: $ac_cv_host" >&5
-echo "${ECHO_T}$ac_cv_host" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+echo "$as_me: error: invalid value of canonical host" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
 host=$ac_cv_host
-host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
 ac_ext=c
@@ -2881,8 +3438,8 @@
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2895,32 +3452,34 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
 fi
 if test -z "$ac_cv_prog_CC"; then
   ac_ct_CC=$CC
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2933,36 +3492,51 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_CC="gcc"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-  CC=$ac_ct_CC
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
 else
   CC="$ac_cv_prog_CC"
 fi
 
 if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2975,74 +3549,34 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
 
+  fi
 fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-fi
 if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3056,7 +3590,7 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
@@ -3067,6 +3601,7 @@
   fi
 done
 done
+IFS=$as_save_IFS
 
 if test $ac_prog_rejected = yes; then
   # We found a bogon in the path, so make sure we never use it.
@@ -3084,22 +3619,23 @@
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
 fi
 if test -z "$CC"; then
   if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl
+  for ac_prog in cl.exe
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3112,36 +3648,38 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
     test -n "$CC" && break
   done
 fi
 if test -z "$CC"; then
   ac_ct_CC=$CC
-  for ac_prog in cl
+  for ac_prog in cl.exe
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3154,29 +3692,45 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
   test -n "$ac_ct_CC" && break
 done
 
-  CC=$ac_ct_CC
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
 fi
 
 fi
@@ -3189,27 +3743,41 @@
    { (exit 1); exit 1; }; }
 
 # Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
-     "checking for C compiler version" >&5
+echo "$as_me:$LINENO: checking for C compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-  (eval $ac_compiler --version </dev/null >&5) 2>&5
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
-  (eval $ac_compiler -v </dev/null >&5) 2>&5
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
-  (eval $ac_compiler -V </dev/null >&5) 2>&5
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
 
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
 if test "${ac_cv_c_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3232,50 +3800,49 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_compiler_gnu=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_compiler_gnu=no
+	ac_compiler_gnu=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
 GCC=`test $ac_compiler_gnu = yes && echo yes`
 ac_test_CFLAGS=${CFLAGS+set}
 ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
 if test "${ac_cv_prog_cc_g+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -3291,38 +3858,118 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	CFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_cv_prog_cc_g=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_prog_cc_g=no
+
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
 if test "$ac_test_CFLAGS" = set; then
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
@@ -3338,12 +3985,12 @@
     CFLAGS=
   fi
 fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_prog_cc_stdc=no
+  ac_cv_prog_cc_c89=no
 ac_save_CC=$CC
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -3377,12 +4024,17 @@
 /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
    function prototypes and stuff, but not '\xHH' hex character constants.
    These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std1 is added to get
+   as 'x'.  The following induces an error, until -std is added to get
    proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
    array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std1.  */
+   that's true only with -std.  */
 int osf4_cc_array ['\x00' == 0 ? 1 : -1];
 
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
 int test (int i, double x);
 struct s1 {int (*f) (int a);};
 struct s2 {int (*f) (double a);};
@@ -3397,205 +4049,57 @@
   return 0;
 }
 _ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX			-qlanglvl=ansi
-# Ultrix and OSF/1	-std1
-# HP-UX 10.20 and later	-Ae
-# HP-UX older versions	-Aa -D_HPUX_SOURCE
-# SVR4			-Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
 do
   CC="$ac_save_CC $ac_arg"
   rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_stdc=$ac_arg
-break
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_c89=$ac_arg
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext
+
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
 done
-rm -f conftest.$ac_ext conftest.$ac_objext
+rm -f conftest.$ac_ext
 CC=$ac_save_CC
 
 fi
-
-case "x$ac_cv_prog_cc_stdc" in
-  x|xno)
-    echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+  xno)
+    { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
   *)
-    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
-    CC="$CC $ac_cv_prog_cc_stdc" ;;
+    CC="$CC $ac_cv_prog_cc_c89"
+    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
 esac
 
-# Some people use a C++ compiler to compile C.  Since we use `exit',
-# in C++ we need to declare it.  In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
-cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
-  choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  for ac_declaration in \
-   '' \
-   'extern "C" void std::exit (int) throw (); using std::exit;' \
-   'extern "C" void std::exit (int); using std::exit;' \
-   'extern "C" void exit (int) throw ();' \
-   'extern "C" void exit (int);' \
-   'void exit (int);'
-do
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-continue
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_declaration
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
-  echo '#ifdef __cplusplus' >>confdefs.h
-  echo $ac_declaration      >>confdefs.h
-  echo '#endif'             >>confdefs.h
-fi
-
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3604,8 +4108,8 @@
 
 depcc="$CC"   am_compiler_list=
 
-echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
-echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; }
 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3669,6 +4173,7 @@
        depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
        $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
          >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
        grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
        grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
        ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
@@ -3694,13 +4199,11 @@
 fi
 
 fi
-echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
-echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; }
 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
 
-
-
-if
+ if
   test "x$enable_dependency_tracking" != xno \
   && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
   am__fastdepCC_TRUE=
@@ -3711,8 +4214,8 @@
 fi
 
 
-echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
-echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
+echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; }
 if test "${lt_cv_path_SED+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3725,12 +4228,13 @@
   test -z "$as_dir" && as_dir=.
   for lt_ac_prog in sed gsed; do
     for ac_exec_ext in '' $ac_executable_extensions; do
-      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+      if { test -f "$as_dir/$lt_ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$lt_ac_prog$ac_exec_ext"; }; then
         lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
       fi
     done
   done
 done
+IFS=$as_save_IFS
 lt_ac_max=0
 lt_ac_count=0
 # Add /usr/xpg4/bin/sed as it is typically found on Solaris
@@ -3765,37 +4269,185 @@
 fi
 
 SED=$lt_cv_path_SED
-echo "$as_me:$LINENO: result: $SED" >&5
-echo "${ECHO_T}$SED" >&6
 
-echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6
-if test "${ac_cv_prog_egrep+set}" = set; then
+{ echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6; }
+
+{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
-    then ac_cv_prog_egrep='grep -E'
-    else ac_cv_prog_egrep='egrep'
+  # Extract the first word of "grep ggrep" to use in msg output
+if test -z "$GREP"; then
+set dummy grep ggrep; ac_prog_name=$2
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_GREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in grep ggrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+    # Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
     fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_GREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
 fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
-echo "${ECHO_T}$ac_cv_prog_egrep" >&6
- EGREP=$ac_cv_prog_egrep
 
+GREP="$ac_cv_path_GREP"
+if test -z "$GREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
 
+else
+  ac_cv_path_GREP=$GREP
+fi
 
-# Check whether --with-gnu-ld or --without-gnu-ld was given.
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     # Extract the first word of "egrep" to use in msg output
+if test -z "$EGREP"; then
+set dummy egrep; ac_prog_name=$2
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_EGREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in egrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+    # Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_EGREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+EGREP="$ac_cv_path_EGREP"
+if test -z "$EGREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+
+   fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+
+# Check whether --with-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then
-  withval="$with_gnu_ld"
-  test "$withval" = no || with_gnu_ld=yes
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
 else
   with_gnu_ld=no
-fi;
+fi
+
 ac_prog=ld
 if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
-  echo "$as_me:$LINENO: checking for ld used by $CC" >&5
-echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
   case $host in
   *-*-mingw*)
     # gcc leaves a trailing carriage return which upsets mingw
@@ -3824,11 +4476,11 @@
     ;;
   esac
 elif test "$with_gnu_ld" = yes; then
-  echo "$as_me:$LINENO: checking for GNU ld" >&5
-echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
 else
-  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
-echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
 fi
 if test "${lt_cv_path_LD+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -3841,7 +4493,7 @@
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
       lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some GNU ld's only accept -v.
+      # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
@@ -3861,21 +4513,21 @@
 
 LD="$lt_cv_path_LD"
 if test -n "$LD"; then
-  echo "$as_me:$LINENO: result: $LD" >&5
-echo "${ECHO_T}$LD" >&6
+  { echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
 echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
    { (exit 1); exit 1; }; }
-echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
-echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
 if test "${lt_cv_prog_gnu_ld+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
 case `$LD -v 2>&1 </dev/null` in
 *GNU* | *'with BFD'*)
   lt_cv_prog_gnu_ld=yes
@@ -3885,20 +4537,20 @@
   ;;
 esac
 fi
-echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
-echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
 with_gnu_ld=$lt_cv_prog_gnu_ld
 
 
-echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
-echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; }
 if test "${lt_cv_ld_reload_flag+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   lt_cv_ld_reload_flag='-r'
 fi
-echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
-echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; }
 reload_flag=$lt_cv_ld_reload_flag
 case $reload_flag in
 "" | " "*) ;;
@@ -3908,15 +4560,15 @@
 case $host_os in
   darwin*)
     if test "$GCC" = yes; then
-      reload_cmds='$CC -nostdlib ${wl}-r -o $output$reload_objs'
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
     else
       reload_cmds='$LD$reload_flag -o $output$reload_objs'
     fi
     ;;
 esac
 
-echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
-echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; }
 if test "${lt_cv_path_NM+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3924,56 +4576,63 @@
   # Let the user override the test.
   lt_cv_path_NM="$NM"
 else
-  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
-    IFS="$lt_save_ifs"
-    test -z "$ac_dir" && ac_dir=.
-    tmp_nm="$ac_dir/${ac_tool_prefix}nm"
-    if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
-      # Check to see if the nm accepts a BSD-compat flag.
-      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
-      #   nm: unknown option "B" ignored
-      # Tru64's nm complains that /dev/null is an invalid object file
-      case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
-      */dev/null* | *'Invalid file or object type'*)
-	lt_cv_path_NM="$tmp_nm -B"
-	break
-        ;;
-      *)
-	case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
-	*/dev/null*)
-	  lt_cv_path_NM="$tmp_nm -p"
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
 	  break
 	  ;;
 	*)
-	  lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
-	  continue # so that we can try to find one that supports BSD flags
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
 	  ;;
 	esac
-      esac
-    fi
+      fi
+    done
+    IFS="$lt_save_ifs"
   done
-  IFS="$lt_save_ifs"
   test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
 fi
 fi
-echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
-echo "${ECHO_T}$lt_cv_path_NM" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
+echo "${ECHO_T}$lt_cv_path_NM" >&6; }
 NM="$lt_cv_path_NM"
 
-echo "$as_me:$LINENO: checking whether ln -s works" >&5
-echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
 LN_S=$as_ln_s
 if test "$LN_S" = "ln -s"; then
-  echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
 else
-  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
-echo "${ECHO_T}no, using $LN_S" >&6
+  { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6; }
 fi
 
-echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5
-echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5
+echo $ECHO_N "checking how to recognize dependent libraries... $ECHO_C" >&6; }
 if test "${lt_cv_deplibs_check_method+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -4014,16 +4673,22 @@
 
 mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
-  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
-  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
-  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
   ;;
 
 darwin* | rhapsody*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-freebsd* | kfreebsd*-gnu | dragonfly*)
+freebsd* | dragonfly*)
   if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
     case $host_cpu in
     i*86 )
@@ -4045,7 +4710,7 @@
 
 hpux10.20* | hpux11*)
   lt_cv_file_magic_cmd=/usr/bin/file
-  case "$host_cpu" in
+  case $host_cpu in
   ia64*)
     lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
     lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
@@ -4061,6 +4726,11 @@
   esac
   ;;
 
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
 irix5* | irix6* | nonstopux*)
   case $LD in
   *-32|*"-32 ") libmagic=32-bit;;
@@ -4072,7 +4742,7 @@
   ;;
 
 # This must be Linux ELF.
-linux*)
+linux* | k*bsd*-gnu)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
@@ -4106,7 +4776,7 @@
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-sco3.2v5*)
+rdos*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
@@ -4114,7 +4784,7 @@
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
   case $host_vendor in
   motorola)
     lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
@@ -4135,17 +4805,20 @@
   siemens)
     lt_cv_deplibs_check_method=pass_all
     ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
   esac
   ;;
 
-sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7* | sysv4*uw2*)
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 esac
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
-echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; }
 file_magic_cmd=$lt_cv_file_magic_cmd
 deplibs_check_method=$lt_cv_deplibs_check_method
 test -z "$deplibs_check_method" && deplibs_check_method=unknown
@@ -4156,15 +4829,18 @@
 # If no C compiler was specified, use CC.
 LTCC=${LTCC-"$CC"}
 
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
 # Allow CC to be a program name with arguments.
 compiler=$CC
 
 
-# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+# Check whether --enable-libtool-lock was given.
 if test "${enable_libtool_lock+set}" = set; then
-  enableval="$enable_libtool_lock"
+  enableval=$enable_libtool_lock;
+fi
 
-fi;
 test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
 # Some flags need to be propagated to the compiler or linker for good
@@ -4191,7 +4867,7 @@
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 4194 "configure"' > conftest.$ac_ext
+  echo '#line 4870 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -4226,7 +4902,8 @@
   rm -rf conftest*
   ;;
 
-x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|sparc*-*linux*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
@@ -4234,9 +4911,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-    case "`/usr/bin/file conftest.o`" in
+    case `/usr/bin/file conftest.o` in
     *32-bit*)
       case $host in
+        x86_64-*kfreebsd*-gnu)
+          LD="${LD-ld} -m elf_i386_fbsd"
+          ;;
         x86_64-*linux*)
           LD="${LD-ld} -m elf_i386"
           ;;
@@ -4253,6 +4933,9 @@
       ;;
     *64-bit*)
       case $host in
+        x86_64-*kfreebsd*-gnu)
+          LD="${LD-ld} -m elf_x86_64_fbsd"
+          ;;
         x86_64-*linux*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
@@ -4276,8 +4959,8 @@
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
   SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
-  echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
-echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; }
 if test "${lt_cv_cc_needs_belf+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -4303,35 +4986,32 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   lt_cv_cc_needs_belf=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-lt_cv_cc_needs_belf=no
+	lt_cv_cc_needs_belf=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
      ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -4340,14 +5020,34 @@
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
-echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; }
   if test x"$lt_cv_cc_needs_belf" != x"yes"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
     CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)    LD="${LD-ld} -64" ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
 
+
 esac
 
 need_locks="$enable_libtool_lock"
@@ -4358,8 +5058,8 @@
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -4393,24 +5093,22 @@
 #endif
 		     Syntax error
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   :
 else
   echo "$as_me: failed program was:" >&5
@@ -4419,9 +5117,10 @@
   # Broken: fails on valid input.
 continue
 fi
+
 rm -f conftest.err conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether non-existent headers
+  # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -4431,24 +5130,22 @@
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   # Broken: success on invalid input.
 continue
 else
@@ -4459,6 +5156,7 @@
 ac_preproc_ok=:
 break
 fi
+
 rm -f conftest.err conftest.$ac_ext
 
 done
@@ -4476,8 +5174,8 @@
 else
   ac_cv_prog_CPP=$CPP
 fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
 ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
@@ -4500,24 +5198,22 @@
 #endif
 		     Syntax error
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   :
 else
   echo "$as_me: failed program was:" >&5
@@ -4526,9 +5222,10 @@
   # Broken: fails on valid input.
 continue
 fi
+
 rm -f conftest.err conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether non-existent headers
+  # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -4538,24 +5235,22 @@
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   # Broken: success on invalid input.
 continue
 else
@@ -4566,6 +5261,7 @@
 ac_preproc_ok=:
 break
 fi
+
 rm -f conftest.err conftest.$ac_ext
 
 done
@@ -4588,8 +5284,8 @@
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
 if test "${ac_cv_header_stdc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -4613,36 +5309,32 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_cv_header_stdc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_header_stdc=no
+	ac_cv_header_stdc=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
   cat >conftest.$ac_ext <<_ACEOF
@@ -4697,6 +5389,7 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <ctype.h>
+#include <stdlib.h>
 #if ((' ' & 0x0FF) == 0x020)
 # define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
 # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
@@ -4716,18 +5409,27 @@
   for (i = 0; i < 256; i++)
     if (XOR (islower (i), ISLOWER (i))
 	|| toupper (i) != TOUPPER (i))
-      exit(2);
-  exit (0);
+      return 2;
+  return 0;
 }
 _ACEOF
 rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -4740,12 +5442,14 @@
 ( exit $ac_status )
 ac_cv_header_stdc=no
 fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
+
+
 fi
 fi
-echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
 if test $ac_cv_header_stdc = yes; then
 
 cat >>confdefs.h <<\_ACEOF
@@ -4768,9 +5472,9 @@
 		  inttypes.h stdint.h unistd.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -4784,38 +5488,35 @@
 #include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   eval "$as_ac_Header=yes"
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-eval "$as_ac_Header=no"
+	eval "$as_ac_Header=no"
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
 if test `eval echo '${'$as_ac_Header'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
@@ -4830,18 +5531,19 @@
 for ac_header in dlfcn.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
 else
   # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -4852,41 +5554,37 @@
 #include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_header_compiler=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_header_compiler=no
+	ac_header_compiler=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
 
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
 # Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -4895,24 +5593,22 @@
 /* end confdefs.h.  */
 #include <$ac_header>
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   ac_header_preproc=yes
 else
   echo "$as_me: failed program was:" >&5
@@ -4920,9 +5616,10 @@
 
   ac_header_preproc=no
 fi
+
 rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
 
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
@@ -4946,25 +5643,19 @@
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------------ ##
-## Report this to the AC_PACKAGE_NAME lists.  ##
-## ------------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
+
     ;;
 esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   eval "$as_ac_Header=\$ac_header_preproc"
 fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
 
 fi
 if test `eval echo '${'$as_ac_Header'}'` = yes; then
@@ -4981,13 +5672,13 @@
 if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
     ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
     (test "X$CXX" != "Xg++"))) ; then
-  ac_ext=cc
+  ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
-echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; }
 if test -z "$CXXCPP"; then
   if test "${ac_cv_prog_CXXCPP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -5017,24 +5708,22 @@
 #endif
 		     Syntax error
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_cxx_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   :
 else
   echo "$as_me: failed program was:" >&5
@@ -5043,9 +5732,10 @@
   # Broken: fails on valid input.
 continue
 fi
+
 rm -f conftest.err conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether non-existent headers
+  # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -5055,24 +5745,22 @@
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_cxx_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   # Broken: success on invalid input.
 continue
 else
@@ -5083,6 +5771,7 @@
 ac_preproc_ok=:
 break
 fi
+
 rm -f conftest.err conftest.$ac_ext
 
 done
@@ -5100,8 +5789,8 @@
 else
   ac_cv_prog_CXXCPP=$CXXCPP
 fi
-echo "$as_me:$LINENO: result: $CXXCPP" >&5
-echo "${ECHO_T}$CXXCPP" >&6
+{ echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6; }
 ac_preproc_ok=false
 for ac_cxx_preproc_warn_flag in '' yes
 do
@@ -5124,24 +5813,22 @@
 #endif
 		     Syntax error
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_cxx_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   :
 else
   echo "$as_me: failed program was:" >&5
@@ -5150,9 +5837,10 @@
   # Broken: fails on valid input.
 continue
 fi
+
 rm -f conftest.err conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether non-existent headers
+  # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -5162,24 +5850,22 @@
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_cxx_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   # Broken: success on invalid input.
 continue
 else
@@ -5190,6 +5876,7 @@
 ac_preproc_ok=:
 break
 fi
+
 rm -f conftest.err conftest.$ac_ext
 
 done
@@ -5205,7 +5892,7 @@
    { (exit 1); exit 1; }; }
 fi
 
-ac_ext=cc
+ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
@@ -5219,12 +5906,12 @@
 ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_f77_compiler_gnu
 if test -n "$ac_tool_prefix"; then
-  for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
+  for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_F77+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5237,36 +5924,38 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 F77=$ac_cv_prog_F77
 if test -n "$F77"; then
-  echo "$as_me:$LINENO: result: $F77" >&5
-echo "${ECHO_T}$F77" >&6
+  { echo "$as_me:$LINENO: result: $F77" >&5
+echo "${ECHO_T}$F77" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
     test -n "$F77" && break
   done
 fi
 if test -z "$F77"; then
   ac_ct_F77=$F77
-  for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
+  for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_ac_ct_F77+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5279,48 +5968,78 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_F77="$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_F77=$ac_cv_prog_ac_ct_F77
 if test -n "$ac_ct_F77"; then
-  echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
-echo "${ECHO_T}$ac_ct_F77" >&6
+  { echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
+echo "${ECHO_T}$ac_ct_F77" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
   test -n "$ac_ct_F77" && break
 done
 
-  F77=$ac_ct_F77
+  if test "x$ac_ct_F77" = x; then
+    F77=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    F77=$ac_ct_F77
+  fi
 fi
 
 
 # Provide some information about the compiler.
-echo "$as_me:5309:" \
-     "checking for Fortran 77 compiler version" >&5
+echo "$as_me:$LINENO: checking for Fortran 77 compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-  (eval $ac_compiler --version </dev/null >&5) 2>&5
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
-  (eval $ac_compiler -v </dev/null >&5) 2>&5
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
-  (eval $ac_compiler -V </dev/null >&5) 2>&5
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
@@ -5330,8 +6049,8 @@
 # input file.  (Note that this only needs to work for GNU compilers.)
 ac_save_ext=$ac_ext
 ac_ext=F
-echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6; }
 if test "${ac_cv_f77_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5344,46 +6063,42 @@
       end
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_f77_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_f77_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_compiler_gnu=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_compiler_gnu=no
+	ac_compiler_gnu=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_f77_compiler_gnu=$ac_compiler_gnu
 
 fi
-echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6; }
 ac_ext=$ac_save_ext
 ac_test_FFLAGS=${FFLAGS+set}
 ac_save_FFLAGS=$FFLAGS
 FFLAGS=
-echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
-echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
+echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6; }
 if test "${ac_cv_prog_f77_g+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5394,39 +6109,35 @@
       end
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_f77_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_f77_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_cv_prog_f77_g=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_prog_f77_g=no
+	ac_cv_prog_f77_g=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
 fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
-echo "${ECHO_T}$ac_cv_prog_f77_g" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
+echo "${ECHO_T}$ac_cv_prog_f77_g" >&6; }
 if test "$ac_test_FFLAGS" = set; then
   FFLAGS=$ac_save_FFLAGS
 elif test $ac_cv_prog_f77_g = yes; then
@@ -5455,8 +6166,8 @@
 # Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
 
 # find the maximum length of command line arguments
-echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
-echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
+echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; }
 if test "${lt_cv_sys_max_cmd_len+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5503,12 +6214,18 @@
     elif test -x /usr/sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
     else
-      lt_cv_sys_max_cmd_len=65536 # usable default for *BSD
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
     fi
     # And add a safety zone
     lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
     lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
     ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
   osf*)
     # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
     # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
@@ -5522,44 +6239,59 @@
       esac
     fi
     ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ 	]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
   *)
-    # If test is not a shell built-in, we'll probably end up computing a
-    # maximum length that is only half of the actual maximum length, but
-    # we can't tell.
-    SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
-    while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \
 	       = "XX$teststring") >/dev/null 2>&1 &&
-	    new_result=`expr "X$teststring" : ".*" 2>&1` &&
-	    lt_cv_sys_max_cmd_len=$new_result &&
-	    test $i != 17 # 1/2 MB should be enough
-    do
-      i=`expr $i + 1`
-      teststring=$teststring$teststring
-    done
-    teststring=
-    # Add a significant safety factor because C++ compilers can tack on massive
-    # amounts of additional arguments before passing them to the linker.
-    # It appears as though 1/2 is a usable value.
-    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+	      new_result=`expr "X$teststring" : ".*" 2>&1` &&
+	      lt_cv_sys_max_cmd_len=$new_result &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on massive
+      # amounts of additional arguments before passing them to the linker.
+      # It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
     ;;
   esac
 
 fi
 
 if test -n $lt_cv_sys_max_cmd_len ; then
-  echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
-echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6
+  { echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
+echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6; }
 else
-  echo "$as_me:$LINENO: result: none" >&5
-echo "${ECHO_T}none" >&6
+  { echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6; }
 fi
 
 
 
 
+
 # Check for command to grab the raw symbol name followed by C symbol from nm.
-echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
-echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
+echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; }
 if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5594,7 +6326,7 @@
   lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
   lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
   ;;
-linux*)
+linux* | k*bsd*-gnu)
   if test "$host_cpu" = ia64; then
     symcode='[ABCDGIRSTW]'
     lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
@@ -5607,9 +6339,18 @@
 osf*)
   symcode='[BCDEGQRST]'
   ;;
-solaris* | sysv5*)
+solaris*)
   symcode='[BDRT]'
   ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
 sysv4)
   symcode='[DFNSTU]'
   ;;
@@ -5754,15 +6495,15 @@
   lt_cv_sys_global_symbol_to_cdecl=
 fi
 if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
-  echo "$as_me:$LINENO: result: failed" >&5
-echo "${ECHO_T}failed" >&6
+  { echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6; }
 else
-  echo "$as_me:$LINENO: result: ok" >&5
-echo "${ECHO_T}ok" >&6
+  { echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6; }
 fi
 
-echo "$as_me:$LINENO: checking for objdir" >&5
-echo $ECHO_N "checking for objdir... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for objdir" >&5
+echo $ECHO_N "checking for objdir... $ECHO_C" >&6; }
 if test "${lt_cv_objdir+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5776,8 +6517,8 @@
 fi
 rmdir .libs 2>/dev/null
 fi
-echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
-echo "${ECHO_T}$lt_cv_objdir" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
+echo "${ECHO_T}$lt_cv_objdir" >&6; }
 objdir=$lt_cv_objdir
 
 
@@ -5818,7 +6559,7 @@
 default_ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a `.a' archive for static linking (except M$VC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 ltmain="$ac_aux_dir/ltmain.sh"
@@ -5828,8 +6569,8 @@
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ar; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_AR+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5842,32 +6583,34 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_AR="${ac_tool_prefix}ar"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 AR=$ac_cv_prog_AR
 if test -n "$AR"; then
-  echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6
+  { echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
 fi
 if test -z "$ac_cv_prog_AR"; then
   ac_ct_AR=$AR
   # Extract the first word of "ar", so it can be a program name with args.
 set dummy ar; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5880,27 +6623,41 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_AR="ar"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
-  test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false"
 fi
 fi
 ac_ct_AR=$ac_cv_prog_ac_ct_AR
 if test -n "$ac_ct_AR"; then
-  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
-echo "${ECHO_T}$ac_ct_AR" >&6
+  { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-  AR=$ac_ct_AR
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
 else
   AR="$ac_cv_prog_AR"
 fi
@@ -5908,8 +6665,8 @@
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_RANLIB+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5922,32 +6679,34 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 RANLIB=$ac_cv_prog_RANLIB
 if test -n "$RANLIB"; then
-  echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6
+  { echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
 fi
 if test -z "$ac_cv_prog_RANLIB"; then
   ac_ct_RANLIB=$RANLIB
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -5960,27 +6719,41 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_RANLIB="ranlib"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
-  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
 fi
 fi
 ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
 if test -n "$ac_ct_RANLIB"; then
-  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6
+  { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-  RANLIB=$ac_ct_RANLIB
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
 else
   RANLIB="$ac_cv_prog_RANLIB"
 fi
@@ -5988,8 +6761,8 @@
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
 set dummy ${ac_tool_prefix}strip; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_STRIP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -6002,32 +6775,34 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_STRIP="${ac_tool_prefix}strip"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
 fi
 fi
 STRIP=$ac_cv_prog_STRIP
 if test -n "$STRIP"; then
-  echo "$as_me:$LINENO: result: $STRIP" >&5
-echo "${ECHO_T}$STRIP" >&6
+  { echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
+
 fi
 if test -z "$ac_cv_prog_STRIP"; then
   ac_ct_STRIP=$STRIP
   # Extract the first word of "strip", so it can be a program name with args.
 set dummy strip; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -6040,27 +6815,41 @@
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     ac_cv_prog_ac_ct_STRIP="strip"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
+IFS=$as_save_IFS
 
-  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
 fi
 fi
 ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
 if test -n "$ac_ct_STRIP"; then
-  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
-echo "${ECHO_T}$ac_ct_STRIP" >&6
+  { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-  STRIP=$ac_ct_STRIP
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
 else
   STRIP="$ac_cv_prog_STRIP"
 fi
@@ -6075,6 +6864,7 @@
 test -z "$AS" && AS=as
 test -z "$CC" && CC=cc
 test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
 test -z "$DLLTOOL" && DLLTOOL=dlltool
 test -z "$LD" && LD=ld
 test -z "$LN_S" && LN_S="ln -s"
@@ -6087,17 +6877,17 @@
 test -z "$ac_objext" && ac_objext=o
 
 # Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
 old_postinstall_cmds='chmod 644 $oldlib'
 old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
   case $host_os in
   openbsd*)
-    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
     ;;
   *)
-    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
     ;;
   esac
   old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
@@ -6118,8 +6908,8 @@
 case $deplibs_check_method in
 file_magic*)
   if test "$file_magic_cmd" = '$MAGIC_CMD'; then
-    echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
-echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
+    { echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6; }
 if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -6139,7 +6929,7 @@
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
-	  file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
 	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
@@ -6171,17 +6961,17 @@
 
 MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
-  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
-echo "${ECHO_T}$MAGIC_CMD" >&6
+  { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
 if test -z "$lt_cv_path_MAGIC_CMD"; then
   if test -n "$ac_tool_prefix"; then
-    echo "$as_me:$LINENO: checking for file" >&5
-echo $ECHO_N "checking for file... $ECHO_C" >&6
+    { echo "$as_me:$LINENO: checking for file" >&5
+echo $ECHO_N "checking for file... $ECHO_C" >&6; }
 if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -6201,7 +6991,7 @@
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
-	  file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
 	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
@@ -6233,11 +7023,11 @@
 
 MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
-  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
-echo "${ECHO_T}$MAGIC_CMD" >&6
+  { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
   else
@@ -6252,21 +7042,21 @@
 enable_dlopen=no
 enable_win32_dll=no
 
-# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+# Check whether --enable-libtool-lock was given.
 if test "${enable_libtool_lock+set}" = set; then
-  enableval="$enable_libtool_lock"
+  enableval=$enable_libtool_lock;
+fi
 
-fi;
 test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
 
-# Check whether --with-pic or --without-pic was given.
+# Check whether --with-pic was given.
 if test "${with_pic+set}" = set; then
-  withval="$with_pic"
-  pic_mode="$withval"
+  withval=$with_pic; pic_mode="$withval"
 else
   pic_mode=default
-fi;
+fi
+
 test -z "$pic_mode" && pic_mode=default
 
 # Use C for the default configuration in the libtool script
@@ -6287,113 +7077,51 @@
 objext=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;\n"
+lt_simple_compile_test_code="int some_variable = 0;"
 
 # Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}\n'
+lt_simple_link_test_code='int main(){return(0);}'
 
 
 # If no C compiler was specified, use CC.
 LTCC=${LTCC-"$CC"}
 
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
 # Allow CC to be a program name with arguments.
 compiler=$CC
 
 
 # save warnings/boilerplate of simple test code
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_compiler_boilerplate=`cat conftest.err`
 $rm conftest*
 
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_linker_boilerplate=`cat conftest.err`
 $rm conftest*
 
 
-#
-# Check for any special shared library compilation flags.
-#
-lt_prog_cc_shlib=
-if test "$GCC" = no; then
-  case $host_os in
-  sco3.2v5*)
-    lt_prog_cc_shlib='-belf'
-    ;;
-  esac
-fi
-if test -n "$lt_prog_cc_shlib"; then
-  { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&5
-echo "$as_me: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&2;}
-  if echo "$old_CC $old_CFLAGS " | grep "[ 	]$lt_prog_cc_shlib[ 	]" >/dev/null; then :
-  else
-    { echo "$as_me:$LINENO: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5
-echo "$as_me: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;}
-    lt_cv_prog_cc_can_build_shared=no
-  fi
-fi
 
-
-#
-# Check to make sure the static flag actually works.
-#
-echo "$as_me:$LINENO: checking if $compiler static flag $lt_prog_compiler_static works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_prog_compiler_static works... $ECHO_C" >&6
-if test "${lt_prog_compiler_static_works+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  lt_prog_compiler_static_works=no
-   save_LDFLAGS="$LDFLAGS"
-   LDFLAGS="$LDFLAGS $lt_prog_compiler_static"
-   printf "$lt_simple_link_test_code" > conftest.$ac_ext
-   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
-     # The compiler can only warn and ignore the option if not recognized
-     # So say no if there are warnings
-     if test -s conftest.err; then
-       # Append any errors to the config.log.
-       cat conftest.err 1>&5
-       $echo "X$_lt_linker_boilerplate" | $Xsed > conftest.exp
-       $SED '/^$/d' conftest.err >conftest.er2
-       if diff conftest.exp conftest.er2 >/dev/null; then
-         lt_prog_compiler_static_works=yes
-       fi
-     else
-       lt_prog_compiler_static_works=yes
-     fi
-   fi
-   $rm conftest*
-   LDFLAGS="$save_LDFLAGS"
-
-fi
-echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
-echo "${ECHO_T}$lt_prog_compiler_static_works" >&6
-
-if test x"$lt_prog_compiler_static_works" = xyes; then
-    :
-else
-    lt_prog_compiler_static=
-fi
-
-
-
-
 lt_prog_compiler_no_builtin_flag=
 
 if test "$GCC" = yes; then
   lt_prog_compiler_no_builtin_flag=' -fno-builtin'
 
 
-echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; }
 if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   lt_cv_prog_compiler_rtti_exceptions=no
   ac_outfile=conftest.$ac_objext
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
    lt_compiler_flag="-fno-rtti -fno-exceptions"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
@@ -6401,28 +7129,28 @@
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    # The option is referenced via a variable to avoid confusing sed.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6407: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7135: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6411: \$? = $ac_status" >&5
+   echo "$as_me:7139: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp
-     $SED '/^$/d' conftest.err >conftest.er2
-     if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_rtti_exceptions=yes
      fi
    fi
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; }
 
 if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
     lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
@@ -6436,8 +7164,8 @@
 lt_prog_compiler_pic=
 lt_prog_compiler_static=
 
-echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
 
   if test "$GCC" = yes; then
     lt_prog_compiler_wl='-Wl,'
@@ -6459,13 +7187,15 @@
       lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
       ;;
 
-    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
       # PIC is the default for these OSes.
       ;;
 
-    mingw* | pw32* | os2*)
+    mingw* | cygwin* | pw32* | os2*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
       lt_prog_compiler_pic='-DDLL_EXPORT'
       ;;
 
@@ -6475,6 +7205,11 @@
       lt_prog_compiler_pic='-fno-common'
       ;;
 
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
     msdosdjgpp*)
       # Just because we use GCC doesn't mean we suddenly get shared libraries
       # on systems that don't support them.
@@ -6491,7 +7226,7 @@
     hpux*)
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	# +Z the default
 	;;
@@ -6528,7 +7263,7 @@
        esac
        ;;
 
-    mingw* | pw32* | os2*)
+    mingw* | cygwin* | pw32* | os2*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       lt_prog_compiler_pic='-DDLL_EXPORT'
@@ -6538,7 +7273,7 @@
       lt_prog_compiler_wl='-Wl,'
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	# +Z the default
 	;;
@@ -6561,25 +7296,41 @@
       lt_prog_compiler_static='-Bstatic'
       ;;
 
-    linux*)
+    linux* | k*bsd*-gnu)
       case $cc_basename in
       icc* | ecc*)
 	lt_prog_compiler_wl='-Wl,'
 	lt_prog_compiler_pic='-KPIC'
 	lt_prog_compiler_static='-static'
         ;;
-      pgcc* | pgf77* | pgf90*)
+      pgcc* | pgf77* | pgf90* | pgf95*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
 	lt_prog_compiler_wl='-Wl,'
 	lt_prog_compiler_pic='-fpic'
-	lt_prog_compiler_static='-static'
+	lt_prog_compiler_static='-Bstatic'
         ;;
       ccc*)
         lt_prog_compiler_wl='-Wl,'
         # All Alpha code is PIC.
         lt_prog_compiler_static='-non_shared'
         ;;
+      *)
+        case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	esac
+	;;
       esac
       ;;
 
@@ -6589,9 +7340,8 @@
       lt_prog_compiler_static='-non_shared'
       ;;
 
-    sco3.2v5*)
-      lt_prog_compiler_pic='-Kpic'
-      lt_prog_compiler_static='-dn'
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
       ;;
 
     solaris*)
@@ -6611,7 +7361,7 @@
       lt_prog_compiler_static='-Bstatic'
       ;;
 
-    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    sysv4 | sysv4.2uw2* | sysv4.3*)
       lt_prog_compiler_wl='-Wl,'
       lt_prog_compiler_pic='-KPIC'
       lt_prog_compiler_static='-Bstatic'
@@ -6624,6 +7374,12 @@
       fi
       ;;
 
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
     unicos*)
       lt_prog_compiler_wl='-Wl,'
       lt_prog_compiler_can_build_shared=no
@@ -6640,22 +7396,22 @@
     esac
   fi
 
-echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic" >&6
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic" >&6; }
 
 #
 # Check to make sure the PIC flag actually works.
 #
 if test -n "$lt_prog_compiler_pic"; then
 
-echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; }
 if test "${lt_prog_compiler_pic_works+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   lt_prog_compiler_pic_works=no
   ac_outfile=conftest.$ac_objext
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
    lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
@@ -6663,28 +7419,28 @@
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    # The option is referenced via a variable to avoid confusing sed.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6669: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7425: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6673: \$? = $ac_status" >&5
+   echo "$as_me:7429: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp
-     $SED '/^$/d' conftest.err >conftest.er2
-     if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        lt_prog_compiler_pic_works=yes
      fi
    fi
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6; }
 
 if test x"$lt_prog_compiler_pic_works" = xyes; then
     case $lt_prog_compiler_pic in
@@ -6697,7 +7453,7 @@
 fi
 
 fi
-case "$host_os" in
+case $host_os in
   # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic=
@@ -6707,8 +7463,50 @@
     ;;
 esac
 
-echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_static_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works=yes
+       fi
+     else
+       lt_prog_compiler_static_works=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works" >&6; }
+
+if test x"$lt_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
 if test "${lt_cv_prog_compiler_c_o+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -6717,7 +7515,7 @@
    mkdir conftest
    cd conftest
    mkdir out
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
    lt_compiler_flag="-o out/conftest2.$ac_objext"
    # Insert the option either (1) after the last *FLAGS variable, or
@@ -6725,25 +7523,25 @@
    # Note that $ac_compile itself does not contain backslashes and begins
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6731: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7529: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:6735: \$? = $ac_status" >&5
+   echo "$as_me:7533: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
-     $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp
-     $SED '/^$/d' out/conftest.err >out/conftest.er2
-     if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_c_o=yes
      fi
    fi
-   chmod u+w .
+   chmod u+w . 2>&5
    $rm conftest*
    # SGI C++ compiler will create directory out/ii_files/ for
    # template instantiation
@@ -6754,23 +7552,23 @@
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6; }
 
 
 hard_links="nottested"
 if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
-  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
   hard_links=yes
   $rm conftest*
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   touch conftest.a
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
-  echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6
+  { echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6; }
   if test "$hard_links" = no; then
     { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
@@ -6780,8 +7578,8 @@
   need_locks=no
 fi
 
-echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
 
   runpath_var=
   allow_undefined_flag=
@@ -6839,6 +7637,10 @@
       with_gnu_ld=no
     fi
     ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
   openbsd*)
     with_gnu_ld=no
     ;;
@@ -6920,10 +7722,10 @@
       allow_undefined_flag=unsupported
       always_export_symbols=no
       enable_shared_with_static_runtimes=yes
-      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
 
       if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
-        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	# If the export-symbols file already is a .def file (1st line
 	# is EXPORTS), use it as is; otherwise, prepend...
 	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -6932,22 +7734,37 @@
 	  echo EXPORTS > $output_objdir/$soname.def;
 	  cat $export_symbols >> $output_objdir/$soname.def;
 	fi~
-	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	ld_shlibs=no
       fi
       ;;
 
-    linux*)
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | k*bsd*-gnu)
       if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
 	tmp_addflag=
 	case $cc_basename,$host_cpu in
 	pgcc*)				# Portland Group C compiler
-	  whole_archive_flag_spec='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
-	pgf77* | pgf90* )			# Portland Group f77 and f90 compilers
-	  whole_archive_flag_spec='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)		# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -6956,13 +7773,22 @@
 	ifc* | ifort*)			# Intel Fortran compiler
 	  tmp_addflag=' -nofor_main' ;;
 	esac
-	archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	*)
+	  tmp_sharedflag='-shared' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
 	if test $supports_anon_versioning = yes; then
 	  archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
   cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
   $echo "local: *; };" >> $output_objdir/$libname.ver~
-	  $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	  $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	fi
       else
 	ld_shlibs=no
@@ -6979,7 +7805,7 @@
       fi
       ;;
 
-    solaris* | sysv5*)
+    solaris*)
       if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
 	ld_shlibs=no
 	cat <<EOF 1>&2
@@ -7000,6 +7826,33 @@
       fi
       ;;
 
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
     sunos4*)
       archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
       wlarc=
@@ -7033,7 +7886,7 @@
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       hardcode_minus_L=yes
-      if test "$GCC" = yes && test -z "$link_static_flag"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	hardcode_direct=unsupported
@@ -7067,6 +7920,7 @@
   	    break
   	  fi
 	  done
+	  ;;
 	esac
 
 	exp_sym_flag='-bexport'
@@ -7093,7 +7947,7 @@
   	   strings "$collect2name" | grep resolve_lib_name >/dev/null
 	  then
   	  # We have reworked collect2
-  	  hardcode_direct=yes
+  	  :
 	  else
   	  # We have old collect2
   	  hardcode_direct=unsupported
@@ -7104,6 +7958,7 @@
   	  hardcode_libdir_flag_spec='-L$libdir'
   	  hardcode_libdir_separator=
 	  fi
+	  ;;
 	esac
 	shared_flag='-shared'
 	if test "$aix_use_runtimelinking" = yes; then
@@ -7116,11 +7971,11 @@
   	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-  	if test "$aix_use_runtimelinking" = yes; then
+	  if test "$aix_use_runtimelinking" = yes; then
 	    shared_flag='${wl}-G'
 	  else
 	    shared_flag='${wl}-bM:SRE'
-  	fi
+	  fi
 	fi
       fi
 
@@ -7148,49 +8003,54 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
 
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
 # Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`; fi
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
-	archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+	archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
        else
 	if test "$host_cpu" = ia64; then
 	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
 	  allow_undefined_flag="-z nodefs"
-	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an empty executable.
 	 cat >conftest.$ac_ext <<_ACEOF
@@ -7209,39 +8069,44 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
 
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
 # Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`; fi
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -7250,13 +8115,11 @@
 	  # -berok will link without error, but may produce a broken library.
 	  no_undefined_flag=' ${wl}-bernotok'
 	  allow_undefined_flag=' ${wl}-berok'
-	  # -bexpall does not export symbols beginning with underscore (_)
-	  always_export_symbols=yes
 	  # Exported symbols can be pulled into shared objects from archives
-	  whole_archive_flag_spec=' '
+	  whole_archive_flag_spec='$convenience'
 	  archive_cmds_need_lc=yes
-	  # This is similar to how AIX traditionally builds it's shared libraries.
-	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -7289,13 +8152,13 @@
       # The linker will automatically build a .lib file if we build a DLL.
       old_archive_From_new_cmds='true'
       # FIXME: Should let the user specify the lib program.
-      old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
       fix_srcfile_path='`cygpath -w "$srcfile"`'
       enable_shared_with_static_runtimes=yes
       ;;
 
     darwin* | rhapsody*)
-      case "$host_os" in
+      case $host_os in
         rhapsody* | darwin1.[012])
          allow_undefined_flag='${wl}-undefined ${wl}suppress'
          ;;
@@ -7324,17 +8187,17 @@
     	output_verbose_link_cmd='echo'
         archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
       module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
       archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
       module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
     else
       case $cc_basename in
         xlc*)
          output_verbose_link_cmd='echo'
-         archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
          module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
-         archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           ;;
        *)
@@ -7374,7 +8237,7 @@
       ;;
 
     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
-    freebsd* | kfreebsd*-gnu | dragonfly*)
+    freebsd* | dragonfly*)
       archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
       hardcode_libdir_flag_spec='-R$libdir'
       hardcode_direct=yes
@@ -7397,47 +8260,62 @@
       export_dynamic_flag_spec='${wl}-E'
       ;;
 
-    hpux10* | hpux11*)
+    hpux10*)
       if test "$GCC" = yes -a "$with_gnu_ld" = no; then
-	case "$host_cpu" in
-	hppa*64*|ia64*)
+	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	hardcode_direct=yes
+	export_dynamic_flag_spec='${wl}-E'
+
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
 	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
 	*)
 	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
-	case "$host_cpu" in
-	hppa*64*|ia64*)
-	  archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
 	*)
-	  archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       fi
       if test "$with_gnu_ld" = no; then
-	case "$host_cpu" in
-	hppa*64*)
-	  hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
 	  hardcode_libdir_flag_spec_ld='+b $libdir'
-	  hardcode_libdir_separator=:
 	  hardcode_direct=no
 	  hardcode_shlibpath_var=no
 	  ;;
-	ia64*)
-	  hardcode_libdir_flag_spec='-L$libdir'
-	  hardcode_direct=no
-	  hardcode_shlibpath_var=no
-
-	  # hardcode_minus_L: Not really in the search PATH,
-	  # but as the default location of the library.
-	  hardcode_minus_L=yes
-	  ;;
 	*)
-	  hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
-	  hardcode_libdir_separator=:
 	  hardcode_direct=yes
 	  export_dynamic_flag_spec='${wl}-E'
 
@@ -7481,24 +8359,28 @@
       ;;
 
     openbsd*)
-      hardcode_direct=yes
-      hardcode_shlibpath_var=no
-      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-	archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
-	hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
-	export_dynamic_flag_spec='${wl}-E'
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+        fi
       else
-       case $host_os in
-	 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
-	   archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-	   hardcode_libdir_flag_spec='-R$libdir'
-	   ;;
-	 *)
-	   archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	   hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
-	   ;;
-       esac
+	ld_shlibs=no
       fi
       ;;
 
@@ -7539,14 +8421,6 @@
       hardcode_libdir_separator=:
       ;;
 
-    sco3.2v5*)
-      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      hardcode_shlibpath_var=no
-      export_dynamic_flag_spec='${wl}-Bexport'
-      runpath_var=LD_RUN_PATH
-      hardcode_runpath_var=yes
-      ;;
-
     solaris*)
       no_undefined_flag=' -z text'
       if test "$GCC" = yes; then
@@ -7565,17 +8439,16 @@
       case $host_os in
       solaris2.[0-5] | solaris2.[0-5].*) ;;
       *)
- 	# The compiler driver will combine linker options so we
- 	# cannot just pass the convience library names through
- 	# without $wl, iff we do not link with $LD.
- 	# Luckily, gcc supports the same syntax we need for Sun Studio.
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
  	# Supported since Solaris 2.6 (maybe 2.5.1?)
- 	case $wlarc in
- 	'')
- 	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
- 	*)
- 	  whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
- 	esac ;;
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
       esac
       link_all_deplibs=yes
       ;;
@@ -7632,36 +8505,45 @@
       fi
       ;;
 
-    sysv4.2uw2*)
-      archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
-      hardcode_direct=yes
-      hardcode_minus_L=no
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
       hardcode_shlibpath_var=no
-      hardcode_runpath_var=yes
-      runpath_var=LD_RUN_PATH
-      ;;
+      runpath_var='LD_RUN_PATH'
 
-   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[78]* | unixware7*)
-      no_undefined_flag='${wl}-z ${wl}text'
       if test "$GCC" = yes; then
-	archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
-      runpath_var='LD_RUN_PATH'
-      hardcode_shlibpath_var=no
       ;;
 
-    sysv5*)
-      no_undefined_flag=' -z text'
-      # $CC -shared without GNU ld will not create a library from C++
-      # object files and a static libstdc++, better avoid it by now
-      archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-  		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
-      hardcode_libdir_flag_spec=
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
       hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
       ;;
 
     uts4*)
@@ -7676,15 +8558,10 @@
     esac
   fi
 
-echo "$as_me:$LINENO: result: $ld_shlibs" >&5
-echo "${ECHO_T}$ld_shlibs" >&6
+{ echo "$as_me:$LINENO: result: $ld_shlibs" >&5
+echo "${ECHO_T}$ld_shlibs" >&6; }
 test "$ld_shlibs" = no && can_build_shared=no
 
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
-  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
 #
 # Do we need to explicitly link libc?
 #
@@ -7702,10 +8579,10 @@
       # Test whether the compiler implicitly links with -lc since on some
       # systems, -lgcc has to come before -lc. If gcc already passes -lc
       # to ld, don't add -lc before -lgcc.
-      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
       $rm conftest*
-      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
       if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
@@ -7717,6 +8594,7 @@
         libobjs=conftest.$ac_objext
         deplibs=
         wl=$lt_prog_compiler_wl
+	pic_flag=$lt_prog_compiler_pic
         compiler_flags=-v
         linker_flags=-v
         verstring=
@@ -7739,16 +8617,16 @@
         cat conftest.err 1>&5
       fi
       $rm conftest*
-      echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
-echo "${ECHO_T}$archive_cmds_need_lc" >&6
+      { echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
+echo "${ECHO_T}$archive_cmds_need_lc" >&6; }
       ;;
     esac
   fi
   ;;
 esac
 
-echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
@@ -7762,17 +8640,55 @@
 version_type=none
 dynamic_linker="$host_os ld.so"
 sys_lib_dlsearch_path_spec="/lib /usr/lib"
+
 if test "$GCC" = yes; then
-  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then
     # if the path contains ";" then we assume it to be the separator
     # otherwise default to the standard path separator (i.e. ":") - it is
     # assumed that no part of a normal pathname contains ";" but that should
     # okay in the real world where ";" in dirpaths is itself problematic.
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+    lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'`
   else
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+    lt_search_path_spec=`echo "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
   fi
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  sys_lib_search_path_spec=`echo $lt_search_path_spec`
 else
   sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
 fi
@@ -7877,7 +8793,8 @@
       dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
-      $install_prog $dir/$dlname \$dldir/$dlname'
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
     postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
       dlpath=$dir/\$dldll~
        $rm \$dlpath'
@@ -7930,13 +8847,9 @@
   soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
-  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
-  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
-  if test "$GCC" = yes; then
-    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
-  else
-    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
-  fi
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
   sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
   ;;
 
@@ -7953,22 +8866,17 @@
   dynamic_linker=no
   ;;
 
-kfreebsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
-  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
@@ -7990,10 +8898,15 @@
     shlibpath_overrides_runpath=yes
     hardcode_into_libs=yes
     ;;
-  *) # from 3.2 on
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
     shlibpath_overrides_runpath=no
     hardcode_into_libs=yes
     ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
   esac
   ;;
 
@@ -8013,7 +8926,7 @@
   version_type=sunos
   need_lib_prefix=no
   need_version=no
-  case "$host_cpu" in
+  case $host_cpu in
   ia64*)
     shrext_cmds='.so'
     hardcode_into_libs=yes
@@ -8053,6 +8966,18 @@
   postinstall_cmds='chmod 555 $lib'
   ;;
 
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
 irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
@@ -8096,7 +9021,7 @@
   ;;
 
 # This must be Linux ELF.
-linux*)
+linux* | k*bsd*-gnu)
   version_type=linux
   need_lib_prefix=no
   need_version=no
@@ -8112,7 +9037,7 @@
 
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ 	]*hwcap[ 	]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
   fi
 
@@ -8125,18 +9050,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-knetbsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -8174,6 +9087,7 @@
 
 openbsd*)
   version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
   # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
   case $host_os in
@@ -8217,11 +9131,8 @@
   sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
-sco3.2v5*)
-  version_type=osf
-  soname_spec='${libname}${release}${shared_ext}$major'
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  shlibpath_var=LD_LIBRARY_PATH
+rdos*)
+  dynamic_linker=no
   ;;
 
 solaris*)
@@ -8249,7 +9160,7 @@
   need_version=yes
   ;;
 
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
@@ -8282,6 +9193,29 @@
   fi
   ;;
 
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
 uts4*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -8293,12 +9227,17 @@
   dynamic_linker=no
   ;;
 esac
-echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6
+{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6; }
 test "$dynamic_linker" = no && can_build_shared=no
 
-echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
 hardcode_action=
 if test -n "$hardcode_libdir_flag_spec" || \
    test -n "$runpath_var" || \
@@ -8322,8 +9261,8 @@
   # directories.
   hardcode_action=unsupported
 fi
-echo "$as_me:$LINENO: result: $hardcode_action" >&5
-echo "${ECHO_T}$hardcode_action" >&6
+{ echo "$as_me:$LINENO: result: $hardcode_action" >&5
+echo "${ECHO_T}$hardcode_action" >&6; }
 
 if test "$hardcode_action" = relink; then
   # Fast installation is not supported
@@ -8336,29 +9275,30 @@
 
 striplib=
 old_striplib=
-echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; }
 if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
   test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
   test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
 else
 # FIXME - insert some real tests, host_os isn't really good enough
   case $host_os in
    darwin*)
        if test -n "$STRIP" ; then
          striplib="$STRIP -x"
-         echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+         old_striplib="$STRIP -S"
+         { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
        else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
        ;;
    *)
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
     ;;
   esac
 fi
@@ -8390,8 +9330,8 @@
 
   darwin*)
   # if libdl is installed we need to link against it
-    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+    { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
 if test "${ac_cv_lib_dl_dlopen+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -8404,56 +9344,53 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
 char dlopen ();
 int
 main ()
 {
-dlopen ();
+return dlopen ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_lib_dl_dlopen=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_dl_dlopen=no
+	ac_cv_lib_dl_dlopen=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
 if test $ac_cv_lib_dl_dlopen = yes; then
   lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
@@ -8467,8 +9404,8 @@
    ;;
 
   *)
-    echo "$as_me:$LINENO: checking for shl_load" >&5
-echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+    { echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; }
 if test "${ac_cv_func_shl_load+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -8495,73 +9432,64 @@
 
 #undef shl_load
 
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
-{
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
 char shl_load ();
 /* The GNU C library defines this for functions which it implements
     to always fail with ENOSYS.  Some functions are actually named
     something starting with __ and the normal name is an alias.  */
-#if defined (__stub_shl_load) || defined (__stub___shl_load)
+#if defined __stub_shl_load || defined __stub___shl_load
 choke me
-#else
-char (*f) () = shl_load;
 #endif
-#ifdef __cplusplus
-}
-#endif
 
 int
 main ()
 {
-return f != shl_load;
+return shl_load ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_func_shl_load=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_func_shl_load=no
+	ac_cv_func_shl_load=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
-echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6; }
 if test $ac_cv_func_shl_load = yes; then
   lt_cv_dlopen="shl_load"
 else
-  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
-echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; }
 if test "${ac_cv_lib_dld_shl_load+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -8574,61 +9502,58 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
 char shl_load ();
 int
 main ()
 {
-shl_load ();
+return shl_load ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_lib_dld_shl_load=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_dld_shl_load=no
+	ac_cv_lib_dld_shl_load=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; }
 if test $ac_cv_lib_dld_shl_load = yes; then
   lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
 else
-  echo "$as_me:$LINENO: checking for dlopen" >&5
-echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; }
 if test "${ac_cv_func_dlopen+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -8655,73 +9580,64 @@
 
 #undef dlopen
 
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
-{
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
 char dlopen ();
 /* The GNU C library defines this for functions which it implements
     to always fail with ENOSYS.  Some functions are actually named
     something starting with __ and the normal name is an alias.  */
-#if defined (__stub_dlopen) || defined (__stub___dlopen)
+#if defined __stub_dlopen || defined __stub___dlopen
 choke me
-#else
-char (*f) () = dlopen;
 #endif
-#ifdef __cplusplus
-}
-#endif
 
 int
 main ()
 {
-return f != dlopen;
+return dlopen ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_func_dlopen=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_func_dlopen=no
+	ac_cv_func_dlopen=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
-echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6; }
 if test $ac_cv_func_dlopen = yes; then
   lt_cv_dlopen="dlopen"
 else
-  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
 if test "${ac_cv_lib_dl_dlopen+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -8734,61 +9650,58 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
 char dlopen ();
 int
 main ()
 {
-dlopen ();
+return dlopen ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_lib_dl_dlopen=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_dl_dlopen=no
+	ac_cv_lib_dl_dlopen=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
 if test $ac_cv_lib_dl_dlopen = yes; then
   lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
-  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
-echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; }
 if test "${ac_cv_lib_svld_dlopen+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -8801,61 +9714,58 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
 char dlopen ();
 int
 main ()
 {
-dlopen ();
+return dlopen ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_lib_svld_dlopen=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_svld_dlopen=no
+	ac_cv_lib_svld_dlopen=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; }
 if test $ac_cv_lib_svld_dlopen = yes; then
   lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
 else
-  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
-echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; }
 if test "${ac_cv_lib_dld_dld_link+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -8868,56 +9778,53 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
 char dld_link ();
 int
 main ()
 {
-dld_link ();
+return dld_link ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_lib_dld_dld_link=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_dld_dld_link=no
+	ac_cv_lib_dld_dld_link=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; }
 if test $ac_cv_lib_dld_dld_link = yes; then
   lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
 fi
@@ -8952,13 +9859,13 @@
     test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
     save_LDFLAGS="$LDFLAGS"
-    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
 
     save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
-    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
-echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+    { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; }
 if test "${lt_cv_dlopen_self+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -8968,7 +9875,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 8971 "configure"
+#line 9878 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -9025,6 +9932,8 @@
       else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
       /* dlclose (self); */
     }
+  else
+    puts (dlerror ());
 
     exit (status);
 }
@@ -9034,12 +9943,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
-    (./conftest; exit; ) 2>/dev/null
+    (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
     case x$lt_status in
       x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
       x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
-      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
     esac
   else :
     # compilation failed
@@ -9050,13 +9959,13 @@
 
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6; }
 
     if test "x$lt_cv_dlopen_self" = xyes; then
-      LDFLAGS="$LDFLAGS $link_static_flag"
-      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
-echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; }
 if test "${lt_cv_dlopen_self_static+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -9066,7 +9975,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9069 "configure"
+#line 9978 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -9123,6 +10032,8 @@
       else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
       /* dlclose (self); */
     }
+  else
+    puts (dlerror ());
 
     exit (status);
 }
@@ -9132,12 +10043,12 @@
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
-    (./conftest; exit; ) 2>/dev/null
+    (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
     case x$lt_status in
       x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
       x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
-      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
     esac
   else :
     # compilation failed
@@ -9148,8 +10059,8 @@
 
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; }
     fi
 
     CPPFLAGS="$save_CPPFLAGS"
@@ -9170,19 +10081,19 @@
 fi
 
 
-# Report which librarie types wil actually be built
-echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
-echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $can_build_shared" >&5
-echo "${ECHO_T}$can_build_shared" >&6
+# Report which library types will actually be built
+{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6; }
 
-echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
-echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; }
 test "$can_build_shared" = "no" && enable_shared=no
 
 # On AIX, shared libraries and static libraries use the same namespace, and
 # are all built from PIC.
-case "$host_os" in
+case $host_os in
 aix3*)
   test "$enable_shared" = yes && enable_static=no
   if test -n "$RANLIB"; then
@@ -9197,15 +10108,15 @@
   fi
     ;;
 esac
-echo "$as_me:$LINENO: result: $enable_shared" >&5
-echo "${ECHO_T}$enable_shared" >&6
+{ echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6; }
 
-echo "$as_me:$LINENO: checking whether to build static libraries" >&5
-echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; }
 # Make sure either enable_shared or enable_static is yes.
 test "$enable_shared" = yes || enable_static=yes
-echo "$as_me:$LINENO: result: $enable_static" >&5
-echo "${ECHO_T}$enable_static" >&6
+{ echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6; }
 
 # The else clause should only fire when bootstrapping the
 # libtool distribution, otherwise you forgot to ship ltmain.sh
@@ -9220,7 +10131,7 @@
   # Now quote all the things that may contain metacharacters while being
   # careful not to overquote the AC_SUBSTed values.  We take copies of the
   # variables and quote the copies for generation of the libtool script.
-  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
     SED SHELL STRIP \
     libname_spec library_names_spec soname_spec extract_expsyms_cmds \
     old_striplib striplib file_magic_cmd finish_cmds finish_eval \
@@ -9262,6 +10173,7 @@
     module_cmds \
     module_expsym_cmds \
     lt_cv_prog_compiler_c_o \
+    fix_srcfile_path \
     exclude_expsyms \
     include_expsyms; do
 
@@ -9306,7 +10218,7 @@
 # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 #
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
 # Free Software Foundation, Inc.
 #
 # This file is part of GNU Libtool:
@@ -9386,6 +10298,9 @@
 # A C compiler.
 LTCC=$lt_LTCC
 
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
 # A language-specific compiler.
 CC=$lt_compiler
 
@@ -9627,7 +10542,7 @@
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
 
 # Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path"
+fix_srcfile_path=$lt_fix_srcfile_path
 
 # Set to yes if exported symbols are required.
 always_export_symbols=$always_export_symbols
@@ -9694,12 +10609,12 @@
 CC="$lt_save_CC"
 
 
-# Check whether --with-tags or --without-tags was given.
+# Check whether --with-tags was given.
 if test "${with_tags+set}" = set; then
-  withval="$with_tags"
-  tagnames="$withval"
-fi;
+  withval=$with_tags; tagnames="$withval"
+fi
 
+
 if test -f "$ltmain" && test -n "$tagnames"; then
   if test ! -f "${ofile}"; then
     { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5
@@ -9716,6 +10631,9 @@
 echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;}
     fi
   fi
+  if test -z "$LTCFLAGS"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
+  fi
 
   # Extract list of available tagged configurations in $ofile.
   # Note that this assumes the entire list is on one line.
@@ -9749,7 +10667,7 @@
 	if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
 	    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
 	    (test "X$CXX" != "Xg++"))) ; then
-	  ac_ext=cc
+	  ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
@@ -9768,6 +10686,7 @@
 hardcode_libdir_flag_spec_ld_CXX=
 hardcode_libdir_separator_CXX=
 hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
 hardcode_automatic_CXX=no
 module_cmds_CXX=
 module_expsym_cmds_CXX=
@@ -9785,37 +10704,40 @@
 compiler_lib_search_path_CXX=
 
 # Source file extension for C++ test sources.
-ac_ext=cc
+ac_ext=cpp
 
 # Object file extension for compiled C++ test sources.
 objext=o
 objext_CXX=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;\n"
+lt_simple_compile_test_code="int some_variable = 0;"
 
 # Code to be used in simple link tests
-lt_simple_link_test_code='int main(int, char *) { return(0); }\n'
+lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 
 # If no C compiler was specified, use CC.
 LTCC=${LTCC-"$CC"}
 
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
 # Allow CC to be a program name with arguments.
 compiler=$CC
 
 
 # save warnings/boilerplate of simple test code
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_compiler_boilerplate=`cat conftest.err`
 $rm conftest*
 
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_linker_boilerplate=`cat conftest.err`
 $rm conftest*
 
@@ -9830,12 +10752,12 @@
 if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
   lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
 else
-  unset lt_cv_prog_gnu_ld
+  $as_unset lt_cv_prog_gnu_ld
 fi
 if test -n "${lt_cv_path_LDCXX+set}"; then
   lt_cv_path_LD=$lt_cv_path_LDCXX
 else
-  unset lt_cv_path_LD
+  $as_unset lt_cv_path_LD
 fi
 test -z "${LDCXX+set}" || LD=$LDCXX
 CC=${CXX-"c++"}
@@ -9864,18 +10786,18 @@
   # Set up default GNU C++ configuration
 
 
-# Check whether --with-gnu-ld or --without-gnu-ld was given.
+# Check whether --with-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then
-  withval="$with_gnu_ld"
-  test "$withval" = no || with_gnu_ld=yes
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
 else
   with_gnu_ld=no
-fi;
+fi
+
 ac_prog=ld
 if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
-  echo "$as_me:$LINENO: checking for ld used by $CC" >&5
-echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
   case $host in
   *-*-mingw*)
     # gcc leaves a trailing carriage return which upsets mingw
@@ -9904,11 +10826,11 @@
     ;;
   esac
 elif test "$with_gnu_ld" = yes; then
-  echo "$as_me:$LINENO: checking for GNU ld" >&5
-echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
 else
-  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
-echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
 fi
 if test "${lt_cv_path_LD+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -9921,7 +10843,7 @@
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
       lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some GNU ld's only accept -v.
+      # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
@@ -9941,21 +10863,21 @@
 
 LD="$lt_cv_path_LD"
 if test -n "$LD"; then
-  echo "$as_me:$LINENO: result: $LD" >&5
-echo "${ECHO_T}$LD" >&6
+  { echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
 echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
    { (exit 1); exit 1; }; }
-echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
-echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
 if test "${lt_cv_prog_gnu_ld+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
 case `$LD -v 2>&1 </dev/null` in
 *GNU* | *'with BFD'*)
   lt_cv_prog_gnu_ld=yes
@@ -9965,8 +10887,8 @@
   ;;
 esac
 fi
-echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
-echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
 with_gnu_ld=$lt_cv_prog_gnu_ld
 
 
@@ -10016,8 +10938,8 @@
 fi
 
 # PORTME: fill in a description of your system's C++ link characteristics
-echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
 ld_shlibs_CXX=yes
 case $host_os in
   aix3*)
@@ -10046,6 +10968,7 @@
 	    ;;
 	  esac
 	done
+	;;
       esac
 
       exp_sym_flag='-bexport'
@@ -10072,7 +10995,7 @@
 	   strings "$collect2name" | grep resolve_lib_name >/dev/null
 	then
 	  # We have reworked collect2
-	  hardcode_direct_CXX=yes
+	  :
 	else
 	  # We have old collect2
 	  hardcode_direct_CXX=unsupported
@@ -10083,6 +11006,7 @@
 	  hardcode_libdir_flag_spec_CXX='-L$libdir'
 	  hardcode_libdir_separator_CXX=
 	fi
+	;;
       esac
       shared_flag='-shared'
       if test "$aix_use_runtimelinking" = yes; then
@@ -10127,50 +11051,55 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
 
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
 # Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`; fi
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
       hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-      archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
      else
       if test "$host_cpu" = ia64; then
 	hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
 	allow_undefined_flag_CXX="-z nodefs"
-	archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
       else
 	# Determine the default libpath from the value encoded in an empty executable.
 	cat >conftest.$ac_ext <<_ACEOF
@@ -10189,39 +11118,44 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
 
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
 # Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`; fi
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -10230,16 +11164,26 @@
 	# -berok will link without error, but may produce a broken library.
 	no_undefined_flag_CXX=' ${wl}-bernotok'
 	allow_undefined_flag_CXX=' ${wl}-berok'
-	# -bexpall does not export symbols beginning with underscore (_)
-	always_export_symbols_CXX=yes
 	# Exported symbols can be pulled into shared objects from archives
-	whole_archive_flag_spec_CXX=' '
+	whole_archive_flag_spec_CXX='$convenience'
 	archive_cmds_need_lc_CXX=yes
-	# This is similar to how AIX traditionally builds it's shared libraries.
-	archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	# This is similar to how AIX traditionally builds its shared libraries.
+	archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
       fi
     fi
     ;;
+
+  beos*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag_CXX=unsupported
+      # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs_CXX=no
+    fi
+    ;;
+
   chorus*)
     case $cc_basename in
       *)
@@ -10249,7 +11193,6 @@
     esac
     ;;
 
-
   cygwin* | mingw* | pw32*)
     # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
     # as there is no search path for DLLs.
@@ -10259,7 +11202,7 @@
     enable_shared_with_static_runtimes_CXX=yes
 
     if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
-      archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+      archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       # If the export-symbols file already is a .def file (1st line
       # is EXPORTS), use it as is; otherwise, prepend...
       archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -10268,13 +11211,13 @@
 	echo EXPORTS > $output_objdir/$soname.def;
 	cat $export_symbols >> $output_objdir/$soname.def;
       fi~
-      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
     else
       ld_shlibs_CXX=no
     fi
   ;;
       darwin* | rhapsody*)
-        case "$host_os" in
+        case $host_os in
         rhapsody* | darwin1.[012])
          allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress'
          ;;
@@ -10312,7 +11255,7 @@
           archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
         fi
         module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
           if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
             archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           else
@@ -10323,10 +11266,10 @@
       case $cc_basename in
         xlc*)
          output_verbose_link_cmd='echo'
-          archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+          archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
           module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
-          archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           ;;
        *)
@@ -10360,7 +11303,7 @@
   freebsd-elf*)
     archive_cmds_need_lc_CXX=no
     ;;
-  freebsd* | kfreebsd*-gnu | dragonfly*)
+  freebsd* | dragonfly*)
     # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
     # conventions
     ld_shlibs_CXX=yes
@@ -10405,34 +11348,21 @@
     ;;
   hpux10*|hpux11*)
     if test $with_gnu_ld = no; then
-      case "$host_cpu" in
-      hppa*64*)
-	hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
-	hardcode_libdir_flag_spec_ld_CXX='+b $libdir'
-	hardcode_libdir_separator_CXX=:
-        ;;
-      ia64*)
-	hardcode_libdir_flag_spec_CXX='-L$libdir'
-        ;;
+      hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_CXX=:
+
+      case $host_cpu in
+      hppa*64*|ia64*) ;;
       *)
-	hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
-	hardcode_libdir_separator_CXX=:
 	export_dynamic_flag_spec_CXX='${wl}-E'
         ;;
       esac
     fi
-    case "$host_cpu" in
-    hppa*64*)
+    case $host_cpu in
+    hppa*64*|ia64*)
       hardcode_direct_CXX=no
       hardcode_shlibpath_var_CXX=no
       ;;
-    ia64*)
-      hardcode_direct_CXX=no
-      hardcode_shlibpath_var_CXX=no
-      hardcode_minus_L_CXX=yes # Not in the search PATH,
-					      # but as the default
-					      # location of the library.
-      ;;
     *)
       hardcode_direct_CXX=yes
       hardcode_minus_L_CXX=yes # Not in the search PATH,
@@ -10447,10 +11377,13 @@
 	ld_shlibs_CXX=no
 	;;
       aCC*)
-	case "$host_cpu" in
-	hppa*64*|ia64*)
-	  archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	  ;;
+	ia64*)
+	  archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
 	*)
 	  archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	  ;;
@@ -10468,10 +11401,13 @@
       *)
 	if test "$GXX" = yes; then
 	  if test $with_gnu_ld = no; then
-	    case "$host_cpu" in
-	    ia64*|hppa*64*)
-	      archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+	    case $host_cpu in
+	    hppa*64*)
+	      archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	      ;;
+	    ia64*)
+	      archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
 	    *)
 	      archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	      ;;
@@ -10484,6 +11420,20 @@
 	;;
     esac
     ;;
+  interix[3-9]*)
+    hardcode_direct_CXX=no
+    hardcode_shlibpath_var_CXX=no
+    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+    export_dynamic_flag_spec_CXX='${wl}-E'
+    # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+    # Instead, shared libraries are loaded at an image base (0x10000000 by
+    # default) and relocated if they conflict, which is a slow very memory
+    # consuming and fragmenting process.  To avoid this, we pick a random,
+    # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+    # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+    archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    ;;
   irix5* | irix6*)
     case $cc_basename in
       CC*)
@@ -10510,7 +11460,7 @@
     hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
     hardcode_libdir_separator_CXX=:
     ;;
-  linux*)
+  linux* | k*bsd*-gnu)
     case $cc_basename in
       KCC*)
 	# Kuck and Associates, Inc. (KAI) C++ Compiler
@@ -10569,7 +11519,7 @@
 
 	hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
 	export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
-	whole_archive_flag_spec_CXX='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
         ;;
       cxx*)
 	# Compaq C++
@@ -10590,6 +11540,29 @@
 	# dependencies.
 	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
 	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C++ 5.9
+	  no_undefined_flag_CXX=' -zdefs'
+	  archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+
+	  # Not sure whether something based on
+	  # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	  # would be better.
+	  output_verbose_link_cmd='echo'
+
+	  # Archives containing C++ object files must be created using
+	  # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	  # necessary to make sure instantiated templates are included
+	  # in the archive.
+	  old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	  ;;
+	esac
+	;;
     esac
     ;;
   lynxos*)
@@ -10628,16 +11601,20 @@
     ld_shlibs_CXX=no
     ;;
   openbsd*)
-    hardcode_direct_CXX=yes
-    hardcode_shlibpath_var_CXX=no
-    archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
-    if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
-      export_dynamic_flag_spec_CXX='${wl}-E'
-      whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    if test -f /usr/libexec/ld.so; then
+      hardcode_direct_CXX=yes
+      hardcode_shlibpath_var_CXX=no
+      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	export_dynamic_flag_spec_CXX='${wl}-E'
+	whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      fi
+      output_verbose_link_cmd='echo'
+    else
+      ld_shlibs_CXX=no
     fi
-    output_verbose_link_cmd='echo'
     ;;
   osf3*)
     case $cc_basename in
@@ -10766,19 +11743,6 @@
     # FIXME: insert proper C++ library support
     ld_shlibs_CXX=no
     ;;
-  sco*)
-    archive_cmds_need_lc_CXX=no
-    case $cc_basename in
-      CC*)
-	# FIXME: insert proper C++ library support
-	ld_shlibs_CXX=no
-	;;
-      *)
-	# FIXME: insert proper C++ library support
-	ld_shlibs_CXX=no
-	;;
-    esac
-    ;;
   sunos4*)
     case $cc_basename in
       CC*)
@@ -10801,38 +11765,26 @@
     case $cc_basename in
       CC*)
 	# Sun C++ 4.2, 5.x and Centerline C++
+        archive_cmds_need_lc_CXX=yes
 	no_undefined_flag_CXX=' -zdefs'
-	archive_cmds_CXX='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-	$CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+	$CC -G${allow_undefined_flag}  ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
 
 	hardcode_libdir_flag_spec_CXX='-R$libdir'
 	hardcode_shlibpath_var_CXX=no
 	case $host_os in
 	  solaris2.[0-5] | solaris2.[0-5].*) ;;
 	  *)
-	    # The C++ compiler is used as linker so we must use $wl
-	    # flag to pass the commands to the underlying system
-	    # linker. We must also pass each convience library through
-	    # to the system linker between allextract/defaultextract.
-	    # The C++ compiler will combine linker options so we
-	    # cannot just pass the convience library names through
-	    # without $wl.
+	    # The compiler driver will combine and reorder linker options,
+	    # but understands `-z linker_flag'.
 	    # Supported since Solaris 2.6 (maybe 2.5.1?)
-	    whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
+	    whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
 	    ;;
 	esac
 	link_all_deplibs_CXX=yes
 
-	# Commands to make compiler produce verbose output that lists
-	# what "hidden" libraries, object files and flags are used when
-	# linking a shared library.
-	#
-	# There doesn't appear to be a way to prevent this compiler from
-	# explicitly linking system object files so we need to strip them
-	# from the output so that they don't get included in the library
-	# dependencies.
-	output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[LR]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	output_verbose_link_cmd='echo'
 
 	# Archives containing C++ object files must be created using
 	# "CC -xar", where "CC" is the Sun C++ compiler.  This is
@@ -10874,13 +11826,70 @@
 	  fi
 
 	  hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	  case $host_os in
+	  solaris2.[0-5] | solaris2.[0-5].*) ;;
+	  *)
+	    whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	    ;;
+	  esac
 	fi
 	;;
     esac
     ;;
-  sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*)
+  sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+    no_undefined_flag_CXX='${wl}-z,text'
     archive_cmds_need_lc_CXX=no
+    hardcode_shlibpath_var_CXX=no
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+	archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      *)
+	archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+    esac
     ;;
+  sysv5* | sco3.2v5* | sco5v6*)
+    # Note: We can NOT use -z defs as we might desire, because we do not
+    # link with -lc, and that would cause any symbols used from libc to
+    # always be unresolved, which means just about no library would
+    # ever link correctly.  If we're not using GNU ld we use -z text
+    # though, which does catch some bad symbols but isn't as heavy-handed
+    # as -z defs.
+    # For security reasons, it is highly recommended that you always
+    # use absolute paths for naming shared libraries, and exclude the
+    # DT_RUNPATH tag from executables and libraries.  But doing so
+    # requires that you compile everything twice, which is a pain.
+    # So that behaviour is only enabled if SCOABSPATH is set to a
+    # non-empty value in the environment.  Most likely only useful for
+    # creating official distributions of packages.
+    # This is a hack until libtool officially supports absolute path
+    # names for shared libraries.
+    no_undefined_flag_CXX='${wl}-z,text'
+    allow_undefined_flag_CXX='${wl}-z,nodefs'
+    archive_cmds_need_lc_CXX=no
+    hardcode_shlibpath_var_CXX=no
+    hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+    hardcode_libdir_separator_CXX=':'
+    link_all_deplibs_CXX=yes
+    export_dynamic_flag_spec_CXX='${wl}-Bexport'
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+	archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      *)
+	archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+    esac
+    ;;
   tandem*)
     case $cc_basename in
       NCC*)
@@ -10903,8 +11912,8 @@
     ld_shlibs_CXX=no
     ;;
 esac
-echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
-echo "${ECHO_T}$ld_shlibs_CXX" >&6
+{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6; }
 test "$ld_shlibs_CXX" = no && can_build_shared=no
 
 GCC_CXX="$GXX"
@@ -10936,7 +11945,7 @@
   # The `*' in the case matches for architectures that use `case' in
   # $output_verbose_cmd can trigger glob expansion during the loop
   # eval without this substitution.
-  output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+  output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
 
   for p in `eval $output_verbose_link_cmd`; do
     case $p in
@@ -11012,6 +12021,62 @@
 
 $rm -f confest.$objext
 
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+    #
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
 case " $postdeps_CXX " in
 *" -lc "*) archive_cmds_need_lc_CXX=no ;;
 esac
@@ -11020,8 +12085,8 @@
 lt_prog_compiler_pic_CXX=
 lt_prog_compiler_static_CXX=
 
-echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
 
   # C++ specific cases for pic, static, wl, etc.
   if test "$GXX" = yes; then
@@ -11042,12 +12107,14 @@
       # like `-m68040'.
       lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
       ;;
-    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
       # PIC is the default for these OSes.
       ;;
-    mingw* | os2* | pw32*)
+    mingw* | cygwin* | os2* | pw32*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
       lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
       ;;
     darwin* | rhapsody*)
@@ -11059,6 +12126,10 @@
       # DJGPP does not support shared libraries at all
       lt_prog_compiler_pic_CXX=
       ;;
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
     sysv4*MP*)
       if test -d /usr/nec; then
 	lt_prog_compiler_pic_CXX=-Kconform_pic
@@ -11067,7 +12138,7 @@
     hpux*)
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	;;
       *)
@@ -11121,22 +12192,22 @@
 	    ;;
 	esac
 	;;
-      freebsd* | kfreebsd*-gnu | dragonfly*)
+      freebsd* | dragonfly*)
 	# FreeBSD uses GNU C++
 	;;
       hpux9* | hpux10* | hpux11*)
 	case $cc_basename in
 	  CC*)
 	    lt_prog_compiler_wl_CXX='-Wl,'
-	    lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
 	    if test "$host_cpu" != ia64; then
 	      lt_prog_compiler_pic_CXX='+Z'
 	    fi
 	    ;;
 	  aCC*)
 	    lt_prog_compiler_wl_CXX='-Wl,'
-	    lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
-	    case "$host_cpu" in
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
 	    hppa*64*|ia64*)
 	      # +Z the default
 	      ;;
@@ -11149,6 +12220,10 @@
 	    ;;
 	esac
 	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
       irix5* | irix6* | nonstopux*)
 	case $cc_basename in
 	  CC*)
@@ -11160,7 +12235,7 @@
 	    ;;
 	esac
 	;;
-      linux*)
+      linux* | k*bsd*-gnu)
 	case $cc_basename in
 	  KCC*)
 	    # KAI C++ Compiler
@@ -11177,7 +12252,7 @@
 	    # Portland Group C++ compiler.
 	    lt_prog_compiler_wl_CXX='-Wl,'
 	    lt_prog_compiler_pic_CXX='-fpic'
-	    lt_prog_compiler_static_CXX='-static'
+	    lt_prog_compiler_static_CXX='-Bstatic'
 	    ;;
 	  cxx*)
 	    # Compaq C++
@@ -11187,6 +12262,14 @@
 	    lt_prog_compiler_static_CXX='-non_shared'
 	    ;;
 	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
 	    ;;
 	esac
 	;;
@@ -11228,15 +12311,6 @@
 	;;
       psos*)
 	;;
-      sco*)
-	case $cc_basename in
-	  CC*)
-	    lt_prog_compiler_pic_CXX='-fPIC'
-	    ;;
-	  *)
-	    ;;
-	esac
-	;;
       solaris*)
 	case $cc_basename in
 	  CC*)
@@ -11278,7 +12352,14 @@
 	    ;;
 	esac
 	;;
-      unixware*)
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
 	;;
       vxworks*)
 	;;
@@ -11288,22 +12369,22 @@
     esac
   fi
 
-echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6; }
 
 #
 # Check to make sure the PIC flag actually works.
 #
 if test -n "$lt_prog_compiler_pic_CXX"; then
 
-echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6; }
 if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   lt_prog_compiler_pic_works_CXX=no
   ac_outfile=conftest.$ac_objext
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
    lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
@@ -11311,28 +12392,28 @@
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    # The option is referenced via a variable to avoid confusing sed.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11317: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12398: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:11321: \$? = $ac_status" >&5
+   echo "$as_me:12402: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp
-     $SED '/^$/d' conftest.err >conftest.er2
-     if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        lt_prog_compiler_pic_works_CXX=yes
      fi
    fi
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6; }
 
 if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then
     case $lt_prog_compiler_pic_CXX in
@@ -11345,7 +12426,7 @@
 fi
 
 fi
-case "$host_os" in
+case $host_os in
   # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic_CXX=
@@ -11355,8 +12436,50 @@
     ;;
 esac
 
-echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_static_works_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works_CXX=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works_CXX=yes
+       fi
+     else
+       lt_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+fi
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
 if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -11365,7 +12488,7 @@
    mkdir conftest
    cd conftest
    mkdir out
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
    lt_compiler_flag="-o out/conftest2.$ac_objext"
    # Insert the option either (1) after the last *FLAGS variable, or
@@ -11373,25 +12496,25 @@
    # Note that $ac_compile itself does not contain backslashes and begins
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11379: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12502: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:11383: \$? = $ac_status" >&5
+   echo "$as_me:12506: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
-     $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp
-     $SED '/^$/d' out/conftest.err >out/conftest.er2
-     if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_c_o_CXX=yes
      fi
    fi
-   chmod u+w .
+   chmod u+w . 2>&5
    $rm conftest*
    # SGI C++ compiler will create directory out/ii_files/ for
    # template instantiation
@@ -11402,23 +12525,23 @@
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6; }
 
 
 hard_links="nottested"
 if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
-  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
   hard_links=yes
   $rm conftest*
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   touch conftest.a
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
-  echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6
+  { echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6; }
   if test "$hard_links" = no; then
     { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
@@ -11428,8 +12551,8 @@
   need_locks=no
 fi
 
-echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
 
   export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
   case $host_os in
@@ -11446,22 +12569,17 @@
     export_symbols_cmds_CXX="$ltdll_cmds"
   ;;
   cygwin* | mingw*)
-    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
   ;;
   *)
     export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
   ;;
   esac
 
-echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
-echo "${ECHO_T}$ld_shlibs_CXX" >&6
+{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6; }
 test "$ld_shlibs_CXX" = no && can_build_shared=no
 
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
-  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
 #
 # Do we need to explicitly link libc?
 #
@@ -11479,10 +12597,10 @@
       # Test whether the compiler implicitly links with -lc since on some
       # systems, -lgcc has to come before -lc. If gcc already passes -lc
       # to ld, don't add -lc before -lgcc.
-      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
       $rm conftest*
-      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
       if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
@@ -11494,6 +12612,7 @@
         libobjs=conftest.$ac_objext
         deplibs=
         wl=$lt_prog_compiler_wl_CXX
+	pic_flag=$lt_prog_compiler_pic_CXX
         compiler_flags=-v
         linker_flags=-v
         verstring=
@@ -11516,16 +12635,16 @@
         cat conftest.err 1>&5
       fi
       $rm conftest*
-      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5
-echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6
+      { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6; }
       ;;
     esac
   fi
   ;;
 esac
 
-echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
@@ -11539,20 +12658,7 @@
 version_type=none
 dynamic_linker="$host_os ld.so"
 sys_lib_dlsearch_path_spec="/lib /usr/lib"
-if test "$GCC" = yes; then
-  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
-    # if the path contains ";" then we assume it to be the separator
-    # otherwise default to the standard path separator (i.e. ":") - it is
-    # assumed that no part of a normal pathname contains ";" but that should
-    # okay in the real world where ";" in dirpaths is itself problematic.
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
-  else
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
-  fi
-else
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
+
 need_lib_prefix=unknown
 hardcode_into_libs=no
 
@@ -11654,7 +12760,8 @@
       dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
-      $install_prog $dir/$dlname \$dldir/$dlname'
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
     postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
       dlpath=$dir/\$dldll~
        $rm \$dlpath'
@@ -11707,13 +12814,8 @@
   soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
-  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
-  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
-  if test "$GCC" = yes; then
-    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
-  else
-    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
-  fi
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
   sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
   ;;
 
@@ -11730,22 +12832,17 @@
   dynamic_linker=no
   ;;
 
-kfreebsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
-  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
@@ -11767,10 +12864,15 @@
     shlibpath_overrides_runpath=yes
     hardcode_into_libs=yes
     ;;
-  *) # from 3.2 on
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
     shlibpath_overrides_runpath=no
     hardcode_into_libs=yes
     ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
   esac
   ;;
 
@@ -11790,7 +12892,7 @@
   version_type=sunos
   need_lib_prefix=no
   need_version=no
-  case "$host_cpu" in
+  case $host_cpu in
   ia64*)
     shrext_cmds='.so'
     hardcode_into_libs=yes
@@ -11830,6 +12932,18 @@
   postinstall_cmds='chmod 555 $lib'
   ;;
 
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
 irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
@@ -11873,7 +12987,7 @@
   ;;
 
 # This must be Linux ELF.
-linux*)
+linux* | k*bsd*-gnu)
   version_type=linux
   need_lib_prefix=no
   need_version=no
@@ -11889,7 +13003,7 @@
 
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ 	]*hwcap[ 	]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
   fi
 
@@ -11902,18 +13016,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-knetbsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -11951,6 +13053,7 @@
 
 openbsd*)
   version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
   # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
   case $host_os in
@@ -11994,11 +13097,8 @@
   sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
-sco3.2v5*)
-  version_type=osf
-  soname_spec='${libname}${release}${shared_ext}$major'
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  shlibpath_var=LD_LIBRARY_PATH
+rdos*)
+  dynamic_linker=no
   ;;
 
 solaris*)
@@ -12026,7 +13126,7 @@
   need_version=yes
   ;;
 
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
@@ -12059,6 +13159,29 @@
   fi
   ;;
 
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
 uts4*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -12070,12 +13193,17 @@
   dynamic_linker=no
   ;;
 esac
-echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6
+{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6; }
 test "$dynamic_linker" = no && can_build_shared=no
 
-echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
 hardcode_action_CXX=
 if test -n "$hardcode_libdir_flag_spec_CXX" || \
    test -n "$runpath_var_CXX" || \
@@ -12099,8 +13227,8 @@
   # directories.
   hardcode_action_CXX=unsupported
 fi
-echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
-echo "${ECHO_T}$hardcode_action_CXX" >&6
+{ echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
+echo "${ECHO_T}$hardcode_action_CXX" >&6; }
 
 if test "$hardcode_action_CXX" = relink; then
   # Fast installation is not supported
@@ -12111,842 +13239,7 @@
   enable_fast_install=needless
 fi
 
-striplib=
-old_striplib=
-echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
-  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
-  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-else
-# FIXME - insert some real tests, host_os isn't really good enough
-  case $host_os in
-   darwin*)
-       if test -n "$STRIP" ; then
-         striplib="$STRIP -x"
-         echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-       else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-       ;;
-   *)
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-    ;;
-  esac
-fi
 
-if test "x$enable_dlopen" != xyes; then
-  enable_dlopen=unknown
-  enable_dlopen_self=unknown
-  enable_dlopen_self_static=unknown
-else
-  lt_cv_dlopen=no
-  lt_cv_dlopen_libs=
-
-  case $host_os in
-  beos*)
-    lt_cv_dlopen="load_add_on"
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=yes
-    ;;
-
-  mingw* | pw32*)
-    lt_cv_dlopen="LoadLibrary"
-    lt_cv_dlopen_libs=
-   ;;
-
-  cygwin*)
-    lt_cv_dlopen="dlopen"
-    lt_cv_dlopen_libs=
-   ;;
-
-  darwin*)
-  # if libdl is installed we need to link against it
-    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_dl_dlopen=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dl_dlopen=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
-if test $ac_cv_lib_dl_dlopen = yes; then
-  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-
-    lt_cv_dlopen="dyld"
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=yes
-
-fi
-
-   ;;
-
-  *)
-    echo "$as_me:$LINENO: checking for shl_load" >&5
-echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
-if test "${ac_cv_func_shl_load+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define shl_load innocuous_shl_load
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char shl_load (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef shl_load
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char shl_load ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_shl_load) || defined (__stub___shl_load)
-choke me
-#else
-char (*f) () = shl_load;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != shl_load;
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_shl_load=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_shl_load=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
-echo "${ECHO_T}$ac_cv_func_shl_load" >&6
-if test $ac_cv_func_shl_load = yes; then
-  lt_cv_dlopen="shl_load"
-else
-  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
-echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char shl_load ();
-int
-main ()
-{
-shl_load ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_dld_shl_load=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_shl_load=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
-if test $ac_cv_lib_dld_shl_load = yes; then
-  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
-else
-  echo "$as_me:$LINENO: checking for dlopen" >&5
-echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
-if test "${ac_cv_func_dlopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define dlopen innocuous_dlopen
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char dlopen (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef dlopen
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_dlopen) || defined (__stub___dlopen)
-choke me
-#else
-char (*f) () = dlopen;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != dlopen;
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_dlopen=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_dlopen=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
-echo "${ECHO_T}$ac_cv_func_dlopen" >&6
-if test $ac_cv_func_dlopen = yes; then
-  lt_cv_dlopen="dlopen"
-else
-  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_dl_dlopen=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dl_dlopen=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
-if test $ac_cv_lib_dl_dlopen = yes; then
-  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
-echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsvld  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_svld_dlopen=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_svld_dlopen=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
-if test $ac_cv_lib_svld_dlopen = yes; then
-  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
-else
-  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
-echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dld_link ();
-int
-main ()
-{
-dld_link ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_cxx_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_dld_dld_link=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_dld_link=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
-if test $ac_cv_lib_dld_dld_link = yes; then
-  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-    ;;
-  esac
-
-  if test "x$lt_cv_dlopen" != xno; then
-    enable_dlopen=yes
-  else
-    enable_dlopen=no
-  fi
-
-  case $lt_cv_dlopen in
-  dlopen)
-    save_CPPFLAGS="$CPPFLAGS"
-    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
-    save_LDFLAGS="$LDFLAGS"
-    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
-    save_LIBS="$LIBS"
-    LIBS="$lt_cv_dlopen_libs $LIBS"
-
-    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
-echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
-if test "${lt_cv_dlopen_self+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  	  if test "$cross_compiling" = yes; then :
-  lt_cv_dlopen_self=cross
-else
-  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
-  lt_status=$lt_dlunknown
-  cat > conftest.$ac_ext <<EOF
-#line 12748 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-#  define LT_DLGLOBAL		RTLD_GLOBAL
-#else
-#  ifdef DL_GLOBAL
-#    define LT_DLGLOBAL		DL_GLOBAL
-#  else
-#    define LT_DLGLOBAL		0
-#  endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
-   find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-#  ifdef RTLD_LAZY
-#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
-#  else
-#    ifdef DL_LAZY
-#      define LT_DLLAZY_OR_NOW		DL_LAZY
-#    else
-#      ifdef RTLD_NOW
-#        define LT_DLLAZY_OR_NOW	RTLD_NOW
-#      else
-#        ifdef DL_NOW
-#          define LT_DLLAZY_OR_NOW	DL_NOW
-#        else
-#          define LT_DLLAZY_OR_NOW	0
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
-  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
-  int status = $lt_dlunknown;
-
-  if (self)
-    {
-      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
-      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
-      /* dlclose (self); */
-    }
-
-    exit (status);
-}
-EOF
-  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
-    (./conftest; exit; ) 2>/dev/null
-    lt_status=$?
-    case x$lt_status in
-      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
-      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
-      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
-    esac
-  else :
-    # compilation failed
-    lt_cv_dlopen_self=no
-  fi
-fi
-rm -fr conftest*
-
-
-fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self" >&6
-
-    if test "x$lt_cv_dlopen_self" = xyes; then
-      LDFLAGS="$LDFLAGS $link_static_flag"
-      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
-echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
-if test "${lt_cv_dlopen_self_static+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  	  if test "$cross_compiling" = yes; then :
-  lt_cv_dlopen_self_static=cross
-else
-  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
-  lt_status=$lt_dlunknown
-  cat > conftest.$ac_ext <<EOF
-#line 12846 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-#  define LT_DLGLOBAL		RTLD_GLOBAL
-#else
-#  ifdef DL_GLOBAL
-#    define LT_DLGLOBAL		DL_GLOBAL
-#  else
-#    define LT_DLGLOBAL		0
-#  endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
-   find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-#  ifdef RTLD_LAZY
-#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
-#  else
-#    ifdef DL_LAZY
-#      define LT_DLLAZY_OR_NOW		DL_LAZY
-#    else
-#      ifdef RTLD_NOW
-#        define LT_DLLAZY_OR_NOW	RTLD_NOW
-#      else
-#        ifdef DL_NOW
-#          define LT_DLLAZY_OR_NOW	DL_NOW
-#        else
-#          define LT_DLLAZY_OR_NOW	0
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
-  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
-  int status = $lt_dlunknown;
-
-  if (self)
-    {
-      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
-      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
-      /* dlclose (self); */
-    }
-
-    exit (status);
-}
-EOF
-  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
-    (./conftest; exit; ) 2>/dev/null
-    lt_status=$?
-    case x$lt_status in
-      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
-      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
-      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
-    esac
-  else :
-    # compilation failed
-    lt_cv_dlopen_self_static=no
-  fi
-fi
-rm -fr conftest*
-
-
-fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
-    fi
-
-    CPPFLAGS="$save_CPPFLAGS"
-    LDFLAGS="$save_LDFLAGS"
-    LIBS="$save_LIBS"
-    ;;
-  esac
-
-  case $lt_cv_dlopen_self in
-  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
-  *) enable_dlopen_self=unknown ;;
-  esac
-
-  case $lt_cv_dlopen_self_static in
-  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
-  *) enable_dlopen_self_static=unknown ;;
-  esac
-fi
-
-
 # The else clause should only fire when bootstrapping the
 # libtool distribution, otherwise you forgot to ship ltmain.sh
 # with your package, and you will get complaints that there are
@@ -12960,7 +13253,7 @@
   # Now quote all the things that may contain metacharacters while being
   # careful not to overquote the AC_SUBSTed values.  We take copies of the
   # variables and quote the copies for generation of the libtool script.
-  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
     SED SHELL STRIP \
     libname_spec library_names_spec soname_spec extract_expsyms_cmds \
     old_striplib striplib file_magic_cmd finish_cmds finish_eval \
@@ -13002,6 +13295,7 @@
     module_cmds_CXX \
     module_expsym_cmds_CXX \
     lt_cv_prog_compiler_c_o_CXX \
+    fix_srcfile_path_CXX \
     exclude_expsyms_CXX \
     include_expsyms_CXX; do
 
@@ -13078,6 +13372,9 @@
 # A C compiler.
 LTCC=$lt_LTCC
 
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
 # A language-specific compiler.
 CC=$lt_compiler_CXX
 
@@ -13319,7 +13616,7 @@
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
 
 # Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path_CXX"
+fix_srcfile_path=$lt_fix_srcfile_path
 
 # Set to yes if exported symbols are required.
 always_export_symbols=$always_export_symbols_CXX
@@ -13410,30 +13707,40 @@
 objext_F77=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
 
 # Code to be used in simple link tests
-lt_simple_link_test_code="      program t\n      end\n"
+lt_simple_link_test_code="\
+      program t
+      end
+"
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 
 # If no C compiler was specified, use CC.
 LTCC=${LTCC-"$CC"}
 
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
 # Allow CC to be a program name with arguments.
 compiler=$CC
 
 
 # save warnings/boilerplate of simple test code
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_compiler_boilerplate=`cat conftest.err`
 $rm conftest*
 
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_linker_boilerplate=`cat conftest.err`
 $rm conftest*
 
@@ -13454,18 +13761,18 @@
 cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
 
 
-echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
-echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $can_build_shared" >&5
-echo "${ECHO_T}$can_build_shared" >&6
+{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6; }
 
-echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
-echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; }
 test "$can_build_shared" = "no" && enable_shared=no
 
 # On AIX, shared libraries and static libraries use the same namespace, and
 # are all built from PIC.
-case "$host_os" in
+case $host_os in
 aix3*)
   test "$enable_shared" = yes && enable_static=no
   if test -n "$RANLIB"; then
@@ -13479,18 +13786,16 @@
   fi
   ;;
 esac
-echo "$as_me:$LINENO: result: $enable_shared" >&5
-echo "${ECHO_T}$enable_shared" >&6
+{ echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6; }
 
-echo "$as_me:$LINENO: checking whether to build static libraries" >&5
-echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; }
 # Make sure either enable_shared or enable_static is yes.
 test "$enable_shared" = yes || enable_static=yes
-echo "$as_me:$LINENO: result: $enable_static" >&5
-echo "${ECHO_T}$enable_static" >&6
+{ echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6; }
 
-test "$ld_shlibs_F77" = no && can_build_shared=no
-
 GCC_F77="$G77"
 LD_F77="$LD"
 
@@ -13498,8 +13803,8 @@
 lt_prog_compiler_pic_F77=
 lt_prog_compiler_static_F77=
 
-echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
 
   if test "$GCC" = yes; then
     lt_prog_compiler_wl_F77='-Wl,'
@@ -13521,13 +13826,15 @@
       lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4'
       ;;
 
-    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
       # PIC is the default for these OSes.
       ;;
 
-    mingw* | pw32* | os2*)
+    mingw* | cygwin* | pw32* | os2*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
       lt_prog_compiler_pic_F77='-DDLL_EXPORT'
       ;;
 
@@ -13537,6 +13844,11 @@
       lt_prog_compiler_pic_F77='-fno-common'
       ;;
 
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
     msdosdjgpp*)
       # Just because we use GCC doesn't mean we suddenly get shared libraries
       # on systems that don't support them.
@@ -13553,7 +13865,7 @@
     hpux*)
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	# +Z the default
 	;;
@@ -13590,7 +13902,7 @@
        esac
        ;;
 
-    mingw* | pw32* | os2*)
+    mingw* | cygwin* | pw32* | os2*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       lt_prog_compiler_pic_F77='-DDLL_EXPORT'
@@ -13600,7 +13912,7 @@
       lt_prog_compiler_wl_F77='-Wl,'
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	# +Z the default
 	;;
@@ -13623,25 +13935,41 @@
       lt_prog_compiler_static_F77='-Bstatic'
       ;;
 
-    linux*)
+    linux* | k*bsd*-gnu)
       case $cc_basename in
       icc* | ecc*)
 	lt_prog_compiler_wl_F77='-Wl,'
 	lt_prog_compiler_pic_F77='-KPIC'
 	lt_prog_compiler_static_F77='-static'
         ;;
-      pgcc* | pgf77* | pgf90*)
+      pgcc* | pgf77* | pgf90* | pgf95*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
 	lt_prog_compiler_wl_F77='-Wl,'
 	lt_prog_compiler_pic_F77='-fpic'
-	lt_prog_compiler_static_F77='-static'
+	lt_prog_compiler_static_F77='-Bstatic'
         ;;
       ccc*)
         lt_prog_compiler_wl_F77='-Wl,'
         # All Alpha code is PIC.
         lt_prog_compiler_static_F77='-non_shared'
         ;;
+      *)
+        case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic_F77='-KPIC'
+	  lt_prog_compiler_static_F77='-Bstatic'
+	  lt_prog_compiler_wl_F77='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic_F77='-KPIC'
+	  lt_prog_compiler_static_F77='-Bstatic'
+	  lt_prog_compiler_wl_F77=''
+	  ;;
+	esac
+	;;
       esac
       ;;
 
@@ -13651,9 +13979,8 @@
       lt_prog_compiler_static_F77='-non_shared'
       ;;
 
-    sco3.2v5*)
-      lt_prog_compiler_pic_F77='-Kpic'
-      lt_prog_compiler_static_F77='-dn'
+    rdos*)
+      lt_prog_compiler_static_F77='-non_shared'
       ;;
 
     solaris*)
@@ -13673,7 +14000,7 @@
       lt_prog_compiler_static_F77='-Bstatic'
       ;;
 
-    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    sysv4 | sysv4.2uw2* | sysv4.3*)
       lt_prog_compiler_wl_F77='-Wl,'
       lt_prog_compiler_pic_F77='-KPIC'
       lt_prog_compiler_static_F77='-Bstatic'
@@ -13686,6 +14013,12 @@
       fi
       ;;
 
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
     unicos*)
       lt_prog_compiler_wl_F77='-Wl,'
       lt_prog_compiler_can_build_shared_F77=no
@@ -13702,22 +14035,22 @@
     esac
   fi
 
-echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6; }
 
 #
 # Check to make sure the PIC flag actually works.
 #
 if test -n "$lt_prog_compiler_pic_F77"; then
 
-echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6; }
 if test "${lt_prog_compiler_pic_works_F77+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   lt_prog_compiler_pic_works_F77=no
   ac_outfile=conftest.$ac_objext
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
    lt_compiler_flag="$lt_prog_compiler_pic_F77"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
@@ -13725,28 +14058,28 @@
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    # The option is referenced via a variable to avoid confusing sed.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13731: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14064: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:13735: \$? = $ac_status" >&5
+   echo "$as_me:14068: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp
-     $SED '/^$/d' conftest.err >conftest.er2
-     if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        lt_prog_compiler_pic_works_F77=yes
      fi
    fi
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6; }
 
 if test x"$lt_prog_compiler_pic_works_F77" = xyes; then
     case $lt_prog_compiler_pic_F77 in
@@ -13759,7 +14092,7 @@
 fi
 
 fi
-case "$host_os" in
+case $host_os in
   # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic_F77=
@@ -13769,8 +14102,50 @@
     ;;
 esac
 
-echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\"
+{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_static_works_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works_F77=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works_F77=yes
+       fi
+     else
+       lt_prog_compiler_static_works_F77=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6; }
+
+if test x"$lt_prog_compiler_static_works_F77" = xyes; then
+    :
+else
+    lt_prog_compiler_static_F77=
+fi
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
 if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -13779,7 +14154,7 @@
    mkdir conftest
    cd conftest
    mkdir out
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
    lt_compiler_flag="-o out/conftest2.$ac_objext"
    # Insert the option either (1) after the last *FLAGS variable, or
@@ -13787,25 +14162,25 @@
    # Note that $ac_compile itself does not contain backslashes and begins
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13793: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14168: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13797: \$? = $ac_status" >&5
+   echo "$as_me:14172: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
-     $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp
-     $SED '/^$/d' out/conftest.err >out/conftest.er2
-     if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_c_o_F77=yes
      fi
    fi
-   chmod u+w .
+   chmod u+w . 2>&5
    $rm conftest*
    # SGI C++ compiler will create directory out/ii_files/ for
    # template instantiation
@@ -13816,23 +14191,23 @@
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6; }
 
 
 hard_links="nottested"
 if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
-  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
   hard_links=yes
   $rm conftest*
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   touch conftest.a
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
-  echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6
+  { echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6; }
   if test "$hard_links" = no; then
     { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
@@ -13842,8 +14217,8 @@
   need_locks=no
 fi
 
-echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
 
   runpath_var=
   allow_undefined_flag_F77=
@@ -13901,6 +14276,10 @@
       with_gnu_ld=no
     fi
     ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
   openbsd*)
     with_gnu_ld=no
     ;;
@@ -13982,10 +14361,10 @@
       allow_undefined_flag_F77=unsupported
       always_export_symbols_F77=no
       enable_shared_with_static_runtimes_F77=yes
-      export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+      export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
 
       if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
-        archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+        archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	# If the export-symbols file already is a .def file (1st line
 	# is EXPORTS), use it as is; otherwise, prepend...
 	archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -13994,22 +14373,37 @@
 	  echo EXPORTS > $output_objdir/$soname.def;
 	  cat $export_symbols >> $output_objdir/$soname.def;
 	fi~
-	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	ld_shlibs_F77=no
       fi
       ;;
 
-    linux*)
+    interix[3-9]*)
+      hardcode_direct_F77=no
+      hardcode_shlibpath_var_F77=no
+      hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec_F77='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | k*bsd*-gnu)
       if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
 	tmp_addflag=
 	case $cc_basename,$host_cpu in
 	pgcc*)				# Portland Group C compiler
-	  whole_archive_flag_spec_F77='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
-	pgf77* | pgf90* )			# Portland Group f77 and f90 compilers
-	  whole_archive_flag_spec_F77='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)		# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -14018,13 +14412,22 @@
 	ifc* | ifort*)			# Intel Fortran compiler
 	  tmp_addflag=' -nofor_main' ;;
 	esac
-	archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec_F77='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	*)
+	  tmp_sharedflag='-shared' ;;
+	esac
+	archive_cmds_F77='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
 	if test $supports_anon_versioning = yes; then
 	  archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~
   cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
   $echo "local: *; };" >> $output_objdir/$libname.ver~
-	  $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	  $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	fi
       else
 	ld_shlibs_F77=no
@@ -14041,7 +14444,7 @@
       fi
       ;;
 
-    solaris* | sysv5*)
+    solaris*)
       if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
 	ld_shlibs_F77=no
 	cat <<EOF 1>&2
@@ -14062,6 +14465,33 @@
       fi
       ;;
 
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs_F77=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+	    archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+	    archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+	  else
+	    ld_shlibs_F77=no
+	  fi
+	;;
+      esac
+      ;;
+
     sunos4*)
       archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
       wlarc=
@@ -14095,7 +14525,7 @@
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       hardcode_minus_L_F77=yes
-      if test "$GCC" = yes && test -z "$link_static_flag"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	hardcode_direct_F77=unsupported
@@ -14129,6 +14559,7 @@
   	    break
   	  fi
 	  done
+	  ;;
 	esac
 
 	exp_sym_flag='-bexport'
@@ -14155,7 +14586,7 @@
   	   strings "$collect2name" | grep resolve_lib_name >/dev/null
 	  then
   	  # We have reworked collect2
-  	  hardcode_direct_F77=yes
+  	  :
 	  else
   	  # We have old collect2
   	  hardcode_direct_F77=unsupported
@@ -14166,6 +14597,7 @@
   	  hardcode_libdir_flag_spec_F77='-L$libdir'
   	  hardcode_libdir_separator_F77=
 	  fi
+	  ;;
 	esac
 	shared_flag='-shared'
 	if test "$aix_use_runtimelinking" = yes; then
@@ -14178,11 +14610,11 @@
   	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-  	if test "$aix_use_runtimelinking" = yes; then
+	  if test "$aix_use_runtimelinking" = yes; then
 	    shared_flag='${wl}-G'
 	  else
 	    shared_flag='${wl}-bM:SRE'
-  	fi
+	  fi
 	fi
       fi
 
@@ -14200,49 +14632,54 @@
       end
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_f77_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_f77_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
 
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
 # Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`; fi
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
        hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
-	archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+	archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
        else
 	if test "$host_cpu" = ia64; then
 	  hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
 	  allow_undefined_flag_F77="-z nodefs"
-	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an empty executable.
 	 cat >conftest.$ac_ext <<_ACEOF
@@ -14251,39 +14688,44 @@
       end
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_f77_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_f77_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
 
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
 # Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`; fi
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -14292,13 +14734,11 @@
 	  # -berok will link without error, but may produce a broken library.
 	  no_undefined_flag_F77=' ${wl}-bernotok'
 	  allow_undefined_flag_F77=' ${wl}-berok'
-	  # -bexpall does not export symbols beginning with underscore (_)
-	  always_export_symbols_F77=yes
 	  # Exported symbols can be pulled into shared objects from archives
-	  whole_archive_flag_spec_F77=' '
+	  whole_archive_flag_spec_F77='$convenience'
 	  archive_cmds_need_lc_F77=yes
-	  # This is similar to how AIX traditionally builds it's shared libraries.
-	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -14331,13 +14771,13 @@
       # The linker will automatically build a .lib file if we build a DLL.
       old_archive_From_new_cmds_F77='true'
       # FIXME: Should let the user specify the lib program.
-      old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      old_archive_cmds_F77='lib -OUT:$oldlib$oldobjs$old_deplibs'
       fix_srcfile_path_F77='`cygpath -w "$srcfile"`'
       enable_shared_with_static_runtimes_F77=yes
       ;;
 
     darwin* | rhapsody*)
-      case "$host_os" in
+      case $host_os in
         rhapsody* | darwin1.[012])
          allow_undefined_flag_F77='${wl}-undefined ${wl}suppress'
          ;;
@@ -14366,17 +14806,17 @@
     	output_verbose_link_cmd='echo'
         archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
       module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
       archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
       module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
     else
       case $cc_basename in
         xlc*)
          output_verbose_link_cmd='echo'
-         archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
          module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
-         archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           ;;
        *)
@@ -14416,7 +14856,7 @@
       ;;
 
     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
-    freebsd* | kfreebsd*-gnu | dragonfly*)
+    freebsd* | dragonfly*)
       archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
       hardcode_libdir_flag_spec_F77='-R$libdir'
       hardcode_direct_F77=yes
@@ -14439,47 +14879,62 @@
       export_dynamic_flag_spec_F77='${wl}-E'
       ;;
 
-    hpux10* | hpux11*)
+    hpux10*)
       if test "$GCC" = yes -a "$with_gnu_ld" = no; then
-	case "$host_cpu" in
-	hppa*64*|ia64*)
+	archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_F77=:
+
+	hardcode_direct_F77=yes
+	export_dynamic_flag_spec_F77='${wl}-E'
+
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L_F77=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
 	  archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
+	ia64*)
+	  archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
 	*)
 	  archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
-	case "$host_cpu" in
-	hppa*64*|ia64*)
-	  archive_cmds_F77='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
+	ia64*)
+	  archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
 	*)
-	  archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+	  archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       fi
       if test "$with_gnu_ld" = no; then
-	case "$host_cpu" in
-	hppa*64*)
-	  hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_F77=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
 	  hardcode_libdir_flag_spec_ld_F77='+b $libdir'
-	  hardcode_libdir_separator_F77=:
 	  hardcode_direct_F77=no
 	  hardcode_shlibpath_var_F77=no
 	  ;;
-	ia64*)
-	  hardcode_libdir_flag_spec_F77='-L$libdir'
-	  hardcode_direct_F77=no
-	  hardcode_shlibpath_var_F77=no
-
-	  # hardcode_minus_L: Not really in the search PATH,
-	  # but as the default location of the library.
-	  hardcode_minus_L_F77=yes
-	  ;;
 	*)
-	  hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
-	  hardcode_libdir_separator_F77=:
 	  hardcode_direct_F77=yes
 	  export_dynamic_flag_spec_F77='${wl}-E'
 
@@ -14523,24 +14978,28 @@
       ;;
 
     openbsd*)
-      hardcode_direct_F77=yes
-      hardcode_shlibpath_var_F77=no
-      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-	archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
-	hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
-	export_dynamic_flag_spec_F77='${wl}-E'
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct_F77=yes
+	hardcode_shlibpath_var_F77=no
+	if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec_F77='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec_F77='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+        fi
       else
-       case $host_os in
-	 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
-	   archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-	   hardcode_libdir_flag_spec_F77='-R$libdir'
-	   ;;
-	 *)
-	   archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	   hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
-	   ;;
-       esac
+	ld_shlibs_F77=no
       fi
       ;;
 
@@ -14581,14 +15040,6 @@
       hardcode_libdir_separator_F77=:
       ;;
 
-    sco3.2v5*)
-      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      hardcode_shlibpath_var_F77=no
-      export_dynamic_flag_spec_F77='${wl}-Bexport'
-      runpath_var=LD_RUN_PATH
-      hardcode_runpath_var=yes
-      ;;
-
     solaris*)
       no_undefined_flag_F77=' -z text'
       if test "$GCC" = yes; then
@@ -14607,17 +15058,16 @@
       case $host_os in
       solaris2.[0-5] | solaris2.[0-5].*) ;;
       *)
- 	# The compiler driver will combine linker options so we
- 	# cannot just pass the convience library names through
- 	# without $wl, iff we do not link with $LD.
- 	# Luckily, gcc supports the same syntax we need for Sun Studio.
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
  	# Supported since Solaris 2.6 (maybe 2.5.1?)
- 	case $wlarc in
- 	'')
- 	  whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;;
- 	*)
- 	  whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
- 	esac ;;
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec_F77='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract'
+	fi
+	;;
       esac
       link_all_deplibs_F77=yes
       ;;
@@ -14674,36 +15124,45 @@
       fi
       ;;
 
-    sysv4.2uw2*)
-      archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
-      hardcode_direct_F77=yes
-      hardcode_minus_L_F77=no
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_F77='${wl}-z,text'
+      archive_cmds_need_lc_F77=no
       hardcode_shlibpath_var_F77=no
-      hardcode_runpath_var=yes
-      runpath_var=LD_RUN_PATH
-      ;;
+      runpath_var='LD_RUN_PATH'
 
-   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[78]* | unixware7*)
-      no_undefined_flag_F77='${wl}-z ${wl}text'
       if test "$GCC" = yes; then
-	archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	archive_cmds_F77='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
-      runpath_var='LD_RUN_PATH'
-      hardcode_shlibpath_var_F77=no
       ;;
 
-    sysv5*)
-      no_undefined_flag_F77=' -z text'
-      # $CC -shared without GNU ld will not create a library from C++
-      # object files and a static libstdc++, better avoid it by now
-      archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-  		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
-      hardcode_libdir_flag_spec_F77=
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag_F77='${wl}-z,text'
+      allow_undefined_flag_F77='${wl}-z,nodefs'
+      archive_cmds_need_lc_F77=no
       hardcode_shlibpath_var_F77=no
+      hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator_F77=':'
+      link_all_deplibs_F77=yes
+      export_dynamic_flag_spec_F77='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
       ;;
 
     uts4*)
@@ -14718,15 +15177,10 @@
     esac
   fi
 
-echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5
-echo "${ECHO_T}$ld_shlibs_F77" >&6
+{ echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5
+echo "${ECHO_T}$ld_shlibs_F77" >&6; }
 test "$ld_shlibs_F77" = no && can_build_shared=no
 
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
-  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
 #
 # Do we need to explicitly link libc?
 #
@@ -14744,10 +15198,10 @@
       # Test whether the compiler implicitly links with -lc since on some
       # systems, -lgcc has to come before -lc. If gcc already passes -lc
       # to ld, don't add -lc before -lgcc.
-      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
       $rm conftest*
-      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
       if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
@@ -14759,6 +15213,7 @@
         libobjs=conftest.$ac_objext
         deplibs=
         wl=$lt_prog_compiler_wl_F77
+	pic_flag=$lt_prog_compiler_pic_F77
         compiler_flags=-v
         linker_flags=-v
         verstring=
@@ -14781,16 +15236,16 @@
         cat conftest.err 1>&5
       fi
       $rm conftest*
-      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5
-echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6
+      { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6; }
       ;;
     esac
   fi
   ;;
 esac
 
-echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
@@ -14804,20 +15259,7 @@
 version_type=none
 dynamic_linker="$host_os ld.so"
 sys_lib_dlsearch_path_spec="/lib /usr/lib"
-if test "$GCC" = yes; then
-  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
-    # if the path contains ";" then we assume it to be the separator
-    # otherwise default to the standard path separator (i.e. ":") - it is
-    # assumed that no part of a normal pathname contains ";" but that should
-    # okay in the real world where ";" in dirpaths is itself problematic.
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
-  else
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
-  fi
-else
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
+
 need_lib_prefix=unknown
 hardcode_into_libs=no
 
@@ -14919,7 +15361,8 @@
       dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
-      $install_prog $dir/$dlname \$dldir/$dlname'
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
     postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
       dlpath=$dir/\$dldll~
        $rm \$dlpath'
@@ -14972,13 +15415,8 @@
   soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
-  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
-  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
-  if test "$GCC" = yes; then
-    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
-  else
-    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
-  fi
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
   sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
   ;;
 
@@ -14995,22 +15433,17 @@
   dynamic_linker=no
   ;;
 
-kfreebsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
-  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
@@ -15032,10 +15465,15 @@
     shlibpath_overrides_runpath=yes
     hardcode_into_libs=yes
     ;;
-  *) # from 3.2 on
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
     shlibpath_overrides_runpath=no
     hardcode_into_libs=yes
     ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
   esac
   ;;
 
@@ -15055,7 +15493,7 @@
   version_type=sunos
   need_lib_prefix=no
   need_version=no
-  case "$host_cpu" in
+  case $host_cpu in
   ia64*)
     shrext_cmds='.so'
     hardcode_into_libs=yes
@@ -15095,6 +15533,18 @@
   postinstall_cmds='chmod 555 $lib'
   ;;
 
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
 irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
@@ -15138,7 +15588,7 @@
   ;;
 
 # This must be Linux ELF.
-linux*)
+linux* | k*bsd*-gnu)
   version_type=linux
   need_lib_prefix=no
   need_version=no
@@ -15154,7 +15604,7 @@
 
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ 	]*hwcap[ 	]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
   fi
 
@@ -15167,18 +15617,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-knetbsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -15216,6 +15654,7 @@
 
 openbsd*)
   version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
   # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
   case $host_os in
@@ -15259,11 +15698,8 @@
   sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
-sco3.2v5*)
-  version_type=osf
-  soname_spec='${libname}${release}${shared_ext}$major'
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  shlibpath_var=LD_LIBRARY_PATH
+rdos*)
+  dynamic_linker=no
   ;;
 
 solaris*)
@@ -15291,7 +15727,7 @@
   need_version=yes
   ;;
 
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
@@ -15324,6 +15760,29 @@
   fi
   ;;
 
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
 uts4*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -15335,12 +15794,17 @@
   dynamic_linker=no
   ;;
 esac
-echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6
+{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6; }
 test "$dynamic_linker" = no && can_build_shared=no
 
-echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
 hardcode_action_F77=
 if test -n "$hardcode_libdir_flag_spec_F77" || \
    test -n "$runpath_var_F77" || \
@@ -15364,8 +15828,8 @@
   # directories.
   hardcode_action_F77=unsupported
 fi
-echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
-echo "${ECHO_T}$hardcode_action_F77" >&6
+{ echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
+echo "${ECHO_T}$hardcode_action_F77" >&6; }
 
 if test "$hardcode_action_F77" = relink; then
   # Fast installation is not supported
@@ -15376,37 +15840,7 @@
   enable_fast_install=needless
 fi
 
-striplib=
-old_striplib=
-echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
-  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
-  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-else
-# FIXME - insert some real tests, host_os isn't really good enough
-  case $host_os in
-   darwin*)
-       if test -n "$STRIP" ; then
-         striplib="$STRIP -x"
-         echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-       else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-       ;;
-   *)
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-    ;;
-  esac
-fi
 
-
-
 # The else clause should only fire when bootstrapping the
 # libtool distribution, otherwise you forgot to ship ltmain.sh
 # with your package, and you will get complaints that there are
@@ -15420,7 +15854,7 @@
   # Now quote all the things that may contain metacharacters while being
   # careful not to overquote the AC_SUBSTed values.  We take copies of the
   # variables and quote the copies for generation of the libtool script.
-  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
     SED SHELL STRIP \
     libname_spec library_names_spec soname_spec extract_expsyms_cmds \
     old_striplib striplib file_magic_cmd finish_cmds finish_eval \
@@ -15462,6 +15896,7 @@
     module_cmds_F77 \
     module_expsym_cmds_F77 \
     lt_cv_prog_compiler_c_o_F77 \
+    fix_srcfile_path_F77 \
     exclude_expsyms_F77 \
     include_expsyms_F77; do
 
@@ -15538,6 +15973,9 @@
 # A C compiler.
 LTCC=$lt_LTCC
 
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
 # A language-specific compiler.
 CC=$lt_compiler_F77
 
@@ -15779,7 +16217,7 @@
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
 
 # Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path_F77"
+fix_srcfile_path=$lt_fix_srcfile_path
 
 # Set to yes if exported symbols are required.
 always_export_symbols=$always_export_symbols_F77
@@ -15829,7 +16267,6 @@
 	if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
 
 
-
 # Source file extension for Java test sources.
 ac_ext=java
 
@@ -15838,30 +16275,33 @@
 objext_GCJ=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code="class foo {}\n"
+lt_simple_compile_test_code="class foo {}"
 
 # Code to be used in simple link tests
-lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
+lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }'
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 
 # If no C compiler was specified, use CC.
 LTCC=${LTCC-"$CC"}
 
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
 # Allow CC to be a program name with arguments.
 compiler=$CC
 
 
 # save warnings/boilerplate of simple test code
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_compiler_boilerplate=`cat conftest.err`
 $rm conftest*
 
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_linker_boilerplate=`cat conftest.err`
 $rm conftest*
 
@@ -15894,14 +16334,14 @@
   lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin'
 
 
-echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; }
 if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   lt_cv_prog_compiler_rtti_exceptions=no
   ac_outfile=conftest.$ac_objext
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
    lt_compiler_flag="-fno-rtti -fno-exceptions"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
@@ -15909,28 +16349,28 @@
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    # The option is referenced via a variable to avoid confusing sed.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15915: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16355: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15919: \$? = $ac_status" >&5
+   echo "$as_me:16359: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp
-     $SED '/^$/d' conftest.err >conftest.er2
-     if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_rtti_exceptions=yes
      fi
    fi
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; }
 
 if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
     lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions"
@@ -15944,8 +16384,8 @@
 lt_prog_compiler_pic_GCJ=
 lt_prog_compiler_static_GCJ=
 
-echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
 
   if test "$GCC" = yes; then
     lt_prog_compiler_wl_GCJ='-Wl,'
@@ -15967,13 +16407,15 @@
       lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4'
       ;;
 
-    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
       # PIC is the default for these OSes.
       ;;
 
-    mingw* | pw32* | os2*)
+    mingw* | cygwin* | pw32* | os2*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
       lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
       ;;
 
@@ -15983,6 +16425,11 @@
       lt_prog_compiler_pic_GCJ='-fno-common'
       ;;
 
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
     msdosdjgpp*)
       # Just because we use GCC doesn't mean we suddenly get shared libraries
       # on systems that don't support them.
@@ -15999,7 +16446,7 @@
     hpux*)
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	# +Z the default
 	;;
@@ -16036,7 +16483,7 @@
        esac
        ;;
 
-    mingw* | pw32* | os2*)
+    mingw* | cygwin* | pw32* | os2*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
@@ -16046,7 +16493,7 @@
       lt_prog_compiler_wl_GCJ='-Wl,'
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
 	# +Z the default
 	;;
@@ -16069,25 +16516,41 @@
       lt_prog_compiler_static_GCJ='-Bstatic'
       ;;
 
-    linux*)
+    linux* | k*bsd*-gnu)
       case $cc_basename in
       icc* | ecc*)
 	lt_prog_compiler_wl_GCJ='-Wl,'
 	lt_prog_compiler_pic_GCJ='-KPIC'
 	lt_prog_compiler_static_GCJ='-static'
         ;;
-      pgcc* | pgf77* | pgf90*)
+      pgcc* | pgf77* | pgf90* | pgf95*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
 	lt_prog_compiler_wl_GCJ='-Wl,'
 	lt_prog_compiler_pic_GCJ='-fpic'
-	lt_prog_compiler_static_GCJ='-static'
+	lt_prog_compiler_static_GCJ='-Bstatic'
         ;;
       ccc*)
         lt_prog_compiler_wl_GCJ='-Wl,'
         # All Alpha code is PIC.
         lt_prog_compiler_static_GCJ='-non_shared'
         ;;
+      *)
+        case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic_GCJ='-KPIC'
+	  lt_prog_compiler_static_GCJ='-Bstatic'
+	  lt_prog_compiler_wl_GCJ='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic_GCJ='-KPIC'
+	  lt_prog_compiler_static_GCJ='-Bstatic'
+	  lt_prog_compiler_wl_GCJ=''
+	  ;;
+	esac
+	;;
       esac
       ;;
 
@@ -16097,9 +16560,8 @@
       lt_prog_compiler_static_GCJ='-non_shared'
       ;;
 
-    sco3.2v5*)
-      lt_prog_compiler_pic_GCJ='-Kpic'
-      lt_prog_compiler_static_GCJ='-dn'
+    rdos*)
+      lt_prog_compiler_static_GCJ='-non_shared'
       ;;
 
     solaris*)
@@ -16119,7 +16581,7 @@
       lt_prog_compiler_static_GCJ='-Bstatic'
       ;;
 
-    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    sysv4 | sysv4.2uw2* | sysv4.3*)
       lt_prog_compiler_wl_GCJ='-Wl,'
       lt_prog_compiler_pic_GCJ='-KPIC'
       lt_prog_compiler_static_GCJ='-Bstatic'
@@ -16132,6 +16594,12 @@
       fi
       ;;
 
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
     unicos*)
       lt_prog_compiler_wl_GCJ='-Wl,'
       lt_prog_compiler_can_build_shared_GCJ=no
@@ -16148,22 +16616,22 @@
     esac
   fi
 
-echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6; }
 
 #
 # Check to make sure the PIC flag actually works.
 #
 if test -n "$lt_prog_compiler_pic_GCJ"; then
 
-echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6; }
 if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   lt_prog_compiler_pic_works_GCJ=no
   ac_outfile=conftest.$ac_objext
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
    lt_compiler_flag="$lt_prog_compiler_pic_GCJ"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
@@ -16171,28 +16639,28 @@
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    # The option is referenced via a variable to avoid confusing sed.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16177: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16645: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:16181: \$? = $ac_status" >&5
+   echo "$as_me:16649: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp
-     $SED '/^$/d' conftest.err >conftest.er2
-     if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        lt_prog_compiler_pic_works_GCJ=yes
      fi
    fi
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6; }
 
 if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then
     case $lt_prog_compiler_pic_GCJ in
@@ -16205,7 +16673,7 @@
 fi
 
 fi
-case "$host_os" in
+case $host_os in
   # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic_GCJ=
@@ -16215,8 +16683,50 @@
     ;;
 esac
 
-echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\"
+{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works_GCJ=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works_GCJ=yes
+       fi
+     else
+       lt_prog_compiler_static_works_GCJ=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6; }
+
+if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then
+    :
+else
+    lt_prog_compiler_static_GCJ=
+fi
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
 if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -16225,7 +16735,7 @@
    mkdir conftest
    cd conftest
    mkdir out
-   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
    lt_compiler_flag="-o out/conftest2.$ac_objext"
    # Insert the option either (1) after the last *FLAGS variable, or
@@ -16233,25 +16743,25 @@
    # Note that $ac_compile itself does not contain backslashes and begins
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16239: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16749: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:16243: \$? = $ac_status" >&5
+   echo "$as_me:16753: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
-     $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp
-     $SED '/^$/d' out/conftest.err >out/conftest.er2
-     if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_c_o_GCJ=yes
      fi
    fi
-   chmod u+w .
+   chmod u+w . 2>&5
    $rm conftest*
    # SGI C++ compiler will create directory out/ii_files/ for
    # template instantiation
@@ -16262,23 +16772,23 @@
    $rm conftest*
 
 fi
-echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6; }
 
 
 hard_links="nottested"
 if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
-  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
   hard_links=yes
   $rm conftest*
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   touch conftest.a
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
-  echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6
+  { echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6; }
   if test "$hard_links" = no; then
     { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
@@ -16288,8 +16798,8 @@
   need_locks=no
 fi
 
-echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
 
   runpath_var=
   allow_undefined_flag_GCJ=
@@ -16347,6 +16857,10 @@
       with_gnu_ld=no
     fi
     ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
   openbsd*)
     with_gnu_ld=no
     ;;
@@ -16428,10 +16942,10 @@
       allow_undefined_flag_GCJ=unsupported
       always_export_symbols_GCJ=no
       enable_shared_with_static_runtimes_GCJ=yes
-      export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+      export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
 
       if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
-        archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+        archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	# If the export-symbols file already is a .def file (1st line
 	# is EXPORTS), use it as is; otherwise, prepend...
 	archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -16440,22 +16954,37 @@
 	  echo EXPORTS > $output_objdir/$soname.def;
 	  cat $export_symbols >> $output_objdir/$soname.def;
 	fi~
-	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	ld_shlibs_GCJ=no
       fi
       ;;
 
-    linux*)
+    interix[3-9]*)
+      hardcode_direct_GCJ=no
+      hardcode_shlibpath_var_GCJ=no
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec_GCJ='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | k*bsd*-gnu)
       if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
 	tmp_addflag=
 	case $cc_basename,$host_cpu in
 	pgcc*)				# Portland Group C compiler
-	  whole_archive_flag_spec_GCJ='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
-	pgf77* | pgf90* )			# Portland Group f77 and f90 compilers
-	  whole_archive_flag_spec_GCJ='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)		# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -16464,13 +16993,22 @@
 	ifc* | ifort*)			# Intel Fortran compiler
 	  tmp_addflag=' -nofor_main' ;;
 	esac
-	archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec_GCJ='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	*)
+	  tmp_sharedflag='-shared' ;;
+	esac
+	archive_cmds_GCJ='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
 	if test $supports_anon_versioning = yes; then
 	  archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~
   cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
   $echo "local: *; };" >> $output_objdir/$libname.ver~
-	  $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	  $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	fi
       else
 	ld_shlibs_GCJ=no
@@ -16487,7 +17025,7 @@
       fi
       ;;
 
-    solaris* | sysv5*)
+    solaris*)
       if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
 	ld_shlibs_GCJ=no
 	cat <<EOF 1>&2
@@ -16508,6 +17046,33 @@
       fi
       ;;
 
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs_GCJ=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+	    archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+	    archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+	  else
+	    ld_shlibs_GCJ=no
+	  fi
+	;;
+      esac
+      ;;
+
     sunos4*)
       archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
       wlarc=
@@ -16541,7 +17106,7 @@
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       hardcode_minus_L_GCJ=yes
-      if test "$GCC" = yes && test -z "$link_static_flag"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	hardcode_direct_GCJ=unsupported
@@ -16575,6 +17140,7 @@
   	    break
   	  fi
 	  done
+	  ;;
 	esac
 
 	exp_sym_flag='-bexport'
@@ -16601,7 +17167,7 @@
   	   strings "$collect2name" | grep resolve_lib_name >/dev/null
 	  then
   	  # We have reworked collect2
-  	  hardcode_direct_GCJ=yes
+  	  :
 	  else
   	  # We have old collect2
   	  hardcode_direct_GCJ=unsupported
@@ -16612,6 +17178,7 @@
   	  hardcode_libdir_flag_spec_GCJ='-L$libdir'
   	  hardcode_libdir_separator_GCJ=
 	  fi
+	  ;;
 	esac
 	shared_flag='-shared'
 	if test "$aix_use_runtimelinking" = yes; then
@@ -16624,11 +17191,11 @@
   	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-  	if test "$aix_use_runtimelinking" = yes; then
+	  if test "$aix_use_runtimelinking" = yes; then
 	    shared_flag='${wl}-G'
 	  else
 	    shared_flag='${wl}-bM:SRE'
-  	fi
+	  fi
 	fi
       fi
 
@@ -16656,49 +17223,54 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
 
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
 # Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`; fi
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
        hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
-	archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+	archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
        else
 	if test "$host_cpu" = ia64; then
 	  hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib'
 	  allow_undefined_flag_GCJ="-z nodefs"
-	  archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	  archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an empty executable.
 	 cat >conftest.$ac_ext <<_ACEOF
@@ -16717,39 +17289,44 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
 
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
 # Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`; fi
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -16758,13 +17335,11 @@
 	  # -berok will link without error, but may produce a broken library.
 	  no_undefined_flag_GCJ=' ${wl}-bernotok'
 	  allow_undefined_flag_GCJ=' ${wl}-berok'
-	  # -bexpall does not export symbols beginning with underscore (_)
-	  always_export_symbols_GCJ=yes
 	  # Exported symbols can be pulled into shared objects from archives
-	  whole_archive_flag_spec_GCJ=' '
+	  whole_archive_flag_spec_GCJ='$convenience'
 	  archive_cmds_need_lc_GCJ=yes
-	  # This is similar to how AIX traditionally builds it's shared libraries.
-	  archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -16797,13 +17372,13 @@
       # The linker will automatically build a .lib file if we build a DLL.
       old_archive_From_new_cmds_GCJ='true'
       # FIXME: Should let the user specify the lib program.
-      old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      old_archive_cmds_GCJ='lib -OUT:$oldlib$oldobjs$old_deplibs'
       fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`'
       enable_shared_with_static_runtimes_GCJ=yes
       ;;
 
     darwin* | rhapsody*)
-      case "$host_os" in
+      case $host_os in
         rhapsody* | darwin1.[012])
          allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress'
          ;;
@@ -16832,17 +17407,17 @@
     	output_verbose_link_cmd='echo'
         archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
       module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
       archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
       module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
     else
       case $cc_basename in
         xlc*)
          output_verbose_link_cmd='echo'
-         archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
          module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
-         archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           ;;
        *)
@@ -16882,7 +17457,7 @@
       ;;
 
     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
-    freebsd* | kfreebsd*-gnu | dragonfly*)
+    freebsd* | dragonfly*)
       archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
       hardcode_libdir_flag_spec_GCJ='-R$libdir'
       hardcode_direct_GCJ=yes
@@ -16905,47 +17480,62 @@
       export_dynamic_flag_spec_GCJ='${wl}-E'
       ;;
 
-    hpux10* | hpux11*)
+    hpux10*)
       if test "$GCC" = yes -a "$with_gnu_ld" = no; then
-	case "$host_cpu" in
-	hppa*64*|ia64*)
+	archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_GCJ=:
+
+	hardcode_direct_GCJ=yes
+	export_dynamic_flag_spec_GCJ='${wl}-E'
+
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L_GCJ=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
 	  archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
+	ia64*)
+	  archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
 	*)
 	  archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
-	case "$host_cpu" in
-	hppa*64*|ia64*)
-	  archive_cmds_GCJ='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
+	ia64*)
+	  archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
 	*)
-	  archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+	  archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       fi
       if test "$with_gnu_ld" = no; then
-	case "$host_cpu" in
-	hppa*64*)
-	  hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_GCJ=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
 	  hardcode_libdir_flag_spec_ld_GCJ='+b $libdir'
-	  hardcode_libdir_separator_GCJ=:
 	  hardcode_direct_GCJ=no
 	  hardcode_shlibpath_var_GCJ=no
 	  ;;
-	ia64*)
-	  hardcode_libdir_flag_spec_GCJ='-L$libdir'
-	  hardcode_direct_GCJ=no
-	  hardcode_shlibpath_var_GCJ=no
-
-	  # hardcode_minus_L: Not really in the search PATH,
-	  # but as the default location of the library.
-	  hardcode_minus_L_GCJ=yes
-	  ;;
 	*)
-	  hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
-	  hardcode_libdir_separator_GCJ=:
 	  hardcode_direct_GCJ=yes
 	  export_dynamic_flag_spec_GCJ='${wl}-E'
 
@@ -16989,24 +17579,28 @@
       ;;
 
     openbsd*)
-      hardcode_direct_GCJ=yes
-      hardcode_shlibpath_var_GCJ=no
-      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-	archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
-	hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
-	export_dynamic_flag_spec_GCJ='${wl}-E'
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct_GCJ=yes
+	hardcode_shlibpath_var_GCJ=no
+	if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec_GCJ='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec_GCJ='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+        fi
       else
-       case $host_os in
-	 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
-	   archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-	   hardcode_libdir_flag_spec_GCJ='-R$libdir'
-	   ;;
-	 *)
-	   archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	   hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
-	   ;;
-       esac
+	ld_shlibs_GCJ=no
       fi
       ;;
 
@@ -17047,14 +17641,6 @@
       hardcode_libdir_separator_GCJ=:
       ;;
 
-    sco3.2v5*)
-      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      hardcode_shlibpath_var_GCJ=no
-      export_dynamic_flag_spec_GCJ='${wl}-Bexport'
-      runpath_var=LD_RUN_PATH
-      hardcode_runpath_var=yes
-      ;;
-
     solaris*)
       no_undefined_flag_GCJ=' -z text'
       if test "$GCC" = yes; then
@@ -17073,17 +17659,16 @@
       case $host_os in
       solaris2.[0-5] | solaris2.[0-5].*) ;;
       *)
- 	# The compiler driver will combine linker options so we
- 	# cannot just pass the convience library names through
- 	# without $wl, iff we do not link with $LD.
- 	# Luckily, gcc supports the same syntax we need for Sun Studio.
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
  	# Supported since Solaris 2.6 (maybe 2.5.1?)
- 	case $wlarc in
- 	'')
- 	  whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;;
- 	*)
- 	  whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
- 	esac ;;
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract'
+	fi
+	;;
       esac
       link_all_deplibs_GCJ=yes
       ;;
@@ -17140,36 +17725,45 @@
       fi
       ;;
 
-    sysv4.2uw2*)
-      archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
-      hardcode_direct_GCJ=yes
-      hardcode_minus_L_GCJ=no
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_GCJ='${wl}-z,text'
+      archive_cmds_need_lc_GCJ=no
       hardcode_shlibpath_var_GCJ=no
-      hardcode_runpath_var=yes
-      runpath_var=LD_RUN_PATH
-      ;;
+      runpath_var='LD_RUN_PATH'
 
-   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[78]* | unixware7*)
-      no_undefined_flag_GCJ='${wl}-z ${wl}text'
       if test "$GCC" = yes; then
-	archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	archive_cmds_GCJ='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
-      runpath_var='LD_RUN_PATH'
-      hardcode_shlibpath_var_GCJ=no
       ;;
 
-    sysv5*)
-      no_undefined_flag_GCJ=' -z text'
-      # $CC -shared without GNU ld will not create a library from C++
-      # object files and a static libstdc++, better avoid it by now
-      archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-  		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
-      hardcode_libdir_flag_spec_GCJ=
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag_GCJ='${wl}-z,text'
+      allow_undefined_flag_GCJ='${wl}-z,nodefs'
+      archive_cmds_need_lc_GCJ=no
       hardcode_shlibpath_var_GCJ=no
+      hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator_GCJ=':'
+      link_all_deplibs_GCJ=yes
+      export_dynamic_flag_spec_GCJ='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
       ;;
 
     uts4*)
@@ -17184,15 +17778,10 @@
     esac
   fi
 
-echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5
-echo "${ECHO_T}$ld_shlibs_GCJ" >&6
+{ echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5
+echo "${ECHO_T}$ld_shlibs_GCJ" >&6; }
 test "$ld_shlibs_GCJ" = no && can_build_shared=no
 
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
-  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
 #
 # Do we need to explicitly link libc?
 #
@@ -17210,10 +17799,10 @@
       # Test whether the compiler implicitly links with -lc since on some
       # systems, -lgcc has to come before -lc. If gcc already passes -lc
       # to ld, don't add -lc before -lgcc.
-      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
       $rm conftest*
-      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
       if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
@@ -17225,6 +17814,7 @@
         libobjs=conftest.$ac_objext
         deplibs=
         wl=$lt_prog_compiler_wl_GCJ
+	pic_flag=$lt_prog_compiler_pic_GCJ
         compiler_flags=-v
         linker_flags=-v
         verstring=
@@ -17247,16 +17837,16 @@
         cat conftest.err 1>&5
       fi
       $rm conftest*
-      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5
-echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6
+      { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6; }
       ;;
     esac
   fi
   ;;
 esac
 
-echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
@@ -17270,20 +17860,7 @@
 version_type=none
 dynamic_linker="$host_os ld.so"
 sys_lib_dlsearch_path_spec="/lib /usr/lib"
-if test "$GCC" = yes; then
-  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
-    # if the path contains ";" then we assume it to be the separator
-    # otherwise default to the standard path separator (i.e. ":") - it is
-    # assumed that no part of a normal pathname contains ";" but that should
-    # okay in the real world where ";" in dirpaths is itself problematic.
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
-  else
-    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
-  fi
-else
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
+
 need_lib_prefix=unknown
 hardcode_into_libs=no
 
@@ -17385,7 +17962,8 @@
       dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
-      $install_prog $dir/$dlname \$dldir/$dlname'
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
     postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
       dlpath=$dir/\$dldll~
        $rm \$dlpath'
@@ -17438,13 +18016,8 @@
   soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
-  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
-  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
-  if test "$GCC" = yes; then
-    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
-  else
-    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
-  fi
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
   sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
   ;;
 
@@ -17461,22 +18034,17 @@
   dynamic_linker=no
   ;;
 
-kfreebsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
-  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
@@ -17498,10 +18066,15 @@
     shlibpath_overrides_runpath=yes
     hardcode_into_libs=yes
     ;;
-  *) # from 3.2 on
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
     shlibpath_overrides_runpath=no
     hardcode_into_libs=yes
     ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
   esac
   ;;
 
@@ -17521,7 +18094,7 @@
   version_type=sunos
   need_lib_prefix=no
   need_version=no
-  case "$host_cpu" in
+  case $host_cpu in
   ia64*)
     shrext_cmds='.so'
     hardcode_into_libs=yes
@@ -17561,6 +18134,18 @@
   postinstall_cmds='chmod 555 $lib'
   ;;
 
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
 irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
@@ -17604,7 +18189,7 @@
   ;;
 
 # This must be Linux ELF.
-linux*)
+linux* | k*bsd*-gnu)
   version_type=linux
   need_lib_prefix=no
   need_version=no
@@ -17620,7 +18205,7 @@
 
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ 	]*hwcap[ 	]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
   fi
 
@@ -17633,18 +18218,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-knetbsd*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='GNU ld.so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -17682,6 +18255,7 @@
 
 openbsd*)
   version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
   # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
   case $host_os in
@@ -17725,11 +18299,8 @@
   sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
-sco3.2v5*)
-  version_type=osf
-  soname_spec='${libname}${release}${shared_ext}$major'
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  shlibpath_var=LD_LIBRARY_PATH
+rdos*)
+  dynamic_linker=no
   ;;
 
 solaris*)
@@ -17757,7 +18328,7 @@
   need_version=yes
   ;;
 
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
@@ -17790,6 +18361,29 @@
   fi
   ;;
 
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
 uts4*)
   version_type=linux
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -17801,12 +18395,17 @@
   dynamic_linker=no
   ;;
 esac
-echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6
+{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6; }
 test "$dynamic_linker" = no && can_build_shared=no
 
-echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
 hardcode_action_GCJ=
 if test -n "$hardcode_libdir_flag_spec_GCJ" || \
    test -n "$runpath_var_GCJ" || \
@@ -17830,8 +18429,8 @@
   # directories.
   hardcode_action_GCJ=unsupported
 fi
-echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
-echo "${ECHO_T}$hardcode_action_GCJ" >&6
+{ echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
+echo "${ECHO_T}$hardcode_action_GCJ" >&6; }
 
 if test "$hardcode_action_GCJ" = relink; then
   # Fast installation is not supported
@@ -17842,842 +18441,7 @@
   enable_fast_install=needless
 fi
 
-striplib=
-old_striplib=
-echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
-  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
-  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-else
-# FIXME - insert some real tests, host_os isn't really good enough
-  case $host_os in
-   darwin*)
-       if test -n "$STRIP" ; then
-         striplib="$STRIP -x"
-         echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-       else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-       ;;
-   *)
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-    ;;
-  esac
-fi
 
-if test "x$enable_dlopen" != xyes; then
-  enable_dlopen=unknown
-  enable_dlopen_self=unknown
-  enable_dlopen_self_static=unknown
-else
-  lt_cv_dlopen=no
-  lt_cv_dlopen_libs=
-
-  case $host_os in
-  beos*)
-    lt_cv_dlopen="load_add_on"
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=yes
-    ;;
-
-  mingw* | pw32*)
-    lt_cv_dlopen="LoadLibrary"
-    lt_cv_dlopen_libs=
-   ;;
-
-  cygwin*)
-    lt_cv_dlopen="dlopen"
-    lt_cv_dlopen_libs=
-   ;;
-
-  darwin*)
-  # if libdl is installed we need to link against it
-    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_dl_dlopen=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dl_dlopen=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
-if test $ac_cv_lib_dl_dlopen = yes; then
-  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-
-    lt_cv_dlopen="dyld"
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=yes
-
-fi
-
-   ;;
-
-  *)
-    echo "$as_me:$LINENO: checking for shl_load" >&5
-echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
-if test "${ac_cv_func_shl_load+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define shl_load innocuous_shl_load
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char shl_load (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef shl_load
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char shl_load ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_shl_load) || defined (__stub___shl_load)
-choke me
-#else
-char (*f) () = shl_load;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != shl_load;
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_shl_load=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_shl_load=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
-echo "${ECHO_T}$ac_cv_func_shl_load" >&6
-if test $ac_cv_func_shl_load = yes; then
-  lt_cv_dlopen="shl_load"
-else
-  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
-echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char shl_load ();
-int
-main ()
-{
-shl_load ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_dld_shl_load=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_shl_load=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
-if test $ac_cv_lib_dld_shl_load = yes; then
-  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
-else
-  echo "$as_me:$LINENO: checking for dlopen" >&5
-echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
-if test "${ac_cv_func_dlopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define dlopen innocuous_dlopen
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char dlopen (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef dlopen
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_dlopen) || defined (__stub___dlopen)
-choke me
-#else
-char (*f) () = dlopen;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != dlopen;
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_dlopen=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_dlopen=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
-echo "${ECHO_T}$ac_cv_func_dlopen" >&6
-if test $ac_cv_func_dlopen = yes; then
-  lt_cv_dlopen="dlopen"
-else
-  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_dl_dlopen=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dl_dlopen=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
-if test $ac_cv_lib_dl_dlopen = yes; then
-  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
-echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsvld  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_svld_dlopen=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_svld_dlopen=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
-if test $ac_cv_lib_svld_dlopen = yes; then
-  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
-else
-  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
-echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char dld_link ();
-int
-main ()
-{
-dld_link ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_dld_dld_link=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_dld_link=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
-if test $ac_cv_lib_dld_dld_link = yes; then
-  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-    ;;
-  esac
-
-  if test "x$lt_cv_dlopen" != xno; then
-    enable_dlopen=yes
-  else
-    enable_dlopen=no
-  fi
-
-  case $lt_cv_dlopen in
-  dlopen)
-    save_CPPFLAGS="$CPPFLAGS"
-    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
-    save_LDFLAGS="$LDFLAGS"
-    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
-    save_LIBS="$LIBS"
-    LIBS="$lt_cv_dlopen_libs $LIBS"
-
-    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
-echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
-if test "${lt_cv_dlopen_self+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  	  if test "$cross_compiling" = yes; then :
-  lt_cv_dlopen_self=cross
-else
-  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
-  lt_status=$lt_dlunknown
-  cat > conftest.$ac_ext <<EOF
-#line 18479 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-#  define LT_DLGLOBAL		RTLD_GLOBAL
-#else
-#  ifdef DL_GLOBAL
-#    define LT_DLGLOBAL		DL_GLOBAL
-#  else
-#    define LT_DLGLOBAL		0
-#  endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
-   find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-#  ifdef RTLD_LAZY
-#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
-#  else
-#    ifdef DL_LAZY
-#      define LT_DLLAZY_OR_NOW		DL_LAZY
-#    else
-#      ifdef RTLD_NOW
-#        define LT_DLLAZY_OR_NOW	RTLD_NOW
-#      else
-#        ifdef DL_NOW
-#          define LT_DLLAZY_OR_NOW	DL_NOW
-#        else
-#          define LT_DLLAZY_OR_NOW	0
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
-  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
-  int status = $lt_dlunknown;
-
-  if (self)
-    {
-      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
-      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
-      /* dlclose (self); */
-    }
-
-    exit (status);
-}
-EOF
-  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
-    (./conftest; exit; ) 2>/dev/null
-    lt_status=$?
-    case x$lt_status in
-      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
-      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
-      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
-    esac
-  else :
-    # compilation failed
-    lt_cv_dlopen_self=no
-  fi
-fi
-rm -fr conftest*
-
-
-fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self" >&6
-
-    if test "x$lt_cv_dlopen_self" = xyes; then
-      LDFLAGS="$LDFLAGS $link_static_flag"
-      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
-echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
-if test "${lt_cv_dlopen_self_static+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  	  if test "$cross_compiling" = yes; then :
-  lt_cv_dlopen_self_static=cross
-else
-  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
-  lt_status=$lt_dlunknown
-  cat > conftest.$ac_ext <<EOF
-#line 18577 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-#  define LT_DLGLOBAL		RTLD_GLOBAL
-#else
-#  ifdef DL_GLOBAL
-#    define LT_DLGLOBAL		DL_GLOBAL
-#  else
-#    define LT_DLGLOBAL		0
-#  endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
-   find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-#  ifdef RTLD_LAZY
-#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
-#  else
-#    ifdef DL_LAZY
-#      define LT_DLLAZY_OR_NOW		DL_LAZY
-#    else
-#      ifdef RTLD_NOW
-#        define LT_DLLAZY_OR_NOW	RTLD_NOW
-#      else
-#        ifdef DL_NOW
-#          define LT_DLLAZY_OR_NOW	DL_NOW
-#        else
-#          define LT_DLLAZY_OR_NOW	0
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
-  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
-  int status = $lt_dlunknown;
-
-  if (self)
-    {
-      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
-      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
-      /* dlclose (self); */
-    }
-
-    exit (status);
-}
-EOF
-  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
-    (./conftest; exit; ) 2>/dev/null
-    lt_status=$?
-    case x$lt_status in
-      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
-      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
-      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
-    esac
-  else :
-    # compilation failed
-    lt_cv_dlopen_self_static=no
-  fi
-fi
-rm -fr conftest*
-
-
-fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
-    fi
-
-    CPPFLAGS="$save_CPPFLAGS"
-    LDFLAGS="$save_LDFLAGS"
-    LIBS="$save_LIBS"
-    ;;
-  esac
-
-  case $lt_cv_dlopen_self in
-  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
-  *) enable_dlopen_self=unknown ;;
-  esac
-
-  case $lt_cv_dlopen_self_static in
-  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
-  *) enable_dlopen_self_static=unknown ;;
-  esac
-fi
-
-
 # The else clause should only fire when bootstrapping the
 # libtool distribution, otherwise you forgot to ship ltmain.sh
 # with your package, and you will get complaints that there are
@@ -18691,7 +18455,7 @@
   # Now quote all the things that may contain metacharacters while being
   # careful not to overquote the AC_SUBSTed values.  We take copies of the
   # variables and quote the copies for generation of the libtool script.
-  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
     SED SHELL STRIP \
     libname_spec library_names_spec soname_spec extract_expsyms_cmds \
     old_striplib striplib file_magic_cmd finish_cmds finish_eval \
@@ -18733,6 +18497,7 @@
     module_cmds_GCJ \
     module_expsym_cmds_GCJ \
     lt_cv_prog_compiler_c_o_GCJ \
+    fix_srcfile_path_GCJ \
     exclude_expsyms_GCJ \
     include_expsyms_GCJ; do
 
@@ -18809,6 +18574,9 @@
 # A C compiler.
 LTCC=$lt_LTCC
 
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
 # A language-specific compiler.
 CC=$lt_compiler_GCJ
 
@@ -19050,7 +18818,7 @@
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
 
 # Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path_GCJ"
+fix_srcfile_path=$lt_fix_srcfile_path
 
 # Set to yes if exported symbols are required.
 always_export_symbols=$always_export_symbols_GCJ
@@ -19099,7 +18867,6 @@
       RC)
 
 
-
 # Source file extension for RC test sources.
 ac_ext=rc
 
@@ -19108,7 +18875,7 @@
 objext_RC=$objext
 
 # Code to be used in simple compile tests
-lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
 
 # Code to be used in simple link tests
 lt_simple_link_test_code="$lt_simple_compile_test_code"
@@ -19118,20 +18885,23 @@
 # If no C compiler was specified, use CC.
 LTCC=${LTCC-"$CC"}
 
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
 # Allow CC to be a program name with arguments.
 compiler=$CC
 
 
 # save warnings/boilerplate of simple test code
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_compiler_boilerplate=`cat conftest.err`
 $rm conftest*
 
 ac_outfile=conftest.$ac_objext
-printf "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
 _lt_linker_boilerplate=`cat conftest.err`
 $rm conftest*
 
@@ -19166,7 +18936,7 @@
   # Now quote all the things that may contain metacharacters while being
   # careful not to overquote the AC_SUBSTed values.  We take copies of the
   # variables and quote the copies for generation of the libtool script.
-  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
     SED SHELL STRIP \
     libname_spec library_names_spec soname_spec extract_expsyms_cmds \
     old_striplib striplib file_magic_cmd finish_cmds finish_eval \
@@ -19208,6 +18978,7 @@
     module_cmds_RC \
     module_expsym_cmds_RC \
     lt_cv_prog_compiler_c_o_RC \
+    fix_srcfile_path_RC \
     exclude_expsyms_RC \
     include_expsyms_RC; do
 
@@ -19284,6 +19055,9 @@
 # A C compiler.
 LTCC=$lt_LTCC
 
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
 # A language-specific compiler.
 CC=$lt_compiler_RC
 
@@ -19525,7 +19299,7 @@
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
 
 # Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path="$fix_srcfile_path_RC"
+fix_srcfile_path=$lt_fix_srcfile_path
 
 # Set to yes if exported symbols are required.
 always_export_symbols=$always_export_symbols_RC
@@ -19624,13 +19398,13 @@
 
 
 
-# Check whether --enable-debug or --disable-debug was given.
+# Check whether --enable-debug was given.
 if test "${enable_debug+set}" = set; then
-  enableval="$enable_debug"
-
+  enableval=$enable_debug;
 	CXXFLAGS="-g -O0 -Wall"
-    cat >>confdefs.h <<\_ACEOF
-#define WITH_DEBUG 1
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_DEBUG
 _ACEOF
 
 
@@ -19639,13 +19413,13 @@
 	CXXFLAGS="-O0"
 
 
-fi;
+fi
 
 
-# Check whether --with-libldap or --without-libldap was given.
-if test "${with_libldap+set}" = set; then
-  withval="$with_libldap"
 
+# Check whether --with-libldap was given.
+if test "${with_libldap+set}" = set; then
+  withval=$with_libldap;
 	LIBS="-L$with_libldap $LIBS "
 
 else
@@ -19653,13 +19427,13 @@
 	LIBS="-L/usr/local/lib $LIBS "
 
 
-fi;
+fi
 
 
-# Check whether --with-ldap-includes or --without-ldap-includes was given.
-if test "${with_ldap_includes+set}" = set; then
-  withval="$with_ldap_includes"
 
+# Check whether --with-ldap-includes was given.
+if test "${with_ldap_includes+set}" = set; then
+  withval=$with_ldap_includes;
 	CPPFLAGS="-I$with_ldap_includes $CPPFLAGS "
 
 else
@@ -19667,10 +19441,11 @@
 	CPPFLAGS="-I/usr/local/include $CPPFLAGS "
 
 
-fi;
+fi
 
-echo "$as_me:$LINENO: checking for main in -lresolv" >&5
-echo $ECHO_N "checking for main in -lresolv... $ECHO_C" >&6
+
+{ echo "$as_me:$LINENO: checking for main in -lresolv" >&5
+echo $ECHO_N "checking for main in -lresolv... $ECHO_C" >&6; }
 if test "${ac_cv_lib_resolv_main+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -19687,46 +19462,43 @@
 int
 main ()
 {
-main ();
+return main ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_lib_resolv_main=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_resolv_main=no
+	ac_cv_lib_resolv_main=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_main" >&5
-echo "${ECHO_T}$ac_cv_lib_resolv_main" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_main" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_main" >&6; }
 if test $ac_cv_lib_resolv_main = yes; then
   cat >>confdefs.h <<_ACEOF
 #define HAVE_LIBRESOLV 1
@@ -19736,8 +19508,8 @@
 
 fi
 
-echo "$as_me:$LINENO: checking for ber_strdup in -llber" >&5
-echo $ECHO_N "checking for ber_strdup in -llber... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for ber_strdup in -llber" >&5
+echo $ECHO_N "checking for ber_strdup in -llber... $ECHO_C" >&6; }
 if test "${ac_cv_lib_lber_ber_strdup+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -19750,56 +19522,53 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
 char ber_strdup ();
 int
 main ()
 {
-ber_strdup ();
+return ber_strdup ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_lib_lber_ber_strdup=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_lber_ber_strdup=no
+	ac_cv_lib_lber_ber_strdup=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_lber_ber_strdup" >&5
-echo "${ECHO_T}$ac_cv_lib_lber_ber_strdup" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_lber_ber_strdup" >&5
+echo "${ECHO_T}$ac_cv_lib_lber_ber_strdup" >&6; }
 if test $ac_cv_lib_lber_ber_strdup = yes; then
 
         :
@@ -19813,8 +19582,8 @@
 
 fi
 
-echo "$as_me:$LINENO: checking for ldap_add_ext in -lldap" >&5
-echo $ECHO_N "checking for ldap_add_ext in -lldap... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for ldap_add_ext in -lldap" >&5
+echo $ECHO_N "checking for ldap_add_ext in -lldap... $ECHO_C" >&6; }
 if test "${ac_cv_lib_ldap_ldap_add_ext+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -19829,56 +19598,53 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
 char ldap_add_ext ();
 int
 main ()
 {
-ldap_add_ext ();
+return ldap_add_ext ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
   ac_cv_lib_ldap_ldap_add_ext=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_lib_ldap_ldap_add_ext=no
+	ac_cv_lib_ldap_ldap_add_ext=no
 fi
-rm -f conftest.err conftest.$ac_objext \
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_add_ext" >&5
-echo "${ECHO_T}$ac_cv_lib_ldap_ldap_add_ext" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_add_ext" >&5
+echo "${ECHO_T}$ac_cv_lib_ldap_ldap_add_ext" >&6; }
 if test $ac_cv_lib_ldap_ldap_add_ext = yes; then
 
         :
@@ -19892,8 +19658,8 @@
 
 fi
 
-echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
-echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; }
 if test "${ac_cv_header_time+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -19917,38 +19683,34 @@
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_cv_header_time=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_header_time=no
+	ac_cv_header_time=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
-echo "${ECHO_T}$ac_cv_header_time" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6; }
 if test $ac_cv_header_time = yes; then
 
 cat >>confdefs.h <<\_ACEOF
@@ -19958,17 +19720,17 @@
 fi
 
 if test "${ac_cv_header_ldap_h+set}" = set; then
-  echo "$as_me:$LINENO: checking for ldap.h" >&5
-echo $ECHO_N "checking for ldap.h... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for ldap.h" >&5
+echo $ECHO_N "checking for ldap.h... $ECHO_C" >&6; }
 if test "${ac_cv_header_ldap_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-echo "$as_me:$LINENO: result: $ac_cv_header_ldap_h" >&5
-echo "${ECHO_T}$ac_cv_header_ldap_h" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_header_ldap_h" >&5
+echo "${ECHO_T}$ac_cv_header_ldap_h" >&6; }
 else
   # Is the header compilable?
-echo "$as_me:$LINENO: checking ldap.h usability" >&5
-echo $ECHO_N "checking ldap.h usability... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking ldap.h usability" >&5
+echo $ECHO_N "checking ldap.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -19979,41 +19741,37 @@
 #include <ldap.h>
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_header_compiler=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_header_compiler=no
+	ac_header_compiler=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
 
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
 # Is the header present?
-echo "$as_me:$LINENO: checking ldap.h presence" >&5
-echo $ECHO_N "checking ldap.h presence... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking ldap.h presence" >&5
+echo $ECHO_N "checking ldap.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -20022,24 +19780,22 @@
 /* end confdefs.h.  */
 #include <ldap.h>
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   ac_header_preproc=yes
 else
   echo "$as_me: failed program was:" >&5
@@ -20047,9 +19803,10 @@
 
   ac_header_preproc=no
 fi
+
 rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
 
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
@@ -20073,25 +19830,18 @@
 echo "$as_me: WARNING: ldap.h: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: ldap.h: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: ldap.h: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------------ ##
-## Report this to the AC_PACKAGE_NAME lists.  ##
-## ------------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
+
     ;;
 esac
-echo "$as_me:$LINENO: checking for ldap.h" >&5
-echo $ECHO_N "checking for ldap.h... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for ldap.h" >&5
+echo $ECHO_N "checking for ldap.h... $ECHO_C" >&6; }
 if test "${ac_cv_header_ldap_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_cv_header_ldap_h=$ac_header_preproc
 fi
-echo "$as_me:$LINENO: result: $ac_cv_header_ldap_h" >&5
-echo "${ECHO_T}$ac_cv_header_ldap_h" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_header_ldap_h" >&5
+echo "${ECHO_T}$ac_cv_header_ldap_h" >&6; }
 
 fi
 
@@ -20121,17 +19871,17 @@
 rm -f conftest*
 
 if test "${ac_cv_header_lber_h+set}" = set; then
-  echo "$as_me:$LINENO: checking for lber.h" >&5
-echo $ECHO_N "checking for lber.h... $ECHO_C" >&6
+  { echo "$as_me:$LINENO: checking for lber.h" >&5
+echo $ECHO_N "checking for lber.h... $ECHO_C" >&6; }
 if test "${ac_cv_header_lber_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-echo "$as_me:$LINENO: result: $ac_cv_header_lber_h" >&5
-echo "${ECHO_T}$ac_cv_header_lber_h" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_header_lber_h" >&5
+echo "${ECHO_T}$ac_cv_header_lber_h" >&6; }
 else
   # Is the header compilable?
-echo "$as_me:$LINENO: checking lber.h usability" >&5
-echo $ECHO_N "checking lber.h usability... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking lber.h usability" >&5
+echo $ECHO_N "checking lber.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -20142,41 +19892,37 @@
 #include <lber.h>
 _ACEOF
 rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
   ac_header_compiler=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_header_compiler=no
+	ac_header_compiler=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
 
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
 # Is the header present?
-echo "$as_me:$LINENO: checking lber.h presence" >&5
-echo $ECHO_N "checking lber.h presence... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking lber.h presence" >&5
+echo $ECHO_N "checking lber.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -20185,24 +19931,22 @@
 /* end confdefs.h.  */
 #include <lber.h>
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
   ac_header_preproc=yes
 else
   echo "$as_me: failed program was:" >&5
@@ -20210,9 +19954,10 @@
 
   ac_header_preproc=no
 fi
+
 rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
 
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
@@ -20236,25 +19981,18 @@
 echo "$as_me: WARNING: lber.h: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: lber.h: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: lber.h: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------------ ##
-## Report this to the AC_PACKAGE_NAME lists.  ##
-## ------------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
+
     ;;
 esac
-echo "$as_me:$LINENO: checking for lber.h" >&5
-echo $ECHO_N "checking for lber.h... $ECHO_C" >&6
+{ echo "$as_me:$LINENO: checking for lber.h" >&5
+echo $ECHO_N "checking for lber.h... $ECHO_C" >&6; }
 if test "${ac_cv_header_lber_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_cv_header_lber_h=$ac_header_preproc
 fi
-echo "$as_me:$LINENO: result: $ac_cv_header_lber_h" >&5
-echo "${ECHO_T}$ac_cv_header_lber_h" >&6
+{ echo "$as_me:$LINENO: result: $ac_cv_header_lber_h" >&5
+echo "${ECHO_T}$ac_cv_header_lber_h" >&6; }
 
 fi
 
@@ -20286,7 +20024,8 @@
 
 
 
-                              ac_config_files="$ac_config_files Makefile src/Makefile examples/Makefile"
+ac_config_files="$ac_config_files Makefile src/Makefile examples/Makefile"
+
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
@@ -20305,39 +20044,58 @@
 
 # The following way of writing the cache mishandles newlines in values,
 # but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
+# So, we kill variables containing newlines.
 # Ultrix sh set writes to stderr and can't be redirected directly,
 # and sets the high bit in the cache file unless we assign to the vars.
-{
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+
   (set) 2>&1 |
-    case `(ac_space=' '; set | grep ac_space) 2>&1` in
-    *ac_space=\ *)
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
       # `set' does not quote correctly, so add quotes (double-quote
       # substitution turns \\\\ into \\, and sed turns \\ into \).
       sed -n \
 	"s/'/'\\\\''/g;
 	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
-      ;;
+      ;; #(
     *)
       # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n \
-	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
       ;;
-    esac;
-} |
+    esac |
+    sort
+) |
   sed '
+     /^ac_cv_env_/b end
      t clear
-     : clear
+     :clear
      s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
      t end
-     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
-     : end' >>confcache
-if diff $cache_file confcache >/dev/null 2>&1; then :; else
-  if test -w $cache_file; then
-    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
     cat confcache >$cache_file
   else
-    echo "not updating unwritable cache $cache_file"
+    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+echo "$as_me: not updating unwritable cache $cache_file" >&6;}
   fi
 fi
 rm -f confcache
@@ -20346,32 +20104,18 @@
 # Let make expand exec_prefix.
 test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
-  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
-s/:*\$(srcdir):*/:/;
-s/:*\${srcdir}:*/:/;
-s/:*@srcdir@:*/:/;
-s/^\([^=]*=[	 ]*\):*/\1/;
-s/:*$//;
-s/^[^=]*=[	 ]*$//;
-}'
-fi
-
 DEFS=-DHAVE_CONFIG_H
 
 ac_libobjs=
 ac_ltlibobjs=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
-  ac_i=`echo "$ac_i" |
-	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
-  # 2. Add them.
-  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
-  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
 done
 LIBOBJS=$ac_libobjs
 
@@ -20423,18 +20167,46 @@
 ## M4sh Initialization.  ##
 ## --------------------- ##
 
-# Be Bourne compatible
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   emulate sh
   NULLCMD=:
   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
-  set -o posix
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
 fi
-DUALCASE=1; export DUALCASE # for MKS sh
 
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
 # Support unset when possible.
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
@@ -20443,8 +20215,43 @@
 fi
 
 
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
 # Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
 PS1='$ '
 PS2='> '
 PS4='+ '
@@ -20458,18 +20265,19 @@
   if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
-    $as_unset $as_var
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
   fi
 done
 
 # Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
@@ -20477,159 +20285,120 @@
 
 
 # Name of the executable.
-as_me=`$as_basename "$0" ||
+as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)$' \| \
-	 .     : '\(.\)' 2>/dev/null ||
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
 echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
-  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\/\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
 
+# CDPATH.
+$as_unset CDPATH
 
-# PATH needs CR, and LINENO needs CR and PATH.
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
 
-
   as_lineno_1=$LINENO
   as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
   test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
-  # Find who we are.  Look in the path if we contain no path at all
-  # relative or not.
-  case $0 in
-    *[\\/]* ) as_myself=$0 ;;
-    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
 
-       ;;
-  esac
-  # We did not find ourselves, most probably we were run as `sh COMMAND'
-  # in which case we are not to be found in the path.
-  if test "x$as_myself" = x; then
-    as_myself=$0
-  fi
-  if test ! -f "$as_myself"; then
-    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
-echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
-   { (exit 1); exit 1; }; }
-  fi
-  case $CONFIG_SHELL in
-  '')
-    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for as_base in sh bash ksh sh5; do
-	 case $as_dir in
-	 /*)
-	   if ("$as_dir/$as_base" -c '
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
-	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
-	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
-	     CONFIG_SHELL=$as_dir/$as_base
-	     export CONFIG_SHELL
-	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
-	   fi;;
-	 esac
-       done
-done
-;;
-  esac
-
   # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
   # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line before each line; the second 'sed' does the real
-  # work.  The second script uses 'N' to pair each line-number line
-  # with the numbered line, and appends trailing '-' during
-  # substitution so that $LINENO is not a special case at line end.
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
   # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
-  sed '=' <$as_myself |
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
     sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
       N
-      s,$,-,
-      : loop
-      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
       t loop
-      s,-$,,
-      s,^['$as_cr_digits']*\n,,
+      s/-\n.*//
     ' >$as_me.lineno &&
-  chmod +x $as_me.lineno ||
-    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
-echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
    { (exit 1); exit 1; }; }
 
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensible to this).
-  . ./$as_me.lineno
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
   # Exit status is that of the last command.
   exit
 }
 
 
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
-  *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T='	' ;;
-  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
-  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1; then
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
   as_expr=expr
 else
   as_expr=false
 fi
 
 rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
 echo >conf$$.file
 if ln -s conf$$.file conf$$ 2>/dev/null; then
-  # We could just check for DJGPP; but this test a) works b) is more generic
-  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
-  if test -f conf$$.exe; then
-    # Don't use ln at all; we don't have any links
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
     as_ln_s='cp -p'
-  else
-    as_ln_s='ln -s'
-  fi
 elif ln conf$$.file conf$$ 2>/dev/null; then
   as_ln_s=ln
 else
   as_ln_s='cp -p'
 fi
-rm -f conf$$ conf$$.exe conf$$.file
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
 
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
@@ -20638,7 +20407,28 @@
   as_mkdir_p=false
 fi
 
-as_executable_p="test -f"
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+        test -d "$1/.";
+      else
+	case $1 in
+        -*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -20647,62 +20437,35 @@
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" 	$as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
 exec 6>&1
 
-# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# Save the log message, to keep $[0] and so on meaningful, and to
 # report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.  Logging --version etc. is OK.
-exec 5>>config.log
-{
-  echo
-  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-} >&5
-cat >&5 <<_CSEOF
+# values after options handling.
+ac_log="
+This file was extended by ldapcpplib $as_me 0.0.5, which was
+generated by GNU Autoconf 2.61.  Invocation command line was
 
-This file was extended by $as_me, which was
-generated by GNU Autoconf 2.59.  Invocation command line was
-
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
   CONFIG_LINKS    = $CONFIG_LINKS
   CONFIG_COMMANDS = $CONFIG_COMMANDS
   $ $0 $@
 
-_CSEOF
-echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
-echo >&5
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
 _ACEOF
 
+cat >>$CONFIG_STATUS <<_ACEOF
 # Files that config.status was made for.
-if test -n "$ac_config_files"; then
-  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
-fi
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
 
-if test -n "$ac_config_headers"; then
-  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
-fi
+_ACEOF
 
-if test -n "$ac_config_links"; then
-  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_commands"; then
-  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
-fi
-
 cat >>$CONFIG_STATUS <<\_ACEOF
-
 ac_cs_usage="\
 \`$as_me' instantiates files from templates according to the
 current configuration.
@@ -20710,7 +20473,7 @@
 Usage: $0 [OPTIONS] [FILE]...
 
   -h, --help       print this help, then exit
-  -V, --version    print version number, then exit
+  -V, --version    print version number and configuration settings, then exit
   -q, --quiet      do not print progress messages
   -d, --debug      don't remove temporary files
       --recheck    update $as_me by reconfiguring in the same conditions
@@ -20729,19 +20492,22 @@
 $config_commands
 
 Report bugs to <bug-autoconf at gnu.org>."
-_ACEOF
 
+_ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-config.status
-configured by $0, generated by GNU Autoconf 2.59,
-  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+ldapcpplib config.status 0.0.5
+configured by $0, generated by GNU Autoconf 2.61,
+  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
-Copyright (C) 2003 Free Software Foundation, Inc.
+Copyright (C) 2006 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
-srcdir=$srcdir
-INSTALL="$INSTALL"
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
 _ACEOF
 
 cat >>$CONFIG_STATUS <<\_ACEOF
@@ -20752,39 +20518,24 @@
 do
   case $1 in
   --*=*)
-    ac_option=`expr "x$1" : 'x\([^=]*\)='`
-    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
     ac_shift=:
     ;;
-  -*)
+  *)
     ac_option=$1
     ac_optarg=$2
     ac_shift=shift
     ;;
-  *) # This is not an option, so the user has probably given explicit
-     # arguments.
-     ac_option=$1
-     ac_need_defaults=false;;
   esac
 
   case $ac_option in
   # Handling of the options.
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
-  --version | --vers* | -V )
-    echo "$ac_cs_version"; exit 0 ;;
-  --he | --h)
-    # Conflict between --help and --header
-    { { echo "$as_me:$LINENO: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2;}
-   { (exit 1); exit 1; }; };;
-  --help | --hel | -h )
-    echo "$ac_cs_usage"; exit 0 ;;
-  --debug | --d* | -d )
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
@@ -20794,18 +20545,24 @@
     $ac_shift
     CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
     ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    { echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit ;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2;}
+  -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
    { (exit 1); exit 1; }; } ;;
 
-  *) ac_config_targets="$ac_config_targets $1" ;;
+  *) ac_config_targets="$ac_config_targets $1"
+     ac_need_defaults=false ;;
 
   esac
   shift
@@ -20821,39 +20578,51 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 if \$ac_cs_recheck; then
-  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
-  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  CONFIG_SHELL=$SHELL
+  export CONFIG_SHELL
+  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
 fi
 
 _ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  echo "$ac_log"
+} >&5
 
+_ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 #
-# INIT-COMMANDS section.
+# INIT-COMMANDS
 #
-
 AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
 
 _ACEOF
 
-
-
 cat >>$CONFIG_STATUS <<\_ACEOF
+
+# Handling of arguments.
 for ac_config_target in $ac_config_targets
 do
-  case "$ac_config_target" in
-  # Handling of arguments.
-  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-  "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
-  "examples/Makefile" ) CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
-  "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
-  "src/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
+  case $ac_config_target in
+    "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+    "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
+
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
    { (exit 1); exit 1; }; };;
   esac
 done
 
+
 # If the user did not use the arguments to specify the items to instantiate,
 # then the envvar interface is used.  Set only those that are not.
 # We use the long form for the default assignment because of an extremely
@@ -20865,600 +20634,596 @@
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
-# simply because there is no reason to put it here, and in addition,
+# simply because there is no reason against having it here, and in addition,
 # creating and moving files from /tmp can sometimes cause problems.
-# Create a temporary directory, and hook for its removal unless debugging.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
   trap '{ (exit 1); exit 1; }' 1 2 13 15
 }
-
 # Create a (secure) tmp directory for tmp files.
 
 {
-  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
   test -n "$tmp" && test -d "$tmp"
 }  ||
 {
-  tmp=./confstat$$-$RANDOM
-  (umask 077 && mkdir $tmp)
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
 } ||
 {
    echo "$me: cannot create a temporary directory in ." >&2
    { (exit 1); exit 1; }
 }
 
-_ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
-
 #
-# CONFIG_FILES section.
+# Set up the sed scripts for CONFIG_FILES section.
 #
 
 # No need to generate the scripts if there are no CONFIG_FILES.
 # This happens for instance when ./config.status config.h
-if test -n "\$CONFIG_FILES"; then
-  # Protect against being on the right side of a sed subst in config.status.
-  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
-   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
-s, at SHELL@,$SHELL,;t t
-s, at PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
-s, at PACKAGE_NAME@,$PACKAGE_NAME,;t t
-s, at PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
-s, at PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
-s, at PACKAGE_STRING@,$PACKAGE_STRING,;t t
-s, at PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
-s, at exec_prefix@,$exec_prefix,;t t
-s, at prefix@,$prefix,;t t
-s, at program_transform_name@,$program_transform_name,;t t
-s, at bindir@,$bindir,;t t
-s, at sbindir@,$sbindir,;t t
-s, at libexecdir@,$libexecdir,;t t
-s, at datadir@,$datadir,;t t
-s, at sysconfdir@,$sysconfdir,;t t
-s, at sharedstatedir@,$sharedstatedir,;t t
-s, at localstatedir@,$localstatedir,;t t
-s, at libdir@,$libdir,;t t
-s, at includedir@,$includedir,;t t
-s, at oldincludedir@,$oldincludedir,;t t
-s, at infodir@,$infodir,;t t
-s, at mandir@,$mandir,;t t
-s, at build_alias@,$build_alias,;t t
-s, at host_alias@,$host_alias,;t t
-s, at target_alias@,$target_alias,;t t
-s, at DEFS@,$DEFS,;t t
-s, at ECHO_C@,$ECHO_C,;t t
-s, at ECHO_N@,$ECHO_N,;t t
-s, at ECHO_T@,$ECHO_T,;t t
-s, at LIBS@,$LIBS,;t t
-s, at INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
-s, at INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
-s, at INSTALL_DATA@,$INSTALL_DATA,;t t
-s, at CYGPATH_W@,$CYGPATH_W,;t t
-s, at PACKAGE@,$PACKAGE,;t t
-s, at VERSION@,$VERSION,;t t
-s, at ACLOCAL@,$ACLOCAL,;t t
-s, at AUTOCONF@,$AUTOCONF,;t t
-s, at AUTOMAKE@,$AUTOMAKE,;t t
-s, at AUTOHEADER@,$AUTOHEADER,;t t
-s, at MAKEINFO@,$MAKEINFO,;t t
-s, at install_sh@,$install_sh,;t t
-s, at STRIP@,$STRIP,;t t
-s, at ac_ct_STRIP@,$ac_ct_STRIP,;t t
-s, at INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
-s, at mkdir_p@,$mkdir_p,;t t
-s, at AWK@,$AWK,;t t
-s, at SET_MAKE@,$SET_MAKE,;t t
-s, at am__leading_dot@,$am__leading_dot,;t t
-s, at AMTAR@,$AMTAR,;t t
-s, at am__tar@,$am__tar,;t t
-s, at am__untar@,$am__untar,;t t
-s, at CXX@,$CXX,;t t
-s, at CXXFLAGS@,$CXXFLAGS,;t t
-s, at LDFLAGS@,$LDFLAGS,;t t
-s, at CPPFLAGS@,$CPPFLAGS,;t t
-s, at ac_ct_CXX@,$ac_ct_CXX,;t t
-s, at EXEEXT@,$EXEEXT,;t t
-s, at OBJEXT@,$OBJEXT,;t t
-s, at DEPDIR@,$DEPDIR,;t t
-s, at am__include@,$am__include,;t t
-s, at am__quote@,$am__quote,;t t
-s, at AMDEP_TRUE@,$AMDEP_TRUE,;t t
-s, at AMDEP_FALSE@,$AMDEP_FALSE,;t t
-s, at AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
-s, at CXXDEPMODE@,$CXXDEPMODE,;t t
-s, at am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t
-s, at am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t
-s, at build@,$build,;t t
-s, at build_cpu@,$build_cpu,;t t
-s, at build_vendor@,$build_vendor,;t t
-s, at build_os@,$build_os,;t t
-s, at host@,$host,;t t
-s, at host_cpu@,$host_cpu,;t t
-s, at host_vendor@,$host_vendor,;t t
-s, at host_os@,$host_os,;t t
-s, at CC@,$CC,;t t
-s, at CFLAGS@,$CFLAGS,;t t
-s, at ac_ct_CC@,$ac_ct_CC,;t t
-s, at CCDEPMODE@,$CCDEPMODE,;t t
-s, at am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
-s, at am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
-s, at EGREP@,$EGREP,;t t
-s, at LN_S@,$LN_S,;t t
-s, at ECHO@,$ECHO,;t t
-s, at AR@,$AR,;t t
-s, at ac_ct_AR@,$ac_ct_AR,;t t
-s, at RANLIB@,$RANLIB,;t t
-s, at ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
-s, at CPP@,$CPP,;t t
-s, at CXXCPP@,$CXXCPP,;t t
-s, at F77@,$F77,;t t
-s, at FFLAGS@,$FFLAGS,;t t
-s, at ac_ct_F77@,$ac_ct_F77,;t t
-s, at LIBTOOL@,$LIBTOOL,;t t
-s, at LIBOBJS@,$LIBOBJS,;t t
-s, at LTLIBOBJS@,$LTLIBOBJS,;t t
-CEOF
+if test -n "$CONFIG_FILES"; then
 
 _ACEOF
 
-  cat >>$CONFIG_STATUS <<\_ACEOF
-  # Split the substitutions into bite-sized pieces for seds with
-  # small command number limits, like on Digital OSF/1 and HP-UX.
-  ac_max_sed_lines=48
-  ac_sed_frag=1 # Number of current file.
-  ac_beg=1 # First line for current file.
-  ac_end=$ac_max_sed_lines # Line after last line for current file.
-  ac_more_lines=:
-  ac_sed_cmds=
-  while $ac_more_lines; do
-    if test $ac_beg -gt 1; then
-      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
-    else
-      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
-    fi
-    if test ! -s $tmp/subs.frag; then
-      ac_more_lines=false
-    else
-      # The purpose of the label and of the branching condition is to
-      # speed up the sed processing (if there are no `@' at all, there
-      # is no need to browse any of the substitutions).
-      # These are the two extra sed commands mentioned above.
-      (echo ':t
-  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
-      if test -z "$ac_sed_cmds"; then
-	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
-      else
-	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
-      fi
-      ac_sed_frag=`expr $ac_sed_frag + 1`
-      ac_beg=$ac_end
-      ac_end=`expr $ac_end + $ac_max_sed_lines`
-    fi
-  done
-  if test -z "$ac_sed_cmds"; then
-    ac_sed_cmds=cat
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
+INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
+INSTALL_DATA!$INSTALL_DATA$ac_delim
+am__isrc!$am__isrc$ac_delim
+CYGPATH_W!$CYGPATH_W$ac_delim
+PACKAGE!$PACKAGE$ac_delim
+VERSION!$VERSION$ac_delim
+ACLOCAL!$ACLOCAL$ac_delim
+AUTOCONF!$AUTOCONF$ac_delim
+AUTOMAKE!$AUTOMAKE$ac_delim
+AUTOHEADER!$AUTOHEADER$ac_delim
+MAKEINFO!$MAKEINFO$ac_delim
+install_sh!$install_sh$ac_delim
+STRIP!$STRIP$ac_delim
+INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim
+mkdir_p!$mkdir_p$ac_delim
+AWK!$AWK$ac_delim
+SET_MAKE!$SET_MAKE$ac_delim
+am__leading_dot!$am__leading_dot$ac_delim
+AMTAR!$AMTAR$ac_delim
+am__tar!$am__tar$ac_delim
+am__untar!$am__untar$ac_delim
+CXX!$CXX$ac_delim
+CXXFLAGS!$CXXFLAGS$ac_delim
+LDFLAGS!$LDFLAGS$ac_delim
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CXX!$ac_ct_CXX$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+DEPDIR!$DEPDIR$ac_delim
+am__include!$am__include$ac_delim
+am__quote!$am__quote$ac_delim
+AMDEP_TRUE!$AMDEP_TRUE$ac_delim
+AMDEP_FALSE!$AMDEP_FALSE$ac_delim
+AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim
+CXXDEPMODE!$CXXDEPMODE$ac_delim
+am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim
+am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim
+build!$build$ac_delim
+build_cpu!$build_cpu$ac_delim
+build_vendor!$build_vendor$ac_delim
+build_os!$build_os$ac_delim
+host!$host$ac_delim
+host_cpu!$host_cpu$ac_delim
+host_vendor!$host_vendor$ac_delim
+host_os!$host_os$ac_delim
+CC!$CC$ac_delim
+CFLAGS!$CFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+CCDEPMODE!$CCDEPMODE$ac_delim
+am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim
+am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim
+SED!$SED$ac_delim
+GREP!$GREP$ac_delim
+EGREP!$EGREP$ac_delim
+LN_S!$LN_S$ac_delim
+ECHO!$ECHO$ac_delim
+AR!$AR$ac_delim
+RANLIB!$RANLIB$ac_delim
+CPP!$CPP$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
-fi # test -n "$CONFIG_FILES"
+done
 
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
 _ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+CEOF$ac_eof
+_ACEOF
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+CXXCPP!$CXXCPP$ac_delim
+F77!$F77$ac_delim
+FFLAGS!$FFLAGS$ac_delim
+ac_ct_F77!$ac_ct_F77$ac_delim
+LIBTOOL!$LIBTOOL$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 7; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
 cat >>$CONFIG_STATUS <<\_ACEOF
-for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
-  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
-  case $ac_file in
-  - | *:- | *:-:* ) # input from stdin
-	cat >$tmp/stdin
-	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  * )   ac_file_in=$ac_file.in ;;
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
   esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+   { (exit 1); exit 1; }; };;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
 
-  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
-  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+   { (exit 1); exit 1; }; };;
+      esac
+      ac_file_inputs="$ac_file_inputs $ac_f"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input="Generated from "`IFS=:
+	  echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    fi
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin";;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
 $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 	 X"$ac_file" : 'X\(//\)[^/]' \| \
 	 X"$ac_file" : 'X\(//\)$' \| \
-	 X"$ac_file" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
 echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-  { if $as_mkdir_p; then
-    mkdir -p "$ac_dir"
-  else
-    as_dir="$ac_dir"
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  { as_dir="$ac_dir"
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
     as_dirs=
-    while test ! -d "$as_dir"; do
-      as_dirs="$as_dir $as_dirs"
-      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
 $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 	 X"$as_dir" : 'X\(//\)[^/]' \| \
 	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
 echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
     done
-    test ! -n "$as_dirs" || mkdir $as_dirs
-  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
    { (exit 1); exit 1; }; }; }
-
   ac_builddir=.
 
-if test "$ac_dir" != .; then
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
   ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A "../" for each directory in $ac_dir_suffix.
-  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
-  ac_dir_suffix= ac_top_builddir=
-fi
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
 
 case $srcdir in
-  .)  # No --srcdir option.  We are building in place.
+  .)  # We are building in place.
     ac_srcdir=.
-    if test -z "$ac_top_builddir"; then
-       ac_top_srcdir=.
-    else
-       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
-    fi ;;
-  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
     ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir ;;
-  *) # Relative path.
-    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
 esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
-  case "$ac_dir" in
-  .) ac_abs_builddir=`pwd`;;
-  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
-  *) ac_abs_builddir=`pwd`/"$ac_dir";;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
-  case ${ac_top_builddir}. in
-  .) ac_abs_top_builddir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
-  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
-  case $ac_srcdir in
-  .) ac_abs_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
-  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
-  case $ac_top_srcdir in
-  .) ac_abs_top_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
-  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
-  esac;;
-esac
 
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
 
   case $INSTALL in
   [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
-  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
   esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
 
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
-  # Let's still pretend it is `configure' which instantiates (i.e., don't
-  # use $as_me), people would be surprised to read:
-  #    /* config.h.  Generated by config.status.  */
-  if test x"$ac_file" = x-; then
-    configure_input=
-  else
-    configure_input="$ac_file.  "
-  fi
-  configure_input=$configure_input"Generated from `echo $ac_file_in |
-				     sed 's,.*/,,'` by configure."
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
 
-  # First look for the input files in the build tree, otherwise in the
-  # src tree.
-  ac_file_inputs=`IFS=:
-    for f in $ac_file_in; do
-      case $f in
-      -) echo $tmp/stdin ;;
-      [\\/$]*)
-	 # Absolute (can't be DOS-style, as IFS=:)
-	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-	 echo "$f";;
-      *) # Relative
-	 if test -f "$f"; then
-	   # Build tree
-	   echo "$f"
-	 elif test -f "$srcdir/$f"; then
-	   # Source tree
-	   echo "$srcdir/$f"
-	 else
-	   # /dev/null tree
-	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-	 fi;;
-      esac
-    done` || { (exit 1); exit 1; }
+case `sed -n '/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+    s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
 $extrasub
 _ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF
 :t
 /@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s, at configure_input@,$configure_input,;t t
-s, at srcdir@,$ac_srcdir,;t t
-s, at abs_srcdir@,$ac_abs_srcdir,;t t
-s, at top_srcdir@,$ac_top_srcdir,;t t
-s, at abs_top_srcdir@,$ac_abs_top_srcdir,;t t
-s, at builddir@,$ac_builddir,;t t
-s, at abs_builddir@,$ac_abs_builddir,;t t
-s, at top_builddir@,$ac_top_builddir,;t t
-s, at abs_top_builddir@,$ac_abs_top_builddir,;t t
-s, at INSTALL@,$ac_INSTALL,;t t
-" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
-  rm -f $tmp/stdin
-  if test x"$ac_file" != x-; then
-    mv $tmp/out $ac_file
-  else
-    cat $tmp/out
-    rm -f $tmp/out
-  fi
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out
 
-done
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
 
-#
-# CONFIG_HEADER section.
-#
-
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
-#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
-ac_dB='[	 ].*$,\1#\2'
-ac_dC=' '
-ac_dD=',;t'
-# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
-ac_uB='$,\1#\2define\3'
-ac_uC=' '
-ac_uD=',;t'
-
-for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
-  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  rm -f "$tmp/stdin"
   case $ac_file in
-  - | *:- | *:-:* ) # input from stdin
-	cat >$tmp/stdin
-	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  * )   ac_file_in=$ac_file.in ;;
+  -) cat "$tmp/out"; rm -f "$tmp/out";;
+  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
   esac
-
-  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-
-  # First look for the input files in the build tree, otherwise in the
-  # src tree.
-  ac_file_inputs=`IFS=:
-    for f in $ac_file_in; do
-      case $f in
-      -) echo $tmp/stdin ;;
-      [\\/$]*)
-	 # Absolute (can't be DOS-style, as IFS=:)
-	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-	 # Do quote $f, to prevent DOS paths from being IFS'd.
-	 echo "$f";;
-      *) # Relative
-	 if test -f "$f"; then
-	   # Build tree
-	   echo "$f"
-	 elif test -f "$srcdir/$f"; then
-	   # Source tree
-	   echo "$srcdir/$f"
-	 else
-	   # /dev/null tree
-	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-	 fi;;
-      esac
-    done` || { (exit 1); exit 1; }
-  # Remove the trailing spaces.
-  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
-
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
 _ACEOF
 
-# Transform confdefs.h into two sed scripts, `conftest.defines' and
-# `conftest.undefs', that substitutes the proper values into
-# config.h.in to produce config.h.  The first handles `#define'
-# templates, and the second `#undef' templates.
-# And first: Protect against being on the right side of a sed subst in
-# config.status.  Protect against being in an unquoted here document
-# in config.status.
-rm -f conftest.defines conftest.undefs
-# Using a here document instead of a string reduces the quoting nightmare.
-# Putting comments in sed scripts is not portable.
-#
-# `end' is used to avoid that the second main sed command (meant for
-# 0-ary CPP macros) applies to n-ary macro definitions.
-# See the Autoconf documentation for `clear'.
-cat >confdef2sed.sed <<\_ACEOF
-s/[\\&,]/\\&/g
-s,[\\$`],\\&,g
-t clear
-: clear
-s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
-t end
-s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
-: end
-_ACEOF
-# If some macros were called several times there might be several times
-# the same #defines, which is useless.  Nevertheless, we may not want to
-# sort them, since we want the *last* AC-DEFINE to be honored.
-uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
-sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
-rm -f confdef2sed.sed
+# Transform confdefs.h into a sed script `conftest.defines', that
+# substitutes the proper values into config.h.in to produce config.h.
+rm -f conftest.defines conftest.tail
+# First, append a space to every undef/define line, to ease matching.
+echo 's/$/ /' >conftest.defines
+# Then, protect against being on the right side of a sed subst, or in
+# an unquoted here document, in config.status.  If some macros were
+# called several times there might be several #defines for the same
+# symbol, which is useless.  But do not sort them, since the last
+# AC_DEFINE must be honored.
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
+# NAME is the cpp macro being defined, VALUE is the value it is being given.
+# PARAMS is the parameter list in the macro definition--in most cases, it's
+# just an empty string.
+ac_dA='s,^\\([	 #]*\\)[^	 ]*\\([	 ]*'
+ac_dB='\\)[	 (].*,\\1define\\2'
+ac_dC=' '
+ac_dD=' ,'
 
-# This sed command replaces #undef with comments.  This is necessary, for
+uniq confdefs.h |
+  sed -n '
+	t rset
+	:rset
+	s/^[	 ]*#[	 ]*define[	 ][	 ]*//
+	t ok
+	d
+	:ok
+	s/[\\&,]/\\&/g
+	s/^\('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
+	s/^\('"$ac_word_re"'\)[	 ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
+  ' >>conftest.defines
+
+# Remove the space that was appended to ease matching.
+# Then replace #undef with comments.  This is necessary, for
 # example, in the case of _POSIX_SOURCE, which is predefined and required
 # on some systems where configure will not decide to define it.
-cat >>conftest.undefs <<\_ACEOF
-s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
-_ACEOF
+# (The regexp can be short, since the line contains either #define or #undef.)
+echo 's/ $//
+s,^[	 #]*u.*,/* & */,' >>conftest.defines
 
-# Break up conftest.defines because some shells have a limit on the size
-# of here documents, and old seds have small limits too (100 cmds).
-echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
-echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
-echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
-echo '  :' >>$CONFIG_STATUS
-rm -f conftest.tail
-while grep . conftest.defines >/dev/null
+# Break up conftest.defines:
+ac_max_sed_lines=50
+
+# First sed command is:	 sed -f defines.sed $ac_file_inputs >"$tmp/out1"
+# Second one is:	 sed -f defines.sed "$tmp/out1" >"$tmp/out2"
+# Third one will be:	 sed -f defines.sed "$tmp/out2" >"$tmp/out1"
+# et cetera.
+ac_in='$ac_file_inputs'
+ac_out='"$tmp/out1"'
+ac_nxt='"$tmp/out2"'
+
+while :
 do
-  # Write a limited-size here document to $tmp/defines.sed.
-  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
-  # Speed up: don't consider the non `#define' lines.
-  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
-  # Work around the forget-to-reset-the-flag bug.
-  echo 't clr' >>$CONFIG_STATUS
-  echo ': clr' >>$CONFIG_STATUS
-  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  # Write a here document:
+    cat >>$CONFIG_STATUS <<_ACEOF
+    # First, check the format of the line:
+    cat >"\$tmp/defines.sed" <<\\CEOF
+/^[	 ]*#[	 ]*undef[	 ][	 ]*$ac_word_re[	 ]*\$/b def
+/^[	 ]*#[	 ]*define[	 ][	 ]*$ac_word_re[(	 ]/b def
+b
+:def
+_ACEOF
+  sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
   echo 'CEOF
-  sed -f $tmp/defines.sed $tmp/in >$tmp/out
-  rm -f $tmp/in
-  mv $tmp/out $tmp/in
-' >>$CONFIG_STATUS
-  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+    sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
+  ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
+  sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
+  grep . conftest.tail >/dev/null || break
   rm -f conftest.defines
   mv conftest.tail conftest.defines
 done
-rm -f conftest.defines
-echo '  fi # grep' >>$CONFIG_STATUS
-echo >>$CONFIG_STATUS
+rm -f conftest.defines conftest.tail
 
-# Break up conftest.undefs because some shells have a limit on the size
-# of here documents, and old seds have small limits too (100 cmds).
-echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
-rm -f conftest.tail
-while grep . conftest.undefs >/dev/null
-do
-  # Write a limited-size here document to $tmp/undefs.sed.
-  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
-  # Speed up: don't consider the non `#undef'
-  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
-  # Work around the forget-to-reset-the-flag bug.
-  echo 't clr' >>$CONFIG_STATUS
-  echo ': clr' >>$CONFIG_STATUS
-  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
-  echo 'CEOF
-  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
-  rm -f $tmp/in
-  mv $tmp/out $tmp/in
-' >>$CONFIG_STATUS
-  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
-  rm -f conftest.undefs
-  mv conftest.tail conftest.undefs
-done
-rm -f conftest.undefs
-
+echo "ac_result=$ac_in" >>$CONFIG_STATUS
 cat >>$CONFIG_STATUS <<\_ACEOF
-  # Let's still pretend it is `configure' which instantiates (i.e., don't
-  # use $as_me), people would be surprised to read:
-  #    /* config.h.  Generated by config.status.  */
-  if test x"$ac_file" = x-; then
-    echo "/* Generated by configure.  */" >$tmp/config.h
-  else
-    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
-  fi
-  cat $tmp/in >>$tmp/config.h
-  rm -f $tmp/in
   if test x"$ac_file" != x-; then
-    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+    echo "/* $configure_input  */" >"$tmp/config.h"
+    cat "$ac_result" >>"$tmp/config.h"
+    if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
       { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
 echo "$as_me: $ac_file is unchanged" >&6;}
     else
-      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$ac_file" : 'X\(//\)[^/]' \| \
-	 X"$ac_file" : 'X\(//\)$' \| \
-	 X"$ac_file" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-      { if $as_mkdir_p; then
-    mkdir -p "$ac_dir"
-  else
-    as_dir="$ac_dir"
-    as_dirs=
-    while test ! -d "$as_dir"; do
-      as_dirs="$as_dir $as_dirs"
-      as_dir=`(dirname "$as_dir") 2>/dev/null ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-    done
-    test ! -n "$as_dirs" || mkdir $as_dirs
-  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
-   { (exit 1); exit 1; }; }; }
-
       rm -f $ac_file
-      mv $tmp/config.h $ac_file
+      mv "$tmp/config.h" $ac_file
     fi
   else
-    cat $tmp/config.h
-    rm -f $tmp/config.h
+    echo "/* $configure_input  */"
+    cat "$ac_result"
   fi
+  rm -f "$tmp/out12"
 # Compute $ac_file's index in $config_headers.
 _am_stamp_count=1
 for _am_header in $config_headers :; do
@@ -21469,135 +21234,39 @@
       _am_stamp_count=`expr $_am_stamp_count + 1` ;;
   esac
 done
-echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+echo "timestamp for $ac_file" >`$as_dirname -- $ac_file ||
 $as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 	 X$ac_file : 'X\(//\)[^/]' \| \
 	 X$ac_file : 'X\(//\)$' \| \
-	 X$ac_file : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
+	 X$ac_file : 'X\(/\)' \| . 2>/dev/null ||
 echo X$ac_file |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`/stamp-h$_am_stamp_count
-done
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
 
-#
-# CONFIG_COMMANDS section.
-#
-for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
-  ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
-  ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
-  ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
-$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$ac_dest" : 'X\(//\)[^/]' \| \
-	 X"$ac_dest" : 'X\(//\)$' \| \
-	 X"$ac_dest" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X"$ac_dest" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-  { if $as_mkdir_p; then
-    mkdir -p "$ac_dir"
-  else
-    as_dir="$ac_dir"
-    as_dirs=
-    while test ! -d "$as_dir"; do
-      as_dirs="$as_dir $as_dirs"
-      as_dir=`(dirname "$as_dir") 2>/dev/null ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-    done
-    test ! -n "$as_dirs" || mkdir $as_dirs
-  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
-   { (exit 1); exit 1; }; }; }
+  :C)  { echo "$as_me:$LINENO: executing $ac_file commands" >&5
+echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
 
-  ac_builddir=.
 
-if test "$ac_dir" != .; then
-  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A "../" for each directory in $ac_dir_suffix.
-  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
-  ac_dir_suffix= ac_top_builddir=
-fi
-
-case $srcdir in
-  .)  # No --srcdir option.  We are building in place.
-    ac_srcdir=.
-    if test -z "$ac_top_builddir"; then
-       ac_top_srcdir=.
-    else
-       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
-    fi ;;
-  [\\/]* | ?:[\\/]* )  # Absolute path.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir ;;
-  *) # Relative path.
-    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
-  case "$ac_dir" in
-  .) ac_abs_builddir=`pwd`;;
-  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
-  *) ac_abs_builddir=`pwd`/"$ac_dir";;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
-  case ${ac_top_builddir}. in
-  .) ac_abs_top_builddir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
-  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
-  case $ac_srcdir in
-  .) ac_abs_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
-  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
-  case $ac_top_srcdir in
-  .) ac_abs_top_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
-  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
-  esac;;
-esac
-
-
-  { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
-echo "$as_me: executing $ac_dest commands" >&6;}
-  case $ac_dest in
-    depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+  case $ac_file$ac_mode in
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
   # Strip MF so we end up with the name of the file.
   mf=`echo "$mf" | sed -e 's/:.*$//'`
   # Check whether this is an Automake generated Makefile or not.
@@ -21605,20 +21274,32 @@
   # some people rename them; so instead we look at the file content.
   # Grep'ing the first line is not enough: some people post-process
   # each Makefile.in and add a new line on top of each file to say so.
-  # So let's grep whole file.
-  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
-    dirpart=`(dirname "$mf") 2>/dev/null ||
+  # Grep'ing the whole file is not good either: AIX grep has a line
+  # limit of 2048, but all sed's we know have understand at least 4000.
+  if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
+    dirpart=`$as_dirname -- "$mf" ||
 $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 	 X"$mf" : 'X\(//\)[^/]' \| \
 	 X"$mf" : 'X\(//\)$' \| \
-	 X"$mf" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
 echo X"$mf" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
   else
     continue
   fi
@@ -21640,53 +21321,79 @@
        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
     # Make sure the directory exists.
     test -f "$dirpart/$file" && continue
-    fdir=`(dirname "$file") 2>/dev/null ||
+    fdir=`$as_dirname -- "$file" ||
 $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 	 X"$file" : 'X\(//\)[^/]' \| \
 	 X"$file" : 'X\(//\)$' \| \
-	 X"$file" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
 echo X"$file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-    { if $as_mkdir_p; then
-    mkdir -p $dirpart/$fdir
-  else
-    as_dir=$dirpart/$fdir
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    { as_dir=$dirpart/$fdir
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
     as_dirs=
-    while test ! -d "$as_dir"; do
-      as_dirs="$as_dir $as_dirs"
-      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
 $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 	 X"$as_dir" : 'X\(//\)[^/]' \| \
 	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
 echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
     done
-    test ! -n "$as_dirs" || mkdir $as_dirs
-  fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
-echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
    { (exit 1); exit 1; }; }; }
-
     # echo "creating $dirpart/$file"
     echo '# dummy' > "$dirpart/$file"
   done
 done
  ;;
+
   esac
-done
-_ACEOF
+done # for ac_tag
 
-cat >>$CONFIG_STATUS <<\_ACEOF
 
 { (exit 0); exit 0; }
 _ACEOF

Modified: openldap/trunk/contrib/ldapc++/configure.in
===================================================================
--- openldap/trunk/contrib/ldapc++/configure.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/configure.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -8,8 +8,9 @@
 dnl define([AC_CACHE_LOAD], )
 dnl define([AC_CACHE_SAVE], )
 
-AC_INIT(examples/main.cpp)
-AM_INIT_AUTOMAKE(main, 0.0.1)
+AC_INIT(ldapcpplib, 0.0.5)
+AC_CONFIG_SRCDIR(src/LDAPConnection.h)
+AM_INIT_AUTOMAKE(foreign)
 AM_CONFIG_HEADER(src/config.h)
 
 
@@ -23,7 +24,7 @@
 dnl AC_PROG_MAKE_SET
 AC_ARG_ENABLE(debug,[  --enable-debug],[
 	CXXFLAGS="-g -O0 -Wall"
-    AC_DEFINE(WITH_DEBUG)
+    AC_DEFINE(WITH_DEBUG,[],[Define to 1 ot enable debug logging])
 	],[
 	CXXFLAGS="-O0"
     ]

Modified: openldap/trunk/contrib/ldapc++/depcomp
===================================================================
--- openldap/trunk/contrib/ldapc++/depcomp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/depcomp	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,8 +1,10 @@
 #! /bin/sh
-
 # depcomp - compile a program generating dependencies as side-effects
-# Copyright 1999, 2000 Free Software Foundation, Inc.
 
+scriptversion=2005-07-09.11
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2, or (at your option)
@@ -15,8 +17,8 @@
 
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -25,22 +27,45 @@
 
 # Originally written by Alexandre Oliva <oliva at dcc.unicamp.br>.
 
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
 if test -z "$depmode" || test -z "$source" || test -z "$object"; then
   echo "depcomp: Variables source, object and depmode must be set" 1>&2
   exit 1
 fi
-# `libtool' can also be set to `yes' or `no'.
 
-if test -z "$depfile"; then
-   base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
-   dir=`echo "$object" | sed 's,/.*$,/,'`
-   if test "$dir" = "$object"; then
-      dir=
-   fi
-   # FIXME: should be _deps on DOS.
-   depfile="$dir.deps/$base"
-fi
-
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
 tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
 
 rm -f "$tmpdepfile"
@@ -172,19 +197,25 @@
 
 aix)
   # The C for AIX Compiler uses -M and outputs the dependencies
-  # in a .u file.  This file always lives in the current directory.
-  # Also, the AIX compiler puts `$object:' at the start of each line;
-  # $object doesn't have directory information.
-  stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
   tmpdepfile="$stripped.u"
-  outname="$stripped.o"
   if test "$libtool" = yes; then
     "$@" -Wc,-M
   else
     "$@" -M
   fi
+  stat=$?
 
-  stat=$?
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
   if test $stat -eq 0; then :
   else
     rm -f "$tmpdepfile"
@@ -192,6 +223,7 @@
   fi
 
   if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
     # Each line is of the form `foo.o: dependent.h'.
     # Do two passes, one to just change these to
     # `$object: dependent.h' and one to simply `dependent.h:'.
@@ -206,6 +238,44 @@
   rm -f "$tmpdepfile"
   ;;
 
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
 tru64)
    # The Tru64 compiler uses -MD to generate dependencies as a side
    # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
@@ -217,31 +287,47 @@
    base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
 
    if test "$libtool" = yes; then
-      tmpdepfile1="$dir.libs/$base.lo.d"
-      tmpdepfile2="$dir.libs/$base.d"
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mecanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
       "$@" -Wc,-MD
    else
-      tmpdepfile1="$dir$base.o.d"
-      tmpdepfile2="$dir$base.d"
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
       "$@" -MD
    fi
 
    stat=$?
    if test $stat -eq 0; then :
    else
-      rm -f "$tmpdepfile1" "$tmpdepfile2"
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
       exit $stat
    fi
 
-   if test -f "$tmpdepfile1"; then
-      tmpdepfile="$tmpdepfile1"
-   else
-      tmpdepfile="$tmpdepfile2"
-   fi
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
    if test -f "$tmpdepfile"; then
       sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
-      # That's a space and a tab in the [].
-      sed -e 's,^.*\.[a-z]*:[ 	]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
    else
       echo "#dummy" > "$depfile"
    fi
@@ -254,7 +340,7 @@
 
 dashmstdout)
   # Important note: in order to support this mode, a compiler *must*
-  # always write the proprocessed file to stdout, regardless of -o.
+  # always write the preprocessed file to stdout, regardless of -o.
   "$@" || exit $?
 
   # Remove the call to Libtool.
@@ -265,9 +351,7 @@
     shift
   fi
 
-  # Remove `-o $object'.  We will use -o /dev/null later,
-  # however we can't do the remplacement now because
-  # `-o $object' might simply not be used
+  # Remove `-o $object'.
   IFS=" "
   for arg
   do
@@ -287,7 +371,11 @@
   done
 
   test -z "$dashmflag" && dashmflag=-M
-  "$@" -o /dev/null $dashmflag | sed 's:^[^:]*\:[ 	]*:'"$object"'\: :' > "$tmpdepfile"
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
   rm -f "$depfile"
   cat < "$tmpdepfile" > "$depfile"
   tr ' ' '
@@ -306,6 +394,13 @@
 
 makedepend)
   "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
   # X makedepend
   shift
   cleared=no
@@ -318,7 +413,9 @@
     case "$arg" in
     -D*|-I*)
       set fnord "$@" "$arg"; shift ;;
-    -*)
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
       ;;
     *)
       set fnord "$@" "$arg"; shift ;;
@@ -339,7 +436,7 @@
 
 cpp)
   # Important note: in order to support this mode, a compiler *must*
-  # always write the proprocessed file to stdout.
+  # always write the preprocessed file to stdout.
   "$@" || exit $?
 
   # Remove the call to Libtool.
@@ -370,7 +467,8 @@
   done
 
   "$@" -E |
-    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
     sed '$ s: \\$::' > "$tmpdepfile"
   rm -f "$depfile"
   echo "$object : \\" > "$depfile"
@@ -381,7 +479,7 @@
 
 msvisualcpp)
   # Important note: in order to support this mode, a compiler *must*
-  # always write the proprocessed file to stdout, regardless of -o,
+  # always write the preprocessed file to stdout, regardless of -o,
   # because we must use -o when running libtool.
   "$@" || exit $?
   IFS=" "
@@ -421,3 +519,12 @@
 esac
 
 exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:

Modified: openldap/trunk/contrib/ldapc++/examples/Makefile.am
===================================================================
--- openldap/trunk/contrib/ldapc++/examples/Makefile.am	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/examples/Makefile.am	2007-12-15 10:25:31 UTC (rev 892)
@@ -2,10 +2,14 @@
 # Copyright 2003, OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 ##
-noinst_PROGRAMS = main readSchema
+AM_CPPFLAGS = -I$(top_srcdir)/src
+noinst_PROGRAMS = main readSchema urlTest
 
 main_SOURCES = main.cpp
 main_LDADD = ../src/libldapcpp.la
 
 readSchema_SOURCES = readSchema.cpp
 readSchema_LDADD = ../src/libldapcpp.la
+
+urlTest_SOURCES = urlTest.cpp
+urlTest_LDADD = ../src/libldapcpp.la

Modified: openldap/trunk/contrib/ldapc++/examples/Makefile.in
===================================================================
--- openldap/trunk/contrib/ldapc++/examples/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/examples/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# Makefile.in generated by automake 1.10 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -14,15 +14,11 @@
 
 @SET_MAKE@
 
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
 install_sh_SCRIPT = $(install_sh) -c
@@ -36,14 +32,14 @@
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-noinst_PROGRAMS = main$(EXEEXT) readSchema$(EXEEXT)
+noinst_PROGRAMS = main$(EXEEXT) readSchema$(EXEEXT) urlTest$(EXEEXT)
 subdir = examples
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/src/config.h
 CONFIG_CLEAN_FILES =
 PROGRAMS = $(noinst_PROGRAMS)
@@ -53,25 +49,28 @@
 am_readSchema_OBJECTS = readSchema.$(OBJEXT)
 readSchema_OBJECTS = $(am_readSchema_OBJECTS)
 readSchema_DEPENDENCIES = ../src/libldapcpp.la
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src
+am_urlTest_OBJECTS = urlTest.$(OBJEXT)
+urlTest_OBJECTS = $(am_urlTest_OBJECTS)
+urlTest_DEPENDENCIES = ../src/libldapcpp.la
+DEFAULT_INCLUDES = -I. -I$(top_builddir)/src at am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
 CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(main_SOURCES) $(readSchema_SOURCES)
-DIST_SOURCES = $(main_SOURCES) $(readSchema_SOURCES)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(main_SOURCES) $(readSchema_SOURCES) $(urlTest_SOURCES)
+DIST_SOURCES = $(main_SOURCES) $(readSchema_SOURCES) \
+	$(urlTest_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
@@ -98,6 +97,8 @@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FFLAGS = @FFLAGS@
+GREP = @GREP@
+INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -109,6 +110,7 @@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -118,20 +120,18 @@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
-ac_ct_AR = @ac_ct_AR@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
 ac_ct_F77 = @ac_ct_F77@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -143,32 +143,49 @@
 build_cpu = @build_cpu@
 build_os = @build_os@
 build_vendor = @build_vendor@
+builddir = @builddir@
 datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
 host_os = @host_os@
 host_vendor = @host_vendor@
+htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
 libdir = @libdir@
 libexecdir = @libexecdir@
+localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
+psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Copyright 2003, OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+AM_CPPFLAGS = -I$(top_srcdir)/src
 main_SOURCES = main.cpp
 main_LDADD = ../src/libldapcpp.la
 readSchema_SOURCES = readSchema.cpp
 readSchema_LDADD = ../src/libldapcpp.la
+urlTest_SOURCES = urlTest.cpp
+urlTest_LDADD = ../src/libldapcpp.la
 all: all-am
 
 .SUFFIXES:
@@ -211,10 +228,13 @@
 	done
 main$(EXEEXT): $(main_OBJECTS) $(main_DEPENDENCIES) 
 	@rm -f main$(EXEEXT)
-	$(CXXLINK) $(main_LDFLAGS) $(main_OBJECTS) $(main_LDADD) $(LIBS)
+	$(CXXLINK) $(main_OBJECTS) $(main_LDADD) $(LIBS)
 readSchema$(EXEEXT): $(readSchema_OBJECTS) $(readSchema_DEPENDENCIES) 
 	@rm -f readSchema$(EXEEXT)
-	$(CXXLINK) $(readSchema_LDFLAGS) $(readSchema_OBJECTS) $(readSchema_LDADD) $(LIBS)
+	$(CXXLINK) $(readSchema_OBJECTS) $(readSchema_LDADD) $(LIBS)
+urlTest$(EXEEXT): $(urlTest_OBJECTS) $(urlTest_DEPENDENCIES) 
+	@rm -f urlTest$(EXEEXT)
+	$(CXXLINK) $(urlTest_OBJECTS) $(urlTest_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -224,24 +244,25 @@
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/main.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/readSchema.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/urlTest.Po at am__quote@
 
 .cpp.o:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
 
 .cpp.obj:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .cpp.lo:
- at am__fastdepCXX_TRUE@	if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
@@ -252,10 +273,6 @@
 clean-libtool:
 	-rm -rf .libs _libs
 
-distclean-libtool:
-	-rm -f libtool
-uninstall-info-am:
-
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
@@ -305,22 +322,21 @@
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
 distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
 	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
 	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
 	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
 	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
 	    fi; \
@@ -368,7 +384,7 @@
 	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-libtool distclean-tags
+	distclean-tags
 
 dvi: dvi-am
 
@@ -382,12 +398,20 @@
 
 install-data-am:
 
+install-dvi: install-dvi-am
+
 install-exec-am:
 
+install-html: install-html-am
+
 install-info: install-info-am
 
 install-man:
 
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
@@ -408,19 +432,22 @@
 
 ps-am:
 
-uninstall-am: uninstall-info-am
+uninstall-am:
 
+.MAKE: install-am install-strip
+
 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
 	clean-libtool clean-noinstPROGRAMS ctags distclean \
 	distclean-compile distclean-generic distclean-libtool \
 	distclean-tags distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am install-exec \
-	install-exec-am install-info install-info-am install-man \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
 	install-strip installcheck installcheck-am installdirs \
 	maintainer-clean maintainer-clean-generic mostlyclean \
 	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-	pdf pdf-am ps ps-am tags uninstall uninstall-am \
-	uninstall-info-am
+	pdf pdf-am ps ps-am tags uninstall uninstall-am
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.

Modified: openldap/trunk/contrib/ldapc++/examples/main.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/examples/main.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/examples/main.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -3,8 +3,8 @@
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
-#include<iostream.h>
-#include<strstream>
+#include<iostream>
+#include<sstream>
 #include "LDAPConnection.h"
 #include "LDAPConstraints.h"
 #include "LDAPSearchReference.h"
@@ -25,13 +25,13 @@
     cons->setServerControls(ctrls);
     LDAPConnection *lc=new LDAPConnection("localhost",9009);
     lc->setConstraints(cons);
-    cout << "----------------------doing bind...." <<  endl;
+    std::cout << "----------------------doing bind...." << std::endl;
     try{
         lc->bind("cn=Manager,o=Organisation,c=DE" , "secret",cons);
-        cout << lc->getHost() << endl;    
+        std::cout << lc->getHost() << std::endl;    
         bool result = lc->compare("cn=Manager,o=Organisation,c=DE", 
                 LDAPAttribute("cn","Manaer"));
-        cout << "Compare: " << result << endl;
+        std::cout << "Compare: " << result << std::endl;
     
         LDAPAttributeList* attrs=new LDAPAttributeList();
         StringList values;
@@ -52,17 +52,17 @@
         if (entries != 0){
             LDAPEntry* entry = entries->getNext();
             if(entry != 0){
-                cout << *(entry) << endl;
+                std::cout << *(entry) << std::endl;
             }
             while(entry){
                 try{
                     entry = entries->getNext();
                     if(entry != 0){
-                        cout << *(entry) << endl;
+                        std::cout << *(entry) << std::endl;
                     }
                     delete entry;
                 }catch(LDAPReferralException e){
-                    cout << "Caught Referral" << endl;
+                    std::cout << "Caught Referral" << std::endl;
                 }
             }
         }
@@ -70,12 +70,12 @@
         lc->unbind();
         delete lc;
    }catch (LDAPException e){
-        cout << "------------------------- caught Exception ---------"<< endl;
-        cout << e << endl;
+        std::cout << "-------------- caught Exception ---------"<< std::endl;
+        std::cout << e << std::endl;
     }
 
     /*
-    cout << "--------------------starting search" << endl;
+    std::cout << "--------------------starting search" << std::endl;
     LDAPAttributeList* attrs=new LDAPAttributeList();
     StringList values;
     values.add("top");
@@ -105,28 +105,28 @@
                 case LDAP_RES_SEARCH_ENTRY :
                     res2= (LDAPSearchResult*)res;
                     entry=  res2->getEntry();
-                    cout << "Entry:            " << *entry << endl; 
+                    std::cout << "Entry:            " << *entry << std::endl; 
                     delete res;
                     res=q->getNext();
                 break;
                 case LDAP_RES_SEARCH_REFERENCE :
-                    cout << "Reference:         "  << endl;
+                    std::cout << "Reference:         "  << std::endl;
                     delete res;
                     res=q->getNext();
                 break;
                 default :
-                    cout << ( *(LDAPResult*) res) << endl;
+                    std::cout << ( *(LDAPResult*) res) << std::endl;
                     delete res;
-                    cout  << "-----------------search done" << endl;
+                    std::cout  << "-----------------search done" << std::endl;
                     cont=false;
                 break;
             }
         }
         delete q;
     }catch (LDAPException e){
-        cout << "----------------error during search" << endl;
+        std::cout << "----------------error during search" << std::endl;
         delete q;
-        cout << e << endl;
+        std::cout << e << std::endl;
     }
     lc->unbind();
     */

Modified: openldap/trunk/contrib/ldapc++/examples/readSchema.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/examples/readSchema.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/examples/readSchema.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
-#include<iostream.h>
-#include<strstream>
+#include<iostream>
+#include<sstream>
 #include "LDAPConnection.h"
 #include "LDAPConstraints.h"
 #include "LDAPSearchReference.h"
@@ -16,10 +16,10 @@
 
 int main(){
     LDAPConnection *lc=new LDAPConnection("192.168.3.128",389);
-    cout << "----------------------doing bind...." <<  endl;
+    std::cout << "----------------------doing bind...." <<  std::endl;
     try{
         lc->bind("uid=admin,dc=home,dc=local" , "secret");
-        cout << lc->getHost() << endl;
+        std::cout << lc->getHost() << std::endl;
         StringList tmp;
         tmp.add("subschemasubentry");
         LDAPSearchResults* entries = lc->search("", 
@@ -45,14 +45,14 @@
                 LDAPSchema schema;
                 schema.setObjectClasses((oc->getValues()));
                 LDAPObjClass test = schema.getObjectClassByName("inetOrgPerson");
-                cout << test.getDesc() << endl;
+                std::cout << test.getDesc() << std::endl;
 //                StringList mustAttr = test.getMay();
 //                for( StringList::const_iterator i = mustAttr.begin(); i != mustAttr.end(); i++ ){
-//                    cout << *i << endl;
+//                    std::cout << *i << std::endl;
 //                }
                 StringList sup = test.getSup();
                 for( StringList::const_iterator i = sup.begin(); i != sup.end(); i++ ){
-                    cout << *i << endl;
+                    std::cout << *i << std::endl;
                 }
             }
         }
@@ -60,8 +60,8 @@
         lc->unbind();
         delete lc;
    }catch (LDAPException e){
-        cout << "------------------------- caught Exception ---------"<< endl;
-        cout << e << endl;
+        std::cout << "---------------- caught Exception ---------"<< std::endl;
+        std::cout << e << std::endl;
     }
 
 }

Copied: openldap/trunk/contrib/ldapc++/examples/urlTest.cpp (from rev 891, openldap/vendor/openldap-2.4.7/contrib/ldapc++/examples/urlTest.cpp)
===================================================================
--- openldap/trunk/contrib/ldapc++/examples/urlTest.cpp	                        (rev 0)
+++ openldap/trunk/contrib/ldapc++/examples/urlTest.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,35 @@
+#include <LDAPUrl.h>
+#include <LDAPException.h>
+#include <cstdlib>
+#include <iostream>
+
+int main(int argc, char *argv[]) {
+    if ( argc != 2 ) {
+        std::cout << argc << std::endl;
+        std::cout << "urlTest <ldap-URI>" << std::endl;
+        exit(1);
+    }
+    std::string uristr = argv[1];
+    try {
+        LDAPUrl url(uristr);
+        std::cout << "Host: " << url.getHost() << std::endl;
+        std::cout << "Port: " << url.getPort() << std::endl;
+        std::cout << "BaseDN: " << url.getDN() << std::endl;
+        std::cout << "Scope: " << url.getScope() << std::endl;
+        StringList attrs = url.getAttrs();
+        std::cout << "Attrs: " << std::endl;
+        StringList::const_iterator i = attrs.begin();
+        for( ; i != attrs.end(); i++ ) {
+            std::cout << "    " << *i << std::endl;
+        }
+        std::cout << "Filter: " << url.getFilter() << std::endl;
+        std::cout << "Setting new BaseDN" << std::endl;
+        url.setDN("o=Beispiel, c=DE");
+        std::cout << "Url: " << url.getURLString() << std::endl;
+    } catch (LDAPUrlException e) {
+        std::cout << e.getCode() << std::endl;
+        std::cout << e.getErrorMessage() << std::endl;
+        std::cout << e.getAdditionalInfo() << std::endl;
+    }
+
+}

Modified: openldap/trunk/contrib/ldapc++/install-sh
===================================================================
--- openldap/trunk/contrib/ldapc++/install-sh	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/install-sh	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,20 +1,39 @@
 #!/bin/sh
-#
 # install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
+
+scriptversion=2005-05-14.22
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
 #
-# Copyright 1991 by the Massachusetts Institute of Technology
+# Copyright (C) 1994 X Consortium
 #
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission.  M.I.T. makes no representations about the
-# suitability of this software for any purpose.  It is provided "as is"
-# without express or implied warranty.
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
 #
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
 # Calling this script install-sh is preferred over install.sh, to prevent
 # `make' implicit rules from creating a file called install from it
 # when there is no Makefile.
@@ -23,13 +42,11 @@
 # from scratch.  It can only install one file at a time, a restriction
 # shared with many OS's install programs.
 
-
 # set DOITPROG to echo to test this script
 
 # Don't use :- since 4.3BSD and earlier shells don't like it.
 doit="${DOITPROG-}"
 
-
 # put in absolute paths if you don't have them in your path; or use env. vars.
 
 mvprog="${MVPROG-mv}"
@@ -41,211 +58,266 @@
 rmprog="${RMPROG-rm}"
 mkdirprog="${MKDIRPROG-mkdir}"
 
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
 chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
+chowncmd=
+chgrpcmd=
+stripcmd=
 rmcmd="$rmprog -f"
 mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
 
-while [ x"$1" != x ]; do
-    case $1 in
-	-c) instcmd="$cpprog"
-	    shift
-	    continue;;
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
 
-	-d) dir_arg=true
-	    shift
-	    continue;;
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
 
-	-m) chmodcmd="$chmodprog $2"
-	    shift
-	    shift
-	    continue;;
+Options:
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
 
-	-o) chowncmd="$chownprog $2"
-	    shift
-	    shift
-	    continue;;
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
 
-	-g) chgrpcmd="$chgrpprog $2"
-	    shift
-	    shift
-	    continue;;
+while test -n "$1"; do
+  case $1 in
+    -c) shift
+        continue;;
 
-	-s) stripcmd="$stripprog"
-	    shift
-	    continue;;
+    -d) dir_arg=true
+        shift
+        continue;;
 
-	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
-	    shift
-	    continue;;
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
 
-	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
-	    shift
-	    continue;;
+    --help) echo "$usage"; exit $?;;
 
-	*)  if [ x"$src" = x ]
-	    then
-		src=$1
-	    else
-		# this colon is to work around a 386BSD /bin/sh bug
-		:
-		dst=$1
-	    fi
-	    shift
-	    continue;;
-    esac
-done
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
 
-if [ x"$src" = x ]
-then
-	echo "install:	no input file specified"
-	exit 1
-else
-	true
-fi
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
 
-if [ x"$dir_arg" != x ]; then
-	dst=$src
-	src=""
-	
-	if [ -d $dst ]; then
-		instcmd=:
-		chmodcmd=""
-	else
-		instcmd=mkdir
-	fi
-else
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
 
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad 
-# if $src (and thus $dsttmp) contains '*'.
+    -t) dstarg=$2
+	shift
+	shift
+	continue;;
 
-	if [ -f $src -o -d $src ]
-	then
-		true
-	else
-		echo "install:  $src does not exist"
-		exit 1
-	fi
-	
-	if [ x"$dst" = x ]
-	then
-		echo "install:	no destination specified"
-		exit 1
-	else
-		true
-	fi
+    -T) no_target_directory=true
+	shift
+	continue;;
 
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
+    --version) echo "$0 $scriptversion"; exit $?;;
 
-	if [ -d $dst ]
-	then
-		dst="$dst"/`basename $src`
-	else
-		true
-	fi
+    *)  # When -d is used, all remaining arguments are directories to create.
+	# When -t is used, the destination is already specified.
+	test -n "$dir_arg$dstarg" && break
+        # Otherwise, the last argument is the destination.  Remove it from $@.
+	for arg
+	do
+          if test -n "$dstarg"; then
+	    # $@ is not empty: it contains at least $arg.
+	    set fnord "$@" "$dstarg"
+	    shift # fnord
+	  fi
+	  shift # arg
+	  dstarg=$arg
+	done
+	break;;
+  esac
+done
+
+if test -z "$1"; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
 fi
 
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
 
-# Make sure that the destination directory exists.
-#  this part is taken from Noah Friedman's mkinstalldirs script
+  if test -n "$dir_arg"; then
+    dst=$src
+    src=
 
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='	
-'
-IFS="${IFS-${defaultIFS}}"
+    if test -d "$dst"; then
+      mkdircmd=:
+      chmodcmd=
+    else
+      mkdircmd=$mkdirprog
+    fi
+  else
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
 
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
 
-pathcomp=''
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
 
-while [ $# -ne 0 ] ; do
-	pathcomp="${pathcomp}${1}"
-	shift
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dstarg: Is a directory" >&2
+	exit 1
+      fi
+      dst=$dst/`basename "$src"`
+    fi
+  fi
 
-	if [ ! -d "${pathcomp}" ] ;
-        then
-		$mkdirprog "${pathcomp}"
-	else
-		true
-	fi
+  # This sed command emulates the dirname command.
+  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
 
-	pathcomp="${pathcomp}/"
-done
-fi
+  # Make sure that the destination directory exists.
 
-if [ x"$dir_arg" != x ]
-then
-	$doit $instcmd $dst &&
+  # Skip lots of stat calls in the usual case.
+  if test ! -d "$dstdir"; then
+    defaultIFS='
+	 '
+    IFS="${IFS-$defaultIFS}"
 
-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
+    oIFS=$IFS
+    # Some sh's can't handle IFS=/ for some reason.
+    IFS='%'
+    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+    shift
+    IFS=$oIFS
 
-# If we're going to rename the final executable, determine the name now.
+    pathcomp=
 
-	if [ x"$transformarg" = x ] 
-	then
-		dstfile=`basename $dst`
-	else
-		dstfile=`basename $dst $transformbasename | 
-			sed $transformarg`$transformbasename
-	fi
+    while test $# -ne 0 ; do
+      pathcomp=$pathcomp$1
+      shift
+      if test ! -d "$pathcomp"; then
+        $mkdirprog "$pathcomp"
+	# mkdir can fail with a `File exist' error in case several
+	# install-sh are creating the directory concurrently.  This
+	# is OK.
+	test -d "$pathcomp" || exit
+      fi
+      pathcomp=$pathcomp/
+    done
+  fi
 
-# don't allow the sed command to completely eliminate the filename
+  if test -n "$dir_arg"; then
+    $doit $mkdircmd "$dst" \
+      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
 
-	if [ x"$dstfile" = x ] 
-	then
-		dstfile=`basename $dst`
-	else
-		true
-	fi
+  else
+    dstfile=`basename "$dst"`
 
-# Make a temp file name in the proper directory.
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
 
-	dsttmp=$dstdir/#inst.$$#
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+    trap '(exit $?); exit' 1 2 13 15
 
-# Move or copy the file name to the temp name
+    # Copy the file name to the temp name.
+    $doit $cpprog "$src" "$dsttmp" &&
 
-	$doit $instcmd $src $dsttmp &&
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
 
-	trap "rm -f ${dsttmp}" 0 &&
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+      || {
+	   # The rename failed, perhaps because mv can't rename something else
+	   # to itself, or perhaps because mv is so ancient that it does not
+	   # support -f.
 
-# and set any options; do chmod last to preserve setuid bits
+	   # Now remove or move aside any old file at destination location.
+	   # We try this two ways since rm can't unlink itself on some
+	   # systems and the destination file might be busy for other
+	   # reasons.  In this case, the final cleanup might fail but the new
+	   # file should still install successfully.
+	   {
+	     if test -f "$dstdir/$dstfile"; then
+	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+	       || {
+		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		 (exit 1); exit 1
+	       }
+	     else
+	       :
+	     fi
+	   } &&
 
-# If any of these fail, we abort the whole thing.  If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
+	   # Now rename the file to the real destination.
+	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+	 }
+    }
+  fi || { (exit 1); exit 1; }
+done
 
-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit 0
+}
 
-# Now rename the file to the real destination.
-
-	$doit $rmcmd -f $dstdir/$dstfile &&
-	$doit $mvcmd $dsttmp $dstdir/$dstfile 
-
-fi &&
-
-
-exit 0
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:

Modified: openldap/trunk/contrib/ldapc++/ltmain.sh
===================================================================
--- openldap/trunk/contrib/ldapc++/ltmain.sh	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/ltmain.sh	2007-12-15 10:25:31 UTC (rev 892)
@@ -43,8 +43,8 @@
 
 PROGRAM=ltmain.sh
 PACKAGE=libtool
-VERSION=1.5.18
-TIMESTAMP=" (1.1220.2.245 2005/05/16 08:55:27)"
+VERSION=1.5.22
+TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
 
 # See if we are running on zsh, and set the options which allow our
 # commands through without removal of \ escapes.
@@ -88,14 +88,15 @@
 Xsed="${SED}"' -e 1s/^X//'
 sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
 # test EBCDIC or ASCII
-case `echo A|tr A '\301'` in
- A) # EBCDIC based system
-  SP2NL="tr '\100' '\n'"
-  NL2SP="tr '\r\n' '\100\100'"
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  SP2NL='tr \040 \012'
+  NL2SP='tr \015\012 \040\040'
   ;;
- *) # Assume ASCII based system
-  SP2NL="tr '\040' '\012'"
-  NL2SP="tr '\015\012' '\040\040'"
+ *) # EBCDIC based system
+  SP2NL='tr \100 \n'
+  NL2SP='tr \r\n \100\100'
   ;;
 esac
 
@@ -131,14 +132,52 @@
 show="$echo"
 show_help=
 execute_dlfiles=
+duplicate_deps=no
+preserve_args=
 lo2o="s/\\.lo\$/.${objext}/"
 o2lo="s/\\.${objext}\$/.lo/"
-quote_scanset='[[~#^*{};<>?'"'"' 	]'
 
 #####################################
 # Shell function definitions:
 # This seems to be the best place for them
 
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+	# Failing that, at least try and use $RANDOM to avoid a race
+	my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+	save_mktempdir_umask=`umask`
+	umask 0077
+	$mkdir "$my_tmpdir"
+	umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || {
+        $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
+	exit $EXIT_FAILURE
+      }
+    fi
+
+    $echo "X$my_tmpdir" | $Xsed
+}
+
+
 # func_win32_libid arg
 # return the library type of file 'arg'
 #
@@ -157,12 +196,11 @@
     if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
       $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
       win32_nmres=`eval $NM -f posix -A $1 | \
-	sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'`
-      if test "X$win32_nmres" = "Ximport" ; then
-        win32_libid_type="x86 archive import"
-      else
-        win32_libid_type="x86 archive static"
-      fi
+	$SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
     fi
     ;;
   *DLL*)
@@ -192,7 +230,7 @@
       CC_quoted=
       for arg in $CC; do
 	case $arg in
-	  *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+	  *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	  arg="\"$arg\""
 	  ;;
 	esac
@@ -213,7 +251,7 @@
 	    for arg in $CC; do
 	    # Double-quote args containing other shell metacharacters.
 	    case $arg in
-	      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	      arg="\"$arg\""
 	      ;;
 	    esac
@@ -295,9 +333,9 @@
       $run ${rm}r "$my_xdir"
       $show "$mkdir $my_xdir"
       $run $mkdir "$my_xdir"
-      status=$?
-      if test "$status" -ne 0 && test ! -d "$my_xdir"; then
-	exit $status
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
+	exit $exit_status
       fi
       case $host in
       *-darwin*)
@@ -337,7 +375,7 @@
  	    func_extract_an_archive "$my_xdir" "$my_xabs"
 	  fi # $darwin_arches
 	fi # $run
-      ;;
+	;;
       *)
         func_extract_an_archive "$my_xdir" "$my_xabs"
         ;;
@@ -352,6 +390,8 @@
 # Darwin sucks
 eval std_shrext=\"$shrext_cmds\"
 
+disable_libs=no
+
 # Parse our command line options once, thoroughly.
 while test "$#" -gt 0
 do
@@ -468,7 +508,11 @@
     preserve_args="$preserve_args $arg"
     ;;
 
-  --tag) prevopt="--tag" prev=tag ;;
+  --tag)
+    prevopt="--tag"
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
   --tag=*)
     set tag "$optarg" ${1+"$@"}
     shift
@@ -500,6 +544,18 @@
   exit $EXIT_FAILURE
 fi
 
+case $disable_libs in
+no) 
+  ;;
+shared)
+  build_libtool_libs=no
+  build_old_libs=yes
+  ;;
+static)
+  build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+  ;;
+esac
+
 # If this variable is set in any of the actions, the command in it
 # will be execed at the end.  This prevents here-documents from being
 # left over by shells.
@@ -576,7 +632,7 @@
 
     for arg
     do
-      case "$arg_mode" in
+      case $arg_mode in
       arg  )
 	# do not "continue".  Instead, add this to base_compile
 	lastarg="$arg"
@@ -627,7 +683,7 @@
 	    # Many Bourne shells cannot handle close brackets correctly
 	    # in scan sets, so we specify it separately.
 	    case $arg in
-	      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	      arg="\"$arg\""
 	      ;;
 	    esac
@@ -662,7 +718,7 @@
       # in scan sets (worked around with variable expansion),
       # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
       # at all, so we specify them separately.
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	lastarg="\"$lastarg\""
 	;;
       esac
@@ -737,13 +793,12 @@
 
     qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
     case $qlibobj in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	qlibobj="\"$qlibobj\"" ;;
     esac
-    if test "X$libobj" != "X$qlibobj"; then
-	$echo "$modename: libobj name \`$libobj' may not contain shell special characters."
-	exit $EXIT_FAILURE
-    fi
+    test "X$libobj" != "X$qlibobj" \
+	&& $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' 	&()|`$[]' \
+	&& $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
     objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
     xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
     if test "X$xdir" = "X$obj"; then
@@ -824,7 +879,7 @@
     fi
     qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
     case $qsrcfile in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
       qsrcfile="\"$qsrcfile\"" ;;
     esac
 
@@ -857,9 +912,9 @@
       if test ! -d "${xdir}$objdir"; then
 	$show "$mkdir ${xdir}$objdir"
 	$run $mkdir ${xdir}$objdir
-	status=$?
-	if test "$status" -ne 0 && test ! -d "${xdir}$objdir"; then
-	  exit $status
+	exit_status=$?
+	if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
+	  exit $exit_status
 	fi
       fi
 
@@ -1062,6 +1117,7 @@
     no_install=no
     objs=
     non_pic_objects=
+    notinst_path= # paths that contain not-installed libtool libraries
     precious_files_regex=
     prefer_static_libs=no
     preload=no
@@ -1090,14 +1146,15 @@
 	  if test -n "$link_static_flag"; then
 	    dlopen_self=$dlopen_self_static
 	  fi
+	  prefer_static_libs=yes
 	else
 	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
 	    dlopen_self=$dlopen_self_static
 	  fi
+	  prefer_static_libs=built
 	fi
 	build_libtool_libs=no
 	build_old_libs=yes
-	prefer_static_libs=yes
 	break
 	;;
       esac
@@ -1111,7 +1168,7 @@
       arg="$1"
       shift
       case $arg in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
 	;;
       *) qarg=$arg ;;
@@ -1272,6 +1329,11 @@
 		  if test -z "$pic_object" || test "$pic_object" = none ; then
 		    arg="$non_pic_object"
 		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  non_pic_objects="$non_pic_objects $non_pic_object"
 		fi
 	      else
 		# Only an error if not doing a dry-run.
@@ -1355,8 +1417,8 @@
 	  prev=
 	  continue
 	  ;;
-        darwin_framework)
-	  compiler_flags="$compiler_flags $arg"
+	darwin_framework|darwin_framework_skip)
+	  test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
 	  compile_command="$compile_command $arg"
 	  finalize_command="$finalize_command $arg"
 	  prev=
@@ -1420,13 +1482,17 @@
 	continue
 	;;
 
-      -framework)
-        prev=darwin_framework
-        compiler_flags="$compiler_flags $arg"
+      -framework|-arch|-isysroot)
+	case " $CC " in
+	  *" ${arg} ${1} "* | *" ${arg}	${1} "*) 
+		prev=darwin_framework_skip ;;
+	  *) compiler_flags="$compiler_flags $arg"
+	     prev=darwin_framework ;;
+	esac
 	compile_command="$compile_command $arg"
 	finalize_command="$finalize_command $arg"
-        continue
-        ;;
+	continue
+	;;
 
       -inst-prefix-dir)
 	prev=inst_prefix
@@ -1454,7 +1520,8 @@
 	  absdir=`cd "$dir" && pwd`
 	  if test -z "$absdir"; then
 	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
-	    exit $EXIT_FAILURE
+	    absdir="$dir"
+	    notinst_path="$notinst_path $dir"
 	  fi
 	  dir="$absdir"
 	  ;;
@@ -1468,10 +1535,15 @@
 	esac
 	case $host in
 	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
 	  case :$dllsearchpath: in
 	  *":$dir:"*) ;;
 	  *) dllsearchpath="$dllsearchpath:$dir";;
 	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
 	  ;;
 	esac
 	continue
@@ -1480,11 +1552,11 @@
       -l*)
 	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
 	  case $host in
-	  *-*-cygwin* | *-*-pw32* | *-*-beos*)
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
 	    # These systems don't actually have a C or math library (as such)
 	    continue
 	    ;;
-	  *-*-mingw* | *-*-os2*)
+	  *-*-os2*)
 	    # These systems don't actually have a C library (as such)
 	    test "X$arg" = "X-lc" && continue
 	    ;;
@@ -1496,6 +1568,15 @@
 	    # Rhapsody C and math libraries are in the System framework
 	    deplibs="$deplibs -framework System"
 	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
 	  esac
 	elif test "X$arg" = "X-lc_r"; then
 	 case $host in
@@ -1537,21 +1618,24 @@
       # +DA*, +DD* enable 64-bit mode on the HP compiler
       # -q* pass through compiler args for the IBM compiler
       # -m* pass through architecture-specific compiler args for GCC
-      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*)
+      # -m*, -t[45]*, -txscale* pass through architecture-specific
+      # compiler args for GCC
+      # -pg pass through profiling flag for GCC
+      # @file GCC response files
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \
+      -t[45]*|-txscale*|@*)
 
 	# Unknown arguments in both finalize_command and compile_command need
 	# to be aesthetically quoted because they are evaled later.
 	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
 	case $arg in
-	*$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	  arg="\"$arg\""
 	  ;;
 	esac
         compile_command="$compile_command $arg"
         finalize_command="$finalize_command $arg"
-        if test "$with_gcc" = "yes" ; then
-          compiler_flags="$compiler_flags $arg"
-        fi
+        compiler_flags="$compiler_flags $arg"
         continue
         ;;
 
@@ -1659,7 +1743,7 @@
 	for flag in $args; do
 	  IFS="$save_ifs"
 	  case $flag in
-	    *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	    flag="\"$flag\""
 	    ;;
 	  esac
@@ -1677,7 +1761,7 @@
 	for flag in $args; do
 	  IFS="$save_ifs"
 	  case $flag in
-	    *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	    flag="\"$flag\""
 	    ;;
 	  esac
@@ -1710,7 +1794,7 @@
 	# to be aesthetically quoted because they are evaled later.
 	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
 	case $arg in
-	*$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	  arg="\"$arg\""
 	  ;;
 	esac
@@ -1789,6 +1873,11 @@
 	    if test -z "$pic_object" || test "$pic_object" = none ; then
 	      arg="$non_pic_object"
 	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    non_pic_objects="$non_pic_objects $non_pic_object"
 	  fi
 	else
 	  # Only an error if not doing a dry-run.
@@ -1844,7 +1933,7 @@
 	# to be aesthetically quoted because they are evaled later.
 	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
 	case $arg in
-	*$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	  arg="\"$arg\""
 	  ;;
 	esac
@@ -1894,9 +1983,9 @@
     if test ! -d "$output_objdir"; then
       $show "$mkdir $output_objdir"
       $run $mkdir $output_objdir
-      status=$?
-      if test "$status" -ne 0 && test ! -d "$output_objdir"; then
-	exit $status
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
+	exit $exit_status
       fi
     fi
 
@@ -1959,7 +2048,6 @@
     newlib_search_path=
     need_relink=no # whether we're linking any uninstalled libtool libraries
     notinst_deplibs= # not-installed libtool libraries
-    notinst_path= # paths that contain not-installed libtool libraries
     case $linkmode in
     lib)
 	passes="conv link"
@@ -2195,7 +2283,7 @@
 	esac # case $deplib
 	if test "$found" = yes || test -f "$lib"; then :
 	else
-	  $echo "$modename: cannot find the library \`$lib'" 1>&2
+	  $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
 	  exit $EXIT_FAILURE
 	fi
 
@@ -2409,7 +2497,7 @@
 	      case "$temp_rpath " in
 	      *" $dir "*) ;;
 	      *" $absdir "*) ;;
-	      *) temp_rpath="$temp_rpath $dir" ;;
+	      *) temp_rpath="$temp_rpath $absdir" ;;
 	      esac
 	    fi
 
@@ -2446,8 +2534,12 @@
 	fi
 
 	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes ; then
+	  use_static_libs=no
+	fi
 	if test -n "$library_names" &&
-	   { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
 	  if test "$installed" = no; then
 	    notinst_deplibs="$notinst_deplibs $lib"
 	    need_relink=yes
@@ -2560,11 +2652,15 @@
 	      if test "$hardcode_direct" = no; then
 		add="$dir/$linklib"
 		case $host in
-		  *-*-sco3.2v5* ) add_dir="-L$dir" ;;
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
 		  *-*-darwin* )
 		    # if the lib is a module then we can not link against
 		    # it, someone is ignoring the new warnings I added
-		    if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then
+		    if /usr/bin/file -L $add 2> /dev/null |
+                      $EGREP ": [^:]* bundle" >/dev/null ; then
 		      $echo "** Warning, lib $linklib is a module, not a shared library"
 		      if test -z "$old_library" ; then
 		        $echo
@@ -2595,7 +2691,7 @@
 		add_dir="-L$dir"
 		# Try looking first in the location we're being installed to.
 		if test -n "$inst_prefix_dir"; then
-		  case "$libdir" in
+		  case $libdir in
 		    [\\/]*)
 		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
 		      ;;
@@ -2668,7 +2764,7 @@
 	      add_dir="-L$libdir"
 	      # Try looking first in the location we're being installed to.
 	      if test -n "$inst_prefix_dir"; then
-		case "$libdir" in
+		case $libdir in
 		  [\\/]*)
 		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
 		    ;;
@@ -2729,8 +2825,6 @@
 	      fi
 	    fi
 	  else
-	    convenience="$convenience $dir/$old_library"
-	    old_convenience="$old_convenience $dir/$old_library"
 	    deplibs="$dir/$old_library $deplibs"
 	    link_static=yes
 	  fi
@@ -3317,9 +3411,9 @@
 
       # Eliminate all temporary directories.
       for path in $notinst_path; do
-	lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'`
-	deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'`
-	dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'`
+	lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
+	deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
+	dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
       done
 
       if test -n "$xrpath"; then
@@ -3372,8 +3466,13 @@
 	    ;;
 	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
 	    # Do not include libc due to us having libc/libc_r.
-	    test "X$arg" = "X-lc" && continue
 	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
  	  *)
 	    # Add libc to deplibs on all other systems if necessary.
 	    if test "$build_libtool_need_lc" = "yes"; then
@@ -3416,11 +3515,11 @@
 	  int main() { return 0; }
 EOF
 	  $rm conftest
-	  $LTCC -o conftest conftest.c $deplibs
+	  $LTCC $LTCFLAGS -o conftest conftest.c $deplibs
 	  if test "$?" -eq 0 ; then
 	    ldd_output=`ldd conftest`
 	    for i in $deplibs; do
-	      name="`expr $i : '-l\(.*\)'`"
+	      name=`expr $i : '-l\(.*\)'`
 	      # If $name is empty we are operating on a -L argument.
               if test "$name" != "" && test "$name" -ne "0"; then
 		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
@@ -3457,11 +3556,11 @@
 	    # Error occurred in the first compile.  Let's try to salvage
 	    # the situation: Compile a separate program for each library.
 	    for i in $deplibs; do
-	      name="`expr $i : '-l\(.*\)'`"
+	      name=`expr $i : '-l\(.*\)'`
 	      # If $name is empty we are operating on a -L argument.
               if test "$name" != "" && test "$name" != "0"; then
 		$rm conftest
-		$LTCC -o conftest conftest.c $i
+		$LTCC $LTCFLAGS -o conftest conftest.c $i
 		# Did it work?
 		if test "$?" -eq 0 ; then
 		  ldd_output=`ldd conftest`
@@ -3509,7 +3608,7 @@
 	  set dummy $deplibs_check_method
 	  file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
 	  for a_deplib in $deplibs; do
-	    name="`expr $a_deplib : '-l\(.*\)'`"
+	    name=`expr $a_deplib : '-l\(.*\)'`
 	    # If $name is empty we are operating on a -L argument.
             if test "$name" != "" && test  "$name" != "0"; then
 	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
@@ -3578,7 +3677,7 @@
 	  set dummy $deplibs_check_method
 	  match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
 	  for a_deplib in $deplibs; do
-	    name="`expr $a_deplib : '-l\(.*\)'`"
+	    name=`expr $a_deplib : '-l\(.*\)'`
 	    # If $name is empty we are operating on a -L argument.
 	    if test -n "$name" && test "$name" != "0"; then
 	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
@@ -3708,6 +3807,35 @@
 	deplibs=$newdeplibs
       fi
 
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
+
+
       # All the library-specific variables (install_libdir is set above).
       library_names=
       old_library=
@@ -3791,6 +3919,7 @@
 	fi
 
 	lib="$output_objdir/$realname"
+	linknames=
 	for link
 	do
 	  linknames="$linknames $link"
@@ -3819,6 +3948,9 @@
 	        # The command line is too long to execute in one step.
 	        $show "using reloadable object file for export list..."
 	        skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
 	      fi
 	    done
 	    IFS="$save_ifs"
@@ -3888,7 +4020,8 @@
 	  fi
 	fi
 
-	if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` &&
+	if test "X$skipped_export" != "X:" &&
+	   len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
 	   test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
 	  :
 	else
@@ -3923,7 +4056,7 @@
 	  do
 	    eval test_cmds=\"$reload_cmds $objlist $last_robj\"
 	    if test "X$objlist" = X ||
-	       { len=`expr "X$test_cmds" : ".*"` &&
+	       { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
 		 test "$len" -le "$max_cmd_len"; }; then
 	      objlist="$objlist $obj"
 	    else
@@ -4013,13 +4146,30 @@
 	  IFS="$save_ifs"
 	  eval cmd=\"$cmd\"
 	  $show "$cmd"
-	  $run eval "$cmd" || exit $?
+	  $run eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$mode" = relink; then
+	      $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+	    fi
+
+	    exit $lt_exit
+	  }
 	done
 	IFS="$save_ifs"
 
 	# Restore the uninstalled library and exit
 	if test "$mode" = relink; then
 	  $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      $show "${rm}r $gentop"
+	      $run ${rm}r "$gentop"
+	    fi
+	  fi
+
 	  exit $EXIT_SUCCESS
 	fi
 
@@ -4201,6 +4351,35 @@
         ;;
       esac
 
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
       compile_command="$compile_command $compile_deplibs"
       finalize_command="$finalize_command $finalize_deplibs"
 
@@ -4245,10 +4424,15 @@
 	fi
 	case $host in
 	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
 	  case :$dllsearchpath: in
 	  *":$libdir:"*) ;;
 	  *) dllsearchpath="$dllsearchpath:$libdir";;
 	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
 	  ;;
 	esac
       done
@@ -4364,11 +4548,23 @@
 	    if test -z "$export_symbols"; then
 	      export_symbols="$output_objdir/$outputname.exp"
 	      $run $rm $export_symbols
-	      $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+              case $host in
+              *cygwin* | *mingw* )
+	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+		$run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
 	    else
-	      $run eval "${SED} -e 's/\([ ][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
 	      $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
 	      $run eval 'mv "$nlist"T "$nlist"'
+              case $host in
+              *cygwin* | *mingw* )
+	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+		$run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
 	    fi
 	  fi
 
@@ -4485,16 +4681,29 @@
 	  esac
 
 	  # Now compile the dynamic symbol file.
-	  $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
-	  $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+	  $show "(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+	  $run eval '(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
 
 	  # Clean up the generated files.
 	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
 	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
 
 	  # Transform the symbol file into the correct name.
-	  compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
-	  finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+          case $host in
+          *cygwin* | *mingw* )
+            if test -f "$output_objdir/${outputname}.def" ; then
+              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+            else
+              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+             fi
+            ;;
+          * )
+            compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+            finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+            ;;
+          esac
 	  ;;
 	*)
 	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
@@ -4519,7 +4728,7 @@
 	# We have no uninstalled library dependencies, so finalize right now.
 	$show "$link_command"
 	$run eval "$link_command"
-	status=$?
+	exit_status=$?
 
 	# Delete the generated files.
 	if test -n "$dlsyms"; then
@@ -4527,7 +4736,7 @@
 	  $run $rm "$output_objdir/${outputname}S.${objext}"
 	fi
 
-	exit $status
+	exit $exit_status
       fi
 
       if test -n "$shlibpath_var"; then
@@ -4667,10 +4876,12 @@
 	esac
 	case $host in
 	  *cygwin* | *mingw* )
-	    cwrappersource=`$echo ${objdir}/lt-${outputname}.c`
-	    cwrapper=`$echo ${output}.exe`
-	    $rm $cwrappersource $cwrapper
-	    trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+            output_name=`basename $output`
+            output_path=`dirname $output`
+            cwrappersource="$output_path/$objdir/lt-$output_name.c"
+            cwrapper="$output_path/$output_name.exe"
+            $rm $cwrappersource $cwrapper
+            trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
 
 	    cat > $cwrappersource <<EOF
 
@@ -4695,6 +4906,9 @@
 #include <malloc.h>
 #include <stdarg.h>
 #include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
 
 #if defined(PATH_MAX)
 # define LT_PATHMAX PATH_MAX
@@ -4705,16 +4919,20 @@
 #endif
 
 #ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
 #endif
 
 #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
   defined (__OS2__)
-#define HAVE_DOS_BASED_FILE_SYSTEM
-#ifndef DIR_SEPARATOR_2
-#define DIR_SEPARATOR_2 '\\'
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
 #endif
-#endif
 
 #ifndef DIR_SEPARATOR_2
 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
@@ -4723,17 +4941,32 @@
         (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
 #endif /* DIR_SEPARATOR_2 */
 
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
 #define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
 #define XFREE(stale) do { \
   if (stale) { free ((void *) stale); stale = 0; } \
 } while (0)
 
+/* -DDEBUG is fairly common in CFLAGS.  */
+#undef DEBUG
+#if defined DEBUGWRAPPER
+# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
+#else
+# define DEBUG(format, ...)
+#endif
+
 const char *program_name = NULL;
 
 void * xmalloc (size_t num);
 char * xstrdup (const char *string);
-char * basename (const char *name);
-char * fnqualify(const char *path);
+const char * base_name (const char *name);
+char * find_executable(const char *wrapper);
+int    check_executable(const char *path);
 char * strendzap(char *str, const char *pat);
 void lt_fatal (const char *message, ...);
 
@@ -4743,29 +4976,51 @@
   char **newargz;
   int i;
 
-  program_name = (char *) xstrdup ((char *) basename (argv[0]));
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  DEBUG("(main) argv[0]      : %s\n",argv[0]);
+  DEBUG("(main) program_name : %s\n",program_name);
   newargz = XMALLOC(char *, argc+2);
 EOF
 
-	    cat >> $cwrappersource <<EOF
-  newargz[0] = "$SHELL";
+            cat >> $cwrappersource <<EOF
+  newargz[0] = (char *) xstrdup("$SHELL");
 EOF
 
-	    cat >> $cwrappersource <<"EOF"
-  newargz[1] = fnqualify(argv[0]);
+            cat >> $cwrappersource <<"EOF"
+  newargz[1] = find_executable(argv[0]);
+  if (newargz[1] == NULL)
+    lt_fatal("Couldn't find %s", argv[0]);
+  DEBUG("(main) found exe at : %s\n",newargz[1]);
   /* we know the script has the same name, without the .exe */
   /* so make sure newargz[1] doesn't end in .exe */
   strendzap(newargz[1],".exe");
   for (i = 1; i < argc; i++)
     newargz[i+1] = xstrdup(argv[i]);
   newargz[argc+1] = NULL;
+
+  for (i=0; i<argc+1; i++)
+  {
+    DEBUG("(main) newargz[%d]   : %s\n",i,newargz[i]);
+    ;
+  }
+
 EOF
 
-	    cat >> $cwrappersource <<EOF
+            case $host_os in
+              mingw*)
+                cat >> $cwrappersource <<EOF
+  execv("$SHELL",(char const **)newargz);
+EOF
+              ;;
+              *)
+                cat >> $cwrappersource <<EOF
   execv("$SHELL",newargz);
 EOF
+              ;;
+            esac
 
-	    cat >> $cwrappersource <<"EOF"
+            cat >> $cwrappersource <<"EOF"
+  return 127;
 }
 
 void *
@@ -4785,48 +5040,148 @@
 ;
 }
 
-char *
-basename (const char *name)
+const char *
+base_name (const char *name)
 {
   const char *base;
 
 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
   /* Skip over the disk name in MSDOS pathnames. */
-  if (isalpha (name[0]) && name[1] == ':')
+  if (isalpha ((unsigned char)name[0]) && name[1] == ':')
     name += 2;
 #endif
 
   for (base = name; *name; name++)
     if (IS_DIR_SEPARATOR (*name))
       base = name + 1;
-  return (char *) base;
+  return base;
 }
 
+int
+check_executable(const char * path)
+{
+  struct stat st;
+
+  DEBUG("(check_executable)  : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0) &&
+      (
+        /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
+#if defined (S_IXOTH)
+       ((st.st_mode & S_IXOTH) == S_IXOTH) ||
+#endif
+#if defined (S_IXGRP)
+       ((st.st_mode & S_IXGRP) == S_IXGRP) ||
+#endif
+       ((st.st_mode & S_IXUSR) == S_IXUSR))
+      )
+    return 1;
+  else
+    return 0;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise */
 char *
-fnqualify(const char *path)
+find_executable (const char* wrapper)
 {
-  size_t size;
-  char *p;
+  int has_slash = 0;
+  const char* p;
+  const char* p_next;
+  /* static buffer for getcwd */
   char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char* concat_name;
 
-  assert(path != NULL);
+  DEBUG("(find_executable)  : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
 
-  /* Is it qualified already? */
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  if (isalpha (path[0]) && path[1] == ':')
-    return xstrdup (path);
+  if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
+  {
+    concat_name = xstrdup (wrapper);
+    if (check_executable(concat_name))
+      return concat_name;
+    XFREE(concat_name);
+  }
+  else
+  {
 #endif
-  if (IS_DIR_SEPARATOR (path[0]))
-    return xstrdup (path);
+    if (IS_DIR_SEPARATOR (wrapper[0]))
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable(concat_name))
+        return concat_name;
+      XFREE(concat_name);
+    }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  }
+#endif
 
-  /* prepend the current directory */
-  /* doesn't handle '~' */
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+    {
+      has_slash = 1;
+      break;
+    }
+  if (!has_slash)
+  {
+    /* no slashes; search PATH */
+    const char* path = getenv ("PATH");
+    if (path != NULL)
+    {
+      for (p = path; *p; p = p_next)
+      {
+        const char* q;
+        size_t p_len;
+        for (q = p; *q; q++)
+          if (IS_PATH_SEPARATOR(*q))
+            break;
+        p_len = q - p;
+        p_next = (*q == '\0' ? q : q + 1);
+        if (p_len == 0)
+        {
+          /* empty path: current directory */
+          if (getcwd (tmp, LT_PATHMAX) == NULL)
+            lt_fatal ("getcwd failed");
+          tmp_len = strlen(tmp);
+          concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, tmp, tmp_len);
+          concat_name[tmp_len] = '/';
+          strcpy (concat_name + tmp_len + 1, wrapper);
+        }
+        else
+        {
+          concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, p, p_len);
+          concat_name[p_len] = '/';
+          strcpy (concat_name + p_len + 1, wrapper);
+        }
+        if (check_executable(concat_name))
+          return concat_name;
+        XFREE(concat_name);
+      }
+    }
+    /* not found in PATH; assume curdir */
+  }
+  /* Relative path | not found in path: prepend cwd */
   if (getcwd (tmp, LT_PATHMAX) == NULL)
     lt_fatal ("getcwd failed");
-  size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */
-  p = XMALLOC(char, size);
-  sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path);
-  return p;
+  tmp_len = strlen(tmp);
+  concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable(concat_name))
+    return concat_name;
+  XFREE(concat_name);
+  return NULL;
 }
 
 char *
@@ -4870,16 +5225,16 @@
   va_end (ap);
 }
 EOF
-	  # we should really use a build-platform specific compiler
-	  # here, but OTOH, the wrappers (shell script and this C one)
-	  # are only useful if you want to execute the "real" binary.
-	  # Since the "real" binary is built for $host, then this
-	  # wrapper might as well be built for $host, too.
-	  $run $LTCC -s -o $cwrapper $cwrappersource
-	  ;;
-	esac
-	$rm $output
-	trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
+          # we should really use a build-platform specific compiler
+          # here, but OTOH, the wrappers (shell script and this C one)
+          # are only useful if you want to execute the "real" binary.
+          # Since the "real" binary is built for $host, then this
+          # wrapper might as well be built for $host, too.
+          $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
+          ;;
+        esac
+        $rm $output
+        trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
 
 	$echo > $output "\
 #! $SHELL
@@ -5029,13 +5384,13 @@
 	# Backslashes separate directories on plain windows
 	*-*-mingw | *-*-os2*)
 	  $echo >> $output "\
-      exec \$progdir\\\\\$program \${1+\"\$@\"}
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
 "
 	  ;;
 
 	*)
 	  $echo >> $output "\
-      exec \$progdir/\$program \${1+\"\$@\"}
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
 "
 	  ;;
 	esac
@@ -5045,7 +5400,7 @@
     fi
   else
     # The program doesn't exist.
-    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
     \$echo \"This script is just a wrapper for \$program.\" 1>&2
     $echo \"See the $PACKAGE documentation for more information.\" 1>&2
     exit $EXIT_FAILURE
@@ -5109,9 +5464,9 @@
 	    $run ${rm}r "$gentop"
 	    $show "$mkdir $gentop"
 	    $run $mkdir "$gentop"
-	    status=$?
-	    if test "$status" -ne 0 && test ! -d "$gentop"; then
-	      exit $status
+	    exit_status=$?
+	    if test "$exit_status" -ne 0 && test ! -d "$gentop"; then
+	      exit $exit_status
 	    fi
 	  fi
 
@@ -5168,7 +5523,7 @@
 	    oldobjs="$objlist $obj"
 	    objlist="$objlist $obj"
 	    eval test_cmds=\"$old_archive_cmds\"
-	    if len=`expr "X$test_cmds" : ".*"` &&
+	    if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
 	       test "$len" -le "$max_cmd_len"; then
 	      :
 	    else
@@ -5365,11 +5720,11 @@
     # install_prog (especially on Windows NT).
     if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
        # Allow the use of GNU shtool's install command.
-       $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+       $echo "X$nonopt" | grep shtool > /dev/null; then
       # Aesthetically quote it.
       arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
       case $arg in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	arg="\"$arg\""
 	;;
       esac
@@ -5378,14 +5733,14 @@
       shift
     else
       install_prog=
-      arg="$nonopt"
+      arg=$nonopt
     fi
 
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
     arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
     case $arg in
-    *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
       arg="\"$arg\""
       ;;
     esac
@@ -5403,28 +5758,31 @@
     do
       if test -n "$dest"; then
 	files="$files $dest"
-	dest="$arg"
+	dest=$arg
 	continue
       fi
 
       case $arg in
       -d) isdir=yes ;;
-      -f) prev="-f" ;;
-      -g) prev="-g" ;;
-      -m) prev="-m" ;;
-      -o) prev="-o" ;;
+      -f) 
+      	case " $install_prog " in
+	*[\\\ /]cp\ *) ;;
+	*) prev=$arg ;;
+	esac
+	;;
+      -g | -m | -o) prev=$arg ;;
       -s)
 	stripme=" -s"
 	continue
 	;;
-      -*) ;;
-
+      -*)
+	;;
       *)
 	# If the previous option needed an argument, then skip it.
 	if test -n "$prev"; then
 	  prev=
 	else
-	  dest="$arg"
+	  dest=$arg
 	  continue
 	fi
 	;;
@@ -5433,7 +5791,7 @@
       # Aesthetically quote the argument.
       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
       case $arg in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
 	arg="\"$arg\""
 	;;
       esac
@@ -5602,11 +5960,14 @@
 
 	  if test "$#" -gt 0; then
 	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
 	    for linkname
 	    do
 	      if test "$linkname" != "$realname"; then
-		$show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
-		$run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+                $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+                $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
 	      fi
 	    done
 	  fi
@@ -5619,7 +5980,16 @@
 	    IFS="$save_ifs"
 	    eval cmd=\"$cmd\"
 	    $show "$cmd"
-	    $run eval "$cmd" || exit $?
+	    $run eval "$cmd" || {
+	      lt_exit=$?
+
+	      # Restore the uninstalled library and exit
+	      if test "$mode" = relink; then
+		$run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+	      fi
+
+	      exit $lt_exit
+	    }
 	  done
 	  IFS="$save_ifs"
 	fi
@@ -5713,17 +6083,15 @@
 	  notinst_deplibs=
 	  relink_command=
 
-	  # To insure that "foo" is sourced, and not "foo.exe",
-	  # finese the cygwin/MSYS system by explicitly sourcing "foo."
-	  # which disallows the automatic-append-.exe behavior.
-	  case $build in
-	  *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
-	  *) wrapperdot=${wrapper} ;;
-	  esac
+	  # Note that it is not necessary on cygwin/mingw to append a dot to
+	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
+	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+	  # `FILE.' does not work on cygwin managed mounts.
+	  #
 	  # If there is no directory component, then add one.
-	  case $file in
-	  */* | *\\*) . ${wrapperdot} ;;
-	  *) . ./${wrapperdot} ;;
+	  case $wrapper in
+	  */* | *\\*) . ${wrapper} ;;
+	  *) . ./${wrapper} ;;
 	  esac
 
 	  # Check the variables that should have been set.
@@ -5751,34 +6119,21 @@
 	  done
 
 	  relink_command=
-	  # To insure that "foo" is sourced, and not "foo.exe",
-	  # finese the cygwin/MSYS system by explicitly sourcing "foo."
-	  # which disallows the automatic-append-.exe behavior.
-	  case $build in
-	  *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
-	  *) wrapperdot=${wrapper} ;;
-	  esac
+	  # Note that it is not necessary on cygwin/mingw to append a dot to
+	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
+	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+	  # `FILE.' does not work on cygwin managed mounts.
+	  #
 	  # If there is no directory component, then add one.
-	  case $file in
-	  */* | *\\*) . ${wrapperdot} ;;
-	  *) . ./${wrapperdot} ;;
+	  case $wrapper in
+	  */* | *\\*) . ${wrapper} ;;
+	  *) . ./${wrapper} ;;
 	  esac
 
 	  outputname=
 	  if test "$fast_install" = no && test -n "$relink_command"; then
 	    if test "$finalize" = yes && test -z "$run"; then
-	      tmpdir="/tmp"
-	      test -n "$TMPDIR" && tmpdir="$TMPDIR"
-	      tmpdir="$tmpdir/libtool-$$"
-	      save_umask=`umask`
-	      umask 0077
-	      if $mkdir "$tmpdir"; then
-	        umask $save_umask
-	      else
-	        umask $save_umask
-		$echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
-		continue
-	      fi
+	      tmpdir=`func_mktempdir`
 	      file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
 	      outputname="$tmpdir/$file"
 	      # Replace the output file specification.
@@ -5802,7 +6157,7 @@
 	fi
 
 	# remove .exe since cygwin /usr/bin/install will append another
-	# one anyways
+	# one anyway 
 	case $install_prog,$host in
 	*/usr/bin/install*,*cygwin*)
 	  case $file:$destfile in
@@ -5902,7 +6257,7 @@
     # Exit here if they wanted silent mode.
     test "$show" = : && exit $EXIT_SUCCESS
 
-    $echo "----------------------------------------------------------------------"
+    $echo "X----------------------------------------------------------------------" | $Xsed
     $echo "Libraries have been installed in:"
     for libdir in $libdirs; do
       $echo "   $libdir"
@@ -5935,7 +6290,7 @@
     $echo
     $echo "See any operating system documentation about shared libraries for"
     $echo "more information, such as the ld(1) and ld.so(8) manual pages."
-    $echo "----------------------------------------------------------------------"
+    $echo "X----------------------------------------------------------------------" | $Xsed
     exit $EXIT_SUCCESS
     ;;
 
@@ -6152,9 +6507,17 @@
 	    rmfiles="$rmfiles $objdir/$n"
 	  done
 	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
-	  test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
 
-	  if test "$mode" = uninstall; then
+	  case "$mode" in
+	  clean)
+	    case "  $library_names " in
+	    # "  " in the beginning catches empty $dlname
+	    *" $dlname "*) ;;
+	    *) rmfiles="$rmfiles $objdir/$dlname" ;;
+	    esac
+	     test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+	    ;;
+	  uninstall)
 	    if test -n "$library_names"; then
 	      # Do each command in the postuninstall commands.
 	      cmds=$postuninstall_cmds
@@ -6187,7 +6550,8 @@
 	      IFS="$save_ifs"
 	    fi
 	    # FIXME: should reinstall the best remaining shared library.
-	  fi
+	    ;;
+	  esac
 	fi
 	;;
 
@@ -6486,12 +6850,11 @@
 # configuration.  But we'll never go from static-only to shared-only.
 
 # ### BEGIN LIBTOOL TAG CONFIG: disable-shared
-build_libtool_libs=no
-build_old_libs=yes
+disable_libs=shared
 # ### END LIBTOOL TAG CONFIG: disable-shared
 
 # ### BEGIN LIBTOOL TAG CONFIG: disable-static
-build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac`
+disable_libs=static
 # ### END LIBTOOL TAG CONFIG: disable-static
 
 # Local Variables:

Modified: openldap/trunk/contrib/ldapc++/missing
===================================================================
--- openldap/trunk/contrib/ldapc++/missing	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/missing	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,8 +1,12 @@
 #! /bin/sh
 # Common stub for a few missing GNU programs while installing.
-# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-# Franc,ois Pinard <pinard at iro.umontreal.ca>, 1996.
 
+scriptversion=2005-06-08.21
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2, or (at your option)
@@ -15,15 +19,47 @@
 
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
 
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
 if test $# -eq 0; then
   echo 1>&2 "Try \`$0 --help' for more information"
   exit 1
 fi
 
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
 case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
 
   -h|--h|--he|--hel|--help)
     echo "\
@@ -35,6 +71,7 @@
 Options:
   -h, --help      display this help and exit
   -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
 
 Supported PROGRAM values:
   aclocal      touch file \`aclocal.m4'
@@ -43,13 +80,19 @@
   automake     touch all \`Makefile.in' files
   bison        create \`y.tab.[ch]', if possible, from existing .[ch]
   flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
   lex          create \`lex.yy.c', if possible, from existing .c
   makeinfo     touch the output file
-  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake at gnu.org>."
+    exit $?
     ;;
 
   -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
-    echo "missing - GNU libit 0.0"
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
     ;;
 
   -*)
@@ -58,10 +101,45 @@
     exit 1
     ;;
 
-  aclocal)
+esac
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+  lex|yacc)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+  aclocal*)
     echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified \`acinclude.m4' or \`configure.in'.  You might want
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
          to install the \`Automake' and \`Perl' packages.  Grab them from
          any GNU archive site."
     touch aclocal.m4
@@ -69,8 +147,8 @@
 
   autoconf)
     echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified \`configure.in'.  You might want to install the
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
          \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
          archive site."
     touch configure
@@ -78,11 +156,11 @@
 
   autoheader)
     echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified \`acconfig.h' or \`configure.in'.  You might want
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
          to install the \`Autoconf' and \`GNU m4' packages.  Grab them
          from any GNU archive site."
-    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
     test -z "$files" && files="config.h"
     touch_files=
     for f in $files; do
@@ -95,10 +173,10 @@
     touch $touch_files
     ;;
 
-  automake)
+  automake*)
     echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
          You might want to install the \`Automake' and \`Perl' packages.
          Grab them from any GNU archive site."
     find . -type f -name Makefile.am -print |
@@ -106,9 +184,32 @@
 	   while read f; do touch "$f"; done
     ;;
 
+  autom4te)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
   bison|yacc)
     echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
+WARNING: \`$1' $msg.  You should only need it if
          you modified a \`.y' file.  You may need the \`Bison' package
          in order for those modifications to take effect.  You can get
          \`Bison' from any GNU archive site."
@@ -138,7 +239,7 @@
 
   lex|flex)
     echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
+WARNING: \`$1' is $msg.  You should only need it if
          you modified a \`.l' file.  You may need the \`Flex' package
          in order for those modifications to take effect.  You can get
          \`Flex' from any GNU archive site."
@@ -159,28 +260,90 @@
     fi
     ;;
 
+  help2man)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
   makeinfo)
     echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
+WARNING: \`$1' is $msg.  You should only need it if
          you modified a \`.texi' or \`.texinfo' file, or any other file
          indirectly affecting the aspect of the manual.  The spurious
          call might also be the consequence of using a buggy \`make' (AIX,
          DU, IRIX).  You might want to install the \`Texinfo' package or
          the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
     file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
     if test -z "$file"; then
-      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
-      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
     fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
     touch $file
     ;;
 
+  tar)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case "$firstarg" in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case "$firstarg" in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
   *)
     echo 1>&2 "\
-WARNING: \`$1' is needed, and you do not seem to have it handy on your
-         system.  You might have modified some files without having the
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
          proper tools for further handling them.  Check the \`README' file,
-         it often tells you about the needed prerequirements for installing
+         it often tells you about the needed prerequisites for installing
          this package.  You may also peek at any GNU archive site, in case
          some other package would contain this missing \`$1' program."
     exit 1
@@ -188,3 +351,10 @@
 esac
 
 exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:

Deleted: openldap/trunk/contrib/ldapc++/mkinstalldirs
===================================================================
--- openldap/trunk/contrib/ldapc++/mkinstalldirs	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/mkinstalldirs	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,39 +0,0 @@
-#! /bin/sh
-# mkinstalldirs --- make directory hierarchy
-# Author: Noah Friedman <friedman at prep.ai.mit.edu>
-# Created: 1993-05-16
-# Public domain
-
-
-errstatus=0
-
-for file
-do
-   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
-   shift
-
-   pathcomp=
-   for d
-   do
-     pathcomp="$pathcomp$d"
-     case "$pathcomp" in
-       -* ) pathcomp=./$pathcomp ;;
-     esac
-
-     if test ! -d "$pathcomp"; then
-        echo "mkdir $pathcomp"
-
-        mkdir "$pathcomp" || lasterr=$?
-
-        if test ! -d "$pathcomp"; then
-  	  errstatus=$lasterr
-        fi
-     fi
-
-     pathcomp="$pathcomp/"
-   done
-done
-
-exit $errstatus
-
-# mkinstalldirs ends here

Modified: openldap/trunk/contrib/ldapc++/src/LDAPAsynConnection.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPAsynConnection.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPAsynConnection.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000, OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2000-2006, OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -12,7 +12,6 @@
 #include "LDAPBindRequest.h"
 #include "LDAPCompareRequest.h"
 #include "LDAPDeleteRequest.h"
-#include "LDAPException.h"
 #include "LDAPExtRequest.h"
 #include "LDAPEntry.h"
 #include "LDAPModDNRequest.h"
@@ -49,19 +48,33 @@
     DEBUG(LDAP_DEBUG_TRACE | LDAP_DEBUG_PARAMETER,
             "   hostname:" << hostname << endl
             << "   port:" << port << endl);
-    std::ostringstream urlstream;
-    urlstream << "ldap://" + hostname << ":" << port;
-    std::string url = urlstream.str();
-    ldap_initialize(&cur_session, url.c_str());
-    m_host=hostname;
-    m_port=port;
+
+    m_uri.setScheme("ldap");
+    m_uri.setHost(hostname);
+    m_uri.setPort(port);
+    
+    const char *ldapuri = m_uri.getURLString().c_str();
+    int ret = ldap_initialize(&cur_session, ldapuri);
+    if ( ret != LDAP_SUCCESS ) {
+        throw LDAPException( ret );
+    }
     int opt=3;
     ldap_set_option(cur_session, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
     ldap_set_option(cur_session, LDAP_OPT_PROTOCOL_VERSION, &opt);
 }
 
+void LDAPAsynConnection::initialize(const std::string& uri){
+	m_uri.setURLString(uri);
+    int ret = ldap_initialize(&cur_session, m_uri.getURLString().c_str());
+    if ( ret != LDAP_SUCCESS ) {
+        throw LDAPException( ret );
+    }
+    int opt=3;
+    ldap_set_option(cur_session, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
+    ldap_set_option(cur_session, LDAP_OPT_PROTOCOL_VERSION, &opt);
+}
+
 void LDAPAsynConnection::start_tls(){
-    int resCode;
     if( ldap_start_tls_s( cur_session, NULL, NULL ) != LDAP_SUCCESS ) {
         throw LDAPException(this);
     }
@@ -241,12 +254,12 @@
 
 const string& LDAPAsynConnection::getHost() const{
     DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::setHost()" << endl);
-    return m_host;
+    return m_uri.getHost();
 }
 
 int LDAPAsynConnection::getPort() const{
     DEBUG(LDAP_DEBUG_TRACE,"LDAPAsynConnection::getPort()" << endl);
-    return m_port;
+    return m_uri.getPort();
 }
 
 LDAPAsynConnection* LDAPAsynConnection::referralConnect(

Modified: openldap/trunk/contrib/ldapc++/src/LDAPAsynConnection.h
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPAsynConnection.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPAsynConnection.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -13,6 +13,8 @@
 #include<ldap.h>
 #include<lber.h>
 
+#include <LDAPEntry.h>
+#include <LDAPException.h>
 #include <LDAPMessageQueue.h>
 #include <LDAPConstraints.h>
 #include <LDAPModification.h>
@@ -20,9 +22,6 @@
 #include <LDAPUrl.h>
 #include <LDAPUrlList.h>
 
-class LDAPEntry;
-class LDAPAttribute;
-
 //* Main class for an asynchronous LDAP connection 
 /**
  * This class represents an asynchronous connection to an LDAP-Server. It 
@@ -71,7 +70,7 @@
          *      this connection
          */
         LDAPAsynConnection(const std::string& hostname=std::string("localhost"),
-                int port=389, LDAPConstraints *cons=new LDAPConstraints() );
+                int port=0, LDAPConstraints *cons=new LDAPConstraints() );
 
         //* Destructor
         virtual ~LDAPAsynConnection();
@@ -90,6 +89,15 @@
         void init(const std::string& hostname, int port);
 
         /**
+         * Initializes a connection to a server. 
+         * 
+         * There actually no communication to the server. Just the
+         * object is initialized 
+         * @param uri  The LDAP-Uri for the destination
+         */ 
+        void initialize(const std::string& uri);
+
+        /**
          * Start TLS on this connection.  This isn't in the constructor,
          * because it could fail (i.e. server doesn't have SSL cert, client
          * api wasn't compiled against OpenSSL, etc.). 
@@ -307,15 +315,10 @@
         LDAPConstraints *m_constr;
 
         /**
-         * The name of the destination host
+         * The URI of this connection
          */
-        std::string m_host;
+        LDAPUrl m_uri;
 
-        /**
-         * The port the destination server is running on.
-         */
-        int m_port;
-
  protected:
         /**
          * Is caching enabled?

Modified: openldap/trunk/contrib/ldapc++/src/LDAPAttrType.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPAttrType.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPAttrType.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -15,6 +15,7 @@
     desc = string ();
     names = StringList ();
     single = false;
+    usage = 0;
 }
 
 LDAPAttrType::LDAPAttrType (const LDAPAttrType &at){
@@ -25,6 +26,7 @@
     desc = at.desc;
     names = at.names;
     single = at.single;
+    usage = at.usage;
 }
 
 LDAPAttrType::LDAPAttrType (string at_item) { 
@@ -38,10 +40,11 @@
     a = ldap_str2attributetype (at_item.c_str(), &ret, &errp,SCHEMA_PARSE_FLAG);
 
     if (a) {
-	this->setNames (a->at_names);
-	this->setDesc (a->at_desc);
-	this->setOid (a->at_oid);
-	this->setSingle (a->at_single_value);
+	this->setNames( a->at_names );
+	this->setDesc( a->at_desc );
+	this->setOid( a->at_oid );
+	this->setSingle( a->at_single_value );
+	this->setUsage( a->at_usage );
     }
     // else? -> error
 }
@@ -70,6 +73,10 @@
 	oid = at_oid;
 }
 
+void LDAPAttrType::setUsage (int at_usage) {
+    usage = at_usage;
+}
+
 bool LDAPAttrType::isSingle () {
     return single;
 }
@@ -93,3 +100,7 @@
     else
 	return *(names.begin());
 }
+
+int LDAPAttrType::getUsage () {
+    return usage;
+}

Modified: openldap/trunk/contrib/ldapc++/src/LDAPAttrType.h
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPAttrType.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPAttrType.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -24,6 +24,7 @@
 	StringList names;
 	string desc, oid;
 	bool single;
+	int usage;
 	
     public :
 
@@ -74,15 +75,22 @@
 	StringList getNames();
 	
 	/**
-	 * Returns true if attribute type hllows only single value
+	 * Returns true if attribute type allows only single value
 	 */
 	bool isSingle();
 	
+	/**
+ 	 * Return the 'usage' value:
+ 	 * (0=userApplications, 1=directoryOperation, 2=distributedOperation, 
+	 *  3=dSAOperation)
+ 	 */
+ 	int getUsage ();
+
 	void setNames (char **at_names);
 	void setDesc (char *at_desc);
 	void setOid (char *at_oid);
 	void setSingle (int at_single_value);
-	
+	void setUsage (int at_usage );
 };
 
 #endif // LDAP_ATTRTYPE_H

Modified: openldap/trunk/contrib/ldapc++/src/LDAPAttribute.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPAttribute.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPAttribute.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -12,7 +12,7 @@
 
 
 #include <ldap.h> 
-//#include <ctype.h>
+#include <cstdlib>
 
 #include "debug.h"
 #include "StringList.h"

Modified: openldap/trunk/contrib/ldapc++/src/LDAPAttributeList.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPAttributeList.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPAttributeList.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -13,6 +13,8 @@
 #include "LDAPAsynConnection.h"
 #include "LDAPMessage.h"
 
+#include <cstdlib>
+
 using namespace std;
 
 // little helper function for doing case insensitve string comparison

Modified: openldap/trunk/contrib/ldapc++/src/LDAPBindRequest.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPBindRequest.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPBindRequest.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -10,6 +10,8 @@
 #include "LDAPBindRequest.h"
 #include "LDAPException.h"
 
+#include <cstdlib>
+
 using namespace std;
 
 LDAPBindRequest::LDAPBindRequest(const LDAPBindRequest& req) :

Modified: openldap/trunk/contrib/ldapc++/src/LDAPEntry.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPEntry.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPEntry.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -7,6 +7,7 @@
 #include "debug.h"
 #include "LDAPEntry.h"
 
+#include "LDAPAsynConnection.h"
 #include "LDAPException.h"
 
 using namespace std;

Modified: openldap/trunk/contrib/ldapc++/src/LDAPEntry.h
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPEntry.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPEntry.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -8,9 +8,10 @@
 #define LDAP_ENTRY_H
 #include <ldap.h>
 
-#include <LDAPAsynConnection.h>
 #include <LDAPAttributeList.h>
 
+class LDAPAsynConnection;
+
 /**
  * This class is used to store every kind of LDAP Entry.
  */

Modified: openldap/trunk/contrib/ldapc++/src/LDAPException.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPException.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPException.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -22,7 +22,7 @@
 
 LDAPException::LDAPException(const LDAPAsynConnection *lc){
     LDAP *l = lc->getSessionHandle();
-    ldap_get_option(l,LDAP_OPT_ERROR_NUMBER,&m_res_code);
+    ldap_get_option(l,LDAP_OPT_RESULT_CODE,&m_res_code);
     const char *res_cstring = ldap_err2string(m_res_code);
     if ( res_cstring ) {
         m_res_string = string(res_cstring);
@@ -30,11 +30,16 @@
         m_res_string = "";
     }
     const char* err_string;
+
+#ifdef LDAP_OPT_DIAGNOSTIC_MESSAGE
+    ldap_get_option(l,LDAP_OPT_DIAGNOSTIC_MESSAGE ,&err_string);
+#else
     ldap_get_option(l,LDAP_OPT_ERROR_STRING,&err_string);
+#endif
     if ( err_string ) {
-        m_res_string = string(err_string);
+        m_err_string = string(err_string);
     } else {
-        m_res_string = "";
+        m_err_string = "";
     }
 }
 

Modified: openldap/trunk/contrib/ldapc++/src/LDAPException.h
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPException.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPException.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -18,14 +18,15 @@
  */
 class LDAPException{
 		
-	public :
+    public :
         /**
          * Constructs a LDAPException-object from the parameters
          * @param res_code A valid LDAP result code.
          * @param err_string    An addional error message for the error
          *                      that happend (optional)
          */
-		LDAPException(int res_code, const std::string& err_string=std::string());
+        LDAPException(int res_code, 
+                const std::string& err_string=std::string());
 		
         /**
          * Constructs a LDAPException-object from the error state of a
@@ -43,14 +44,13 @@
         /**
          * @return The Result code of the object
          */
-        
-		int getResultCode() const;
+        int getResultCode() const;
 
         /**
          * @return The error message that is corresponding to the result
          *          code .
          */
-		const std::string& getResultMsg() const;
+        const std::string& getResultMsg() const;
         
         /**
          * @return The addional error message of the error (if it was set)
@@ -61,11 +61,11 @@
          * This method can be used to dump the data of a LDAPResult-Object.
          * It is only useful for debugging purposes at the moment
          */
-		friend std::ostream& operator << (std::ostream &s, LDAPException e);
+        friend std::ostream& operator << (std::ostream &s, LDAPException e);
 
-	private :
-		int m_res_code;
-		std::string m_res_string;
-		std::string m_err_string;
+    private :
+        int m_res_code;
+        std::string m_res_string;
+        std::string m_err_string;
 };
 #endif //LDAP_EXCEPTION_H

Modified: openldap/trunk/contrib/ldapc++/src/LDAPExtRequest.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPExtRequest.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPExtRequest.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -12,6 +12,8 @@
 #include "LDAPException.h"
 #include "LDAPResult.h"
 
+#include <cstdlib>
+
 using namespace std;
 
 LDAPExtRequest::LDAPExtRequest(const LDAPExtRequest& req) :

Modified: openldap/trunk/contrib/ldapc++/src/LDAPMessageQueue.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPMessageQueue.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPMessageQueue.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -10,7 +10,6 @@
 #include "LDAPMessageQueue.h"
 #include "LDAPRequest.h"
 #include "LDAPAsynConnection.h"
-#include "LDAPMessage.h"
 #include "LDAPResult.h"
 #include "LDAPSearchReference.h"
 #include "LDAPSearchRequest.h"
@@ -150,7 +149,7 @@
 // TODO Maybe moved to LDAPRequest::followReferral seems more reasonable
 //there
 LDAPRequest* LDAPMessageQueue::chaseReferral(LDAPMsg* ref){
-    DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::chaseReferra()" << endl);
+    DEBUG(LDAP_DEBUG_TRACE,"LDAPMessageQueue::chaseReferral()" << endl);
     LDAPRequest *req=m_activeReq.top();
     LDAPRequest *refReq=req->followReferral(ref);
     if(refReq !=0){

Modified: openldap/trunk/contrib/ldapc++/src/LDAPMessageQueue.h
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPMessageQueue.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPMessageQueue.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -10,9 +10,9 @@
 #include <stack>
 
 #include <LDAPUrlList.h>
+#include <LDAPMessage.h>
 
 class LDAPAsynConnection;
-class LDAPMsg;
 class LDAPRequest;
 class LDAPSearchRequest;
 class LDAPUrl;

Modified: openldap/trunk/contrib/ldapc++/src/LDAPModList.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPModList.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPModList.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -7,6 +7,8 @@
 #include "LDAPModList.h"
 #include "debug.h"
 
+#include <cstdlib>
+
 using namespace std;
 
 LDAPModList::LDAPModList(){

Modified: openldap/trunk/contrib/ldapc++/src/LDAPResult.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPResult.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPResult.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -10,6 +10,8 @@
 #include "LDAPRequest.h"
 #include "LDAPException.h"
 
+#include <cstdlib>
+
 using namespace std;
 
 LDAPResult::LDAPResult(const LDAPRequest *req, LDAPMessage *msg) : 

Modified: openldap/trunk/contrib/ldapc++/src/LDAPUrl.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPUrl.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPUrl.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,74 +1,495 @@
 /*
- * Copyright 2000, OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2000-2006, OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 #include "LDAPUrl.h"
-
-#include <ldap.h>
+#include <sstream>
 #include "debug.h"
 
 using namespace std;
 
-LDAPUrl::LDAPUrl(const char *url){
+#define PCT_ENCFLAG_NONE 0x0000U
+#define PCT_ENCFLAG_COMMA 0x0001U
+#define PCT_ENCFLAG_SLASH 0x0002U
+
+#define LDAP_DEFAULT_PORT 389
+#define LDAPS_DEFAULT_PORT 636
+
+LDAPUrl::LDAPUrl(const std::string &url)
+{
     DEBUG(LDAP_DEBUG_CONSTRUCT, "LDAPUrl::LDAPUrl()" << endl);
     DEBUG(LDAP_DEBUG_CONSTRUCT | LDAP_DEBUG_PARAMETER,
             "   url:" << url << endl);
-    if (ldap_is_ldap_url(url)){
-        LDAPURLDesc *urlDesc;
-        ldap_url_parse(url, &urlDesc);
-        if(urlDesc->lud_host){
-            m_Host = string(urlDesc->lud_host);
-        }
-        m_Port = urlDesc->lud_port;
-        if(urlDesc->lud_dn){
-            m_DN = string(urlDesc->lud_dn);
-        }
-        m_Attrs = StringList(urlDesc->lud_attrs);
-        m_Scope = urlDesc->lud_scope;
-        if(urlDesc->lud_filter){
-            m_Filter = string(urlDesc->lud_filter);
-        }else{
-            m_Filter = "";
-        }
-        m_urlString= string(url);
-        ldap_free_urldesc(urlDesc);
-    }else{
-        DEBUG(LDAP_DEBUG_TRACE,"   noUrl:" << url << endl);
+    m_urlString = url;
+    m_Filter = "";
+    m_Scheme = "ldap";
+    m_Scope = 0;
+    m_Port = 0;
+    regenerate = false;
+    if (url != "") {
+        this->parseUrl();
     }
 }
 
-LDAPUrl::~LDAPUrl(){
+LDAPUrl::~LDAPUrl()
+{
     DEBUG(LDAP_DEBUG_DESTROY, "LDAPUrl::~LDAPUrl()" << endl);
     m_Attrs.clear();
 }
 
-int LDAPUrl::getPort() const {
+int LDAPUrl::getPort() const 
+{
     return m_Port;
 }
 
-int LDAPUrl::getScope() const {
+void LDAPUrl::setPort(int port)
+{
+    m_Port = port;
+    regenerate = true;
+}
+
+int LDAPUrl::getScope() const 
+{
     return m_Scope;
 }
 
-const string& LDAPUrl::getURLString() const {
+void LDAPUrl::setScope( const std::string &scope )
+{
+    if (scope == "base" || scope == "" ) {
+        m_Scope = 0;
+    } else if (scope == "one" ) {
+        m_Scope = 1;
+    } else if (scope == "sub" ) {
+        m_Scope = 2;
+    } else {
+        throw LDAPUrlException(LDAPUrlException::INVALID_SCOPE, 
+                "Scope was:" + scope); 
+    }
+    regenerate = true;
+}
+
+const string& LDAPUrl::getURLString() const
+{
+    if (regenerate){
+        this->components2Url();
+        regenerate=false;
+    }
     return m_urlString;
 }
 
-const string& LDAPUrl::getHost() const {
+void LDAPUrl::setURLString( const std::string &url )
+{
+    m_urlString = url;
+    if (url != "") {
+        this->parseUrl();
+    }
+    regenerate = false;
+}
+
+const string& LDAPUrl::getHost() const 
+{
     return m_Host;
 }
 
-const string& LDAPUrl::getDN() const {
+void LDAPUrl::setHost( const std::string &host )
+{
+    m_Host = host;
+    regenerate = true;
+}
+
+const string& LDAPUrl::getDN() const 
+{
     return m_DN;
 }
+void LDAPUrl::setDN( const std::string &dn )
+{
+    m_DN = dn;
+    regenerate = true;
+}
 
-const string& LDAPUrl::getFilter() const {
+const string& LDAPUrl::getFilter() const 
+{
     return m_Filter;
 }
+void LDAPUrl::setFilter( const std::string &filter )
+{
+    m_Filter = filter;
+    regenerate = true;
+}
 
-const StringList& LDAPUrl::getAttrs() const {
+const StringList& LDAPUrl::getAttrs() const 
+{
     return m_Attrs;
 }
+void LDAPUrl::setAttrs( const StringList &attrs )
+{
+    m_Attrs = attrs;
+    regenerate = true;
+}
 
+const StringList& LDAPUrl::getExtensions() const 
+{
+    return m_Extensions;
+}
+
+void LDAPUrl::setExtensions( const StringList &ext )
+{
+    m_Extensions = ext;
+    regenerate = true;
+}
+
+const std::string& LDAPUrl::getScheme() const
+{
+    return m_Scheme;
+}
+
+void LDAPUrl::setScheme( const std::string &scheme )
+{
+    if (scheme == "ldap" || scheme == "ldaps" || 
+            scheme == "ldapi" || scheme == "cldap" ) 
+    {
+        m_Scheme = scheme;
+        regenerate = true;
+    } else {
+        throw LDAPUrlException(LDAPUrlException::INVALID_SCHEME,
+                "Unknown URL scheme: \"" + scheme + "\"");
+    }
+}
+
+void LDAPUrl::parseUrl() 
+{
+    DEBUG(LDAP_DEBUG_TRACE, "LDAPUrl::parseUrl()" << std::endl);
+    // reading Scheme
+    std::string::size_type pos = m_urlString.find(':');
+    std::string::size_type startpos = m_urlString.find(':');
+    if (pos == std::string::npos) {
+        throw LDAPUrlException(LDAPUrlException::INVALID_URL,
+                "No colon found in URL");
+    }
+    std::string scheme = m_urlString.substr(0, pos);
+    DEBUG(LDAP_DEBUG_TRACE, "    scheme is <" << scheme << ">" << std::endl);
+
+    if ( scheme == "ldap" ) {
+        m_Scheme = scheme;
+    } else if ( scheme == "ldaps" ) {
+        m_Scheme = scheme;
+    } else if ( scheme == "ldapi" ) {
+        m_Scheme = scheme;
+    } else if ( scheme == "cldap" ) {
+        m_Scheme = scheme;
+    } else {
+        throw LDAPUrlException(LDAPUrlException::INVALID_SCHEME,
+                "Unknown URL Scheme: \"" + scheme + "\"");
+    }
+
+    if ( m_urlString[pos+1] != '/' || m_urlString[pos+2] != '/' ) {
+        throw LDAPUrlException(LDAPUrlException::INVALID_URL);
+    } else {
+        startpos = pos + 3;
+    }
+    if ( m_urlString[startpos] == '/' ) {
+        startpos++;
+    } else {
+        pos = m_urlString.find('/', startpos);
+        std::string hostport = m_urlString.substr(startpos, 
+                pos - startpos);
+        DEBUG(LDAP_DEBUG_TRACE, "    hostport: <" << hostport << ">" 
+                << std::endl);
+        std::string::size_type portstart = m_urlString.find(':', startpos);
+        if (portstart == std::string::npos || portstart > pos ) {
+            percentDecode(hostport, m_Host);
+            if ( m_Scheme == "ldap" || m_Scheme == "cldap" ) {
+                m_Port = LDAP_DEFAULT_PORT;
+            } else if ( m_Scheme == "ldaps" ) {
+                m_Port = LDAPS_DEFAULT_PORT;
+            }
+        } else {
+            std::string tmp = m_urlString.substr(startpos, 
+                        portstart - startpos);
+            percentDecode(tmp, m_Host);
+            DEBUG(LDAP_DEBUG_TRACE, "Host: <" << m_Host << ">" << std::endl);
+            std::string port = m_urlString.substr(portstart+1, 
+                    pos-portstart-1);
+            if ( port.length() > 0 ) {
+                std::istringstream i(port);
+                i >> m_Port;
+                if ( i.fail() ){
+                    throw LDAPUrlException(LDAPUrlException::INVALID_PORT);
+                }
+            }
+            DEBUG(LDAP_DEBUG_TRACE, "    Port: <" << m_Port << ">" 
+                    << std::endl);
+        }
+    }
+    startpos = pos + 1;
+    int parserMode = base;
+    while ( pos != std::string::npos ) {
+        pos = m_urlString.find('?', startpos);
+        std::string actComponent = m_urlString.substr(startpos, 
+                pos - startpos);
+        DEBUG(LDAP_DEBUG_TRACE, "    ParserMode:" << parserMode << std::endl);
+        DEBUG(LDAP_DEBUG_TRACE, "    ActComponent: <" << actComponent << ">" 
+                << std::endl);
+        std::string s_scope = "";
+        std::string s_ext = "";
+        switch(parserMode) {
+            case base :
+                percentDecode(actComponent, m_DN);
+                DEBUG(LDAP_DEBUG_TRACE, "    BaseDN:" << m_DN << std::endl); 
+                break;
+            case attrs :
+                DEBUG(LDAP_DEBUG_TRACE, "    reading Attributes" << std::endl);
+                if (actComponent.length() != 0 ) {
+                    string2list(actComponent,m_Attrs, true);
+                }
+                break;
+            case scope :
+                percentDecode(actComponent, s_scope);
+                if (s_scope == "base" || s_scope == "" ) {
+                    m_Scope = 0;
+                } else if (s_scope == "one" ) {
+                    m_Scope = 1;
+                } else if (s_scope == "sub" ) {
+                    m_Scope = 2;
+                } else {
+                    throw LDAPUrlException(LDAPUrlException::INVALID_SCOPE);
+                }
+                DEBUG(LDAP_DEBUG_TRACE, "    Scope: <" << s_scope << ">"
+                        << std::endl);
+                break;
+            case filter :
+                percentDecode(actComponent, m_Filter);
+                DEBUG(LDAP_DEBUG_TRACE, "    filter: <" << m_Filter << ">"
+                        << std::endl);
+                break;
+            case extensions :
+                DEBUG(LDAP_DEBUG_TRACE, "    reading Extensions" << std::endl); 
+                string2list(actComponent, m_Extensions, true);
+                break;
+            default : 
+                DEBUG(LDAP_DEBUG_TRACE, "    unknown state" << std::endl); 
+                break;
+        }
+        startpos = pos + 1;
+        parserMode++;
+    }
+}
+
+void LDAPUrl::percentDecode(const std::string& src, std::string &out)
+{
+    DEBUG(LDAP_DEBUG_TRACE, "LDAPUrl::percentDecode()" << std::endl); 
+    std::string::size_type pos = 0;
+    std::string::size_type startpos = 0;
+    pos = src.find('%', startpos);
+    while ( pos != std::string::npos ) {
+        out += src.substr(startpos, pos - startpos);
+        std::string istr(src.substr(pos+1, 2));
+        std::istringstream i(istr);
+        i.setf(std::ios::hex, std::ios::basefield);
+        i.unsetf(std::ios::showbase);
+        int hex;
+        i >> hex;
+        if ( i.fail() ){
+            throw LDAPUrlException(LDAPUrlException::URL_DECODING_ERROR, 
+                    "Invalid percent encoding");
+        }
+        char j = hex;
+        out.push_back(j);
+        startpos = pos+3;
+        pos = src.find('%', startpos);
+    } 
+    out += src.substr(startpos, pos - startpos);
+}
+
+void LDAPUrl::string2list(const std::string &src, StringList& sl, 
+            bool percentDecode)
+{
+    std::string::size_type comma_startpos = 0;
+    std::string::size_type comma_pos = 0;
+    std::string actItem;
+    while ( comma_pos != std::string::npos ) {
+        comma_pos = src.find(',', comma_startpos);
+        actItem = src.substr(comma_startpos, comma_pos - comma_startpos);
+        if (percentDecode){
+            std::string decoded;
+            this->percentDecode(actItem,decoded);
+            actItem = decoded;
+        }
+        sl.add(actItem);
+        comma_startpos = comma_pos + 1;
+    }
+}
+
+
+void LDAPUrl::components2Url() const
+{
+    std::ostringstream url; 
+    std::string encoded = "";
+    this->percentEncode(m_Host, encoded, PCT_ENCFLAG_SLASH);
+    url << m_Scheme << "://" << encoded;
+    if ( m_Port != 0 ) {
+        url << ":" << m_Port;
+    }
+
+    url << "/";
+    encoded = "";
+    if ( m_DN != "" ) {
+        this->percentEncode( m_DN, encoded );
+        url << encoded;
+    }
+    string qm = "";
+    if ( ! m_Attrs.empty() ){
+        url << "?";
+        bool first = true;
+        for ( StringList::const_iterator i = m_Attrs.begin();
+                i != m_Attrs.end(); i++) 
+        {
+            this->percentEncode( *i, encoded );
+            if ( ! first ) {
+                url << ",";
+            } else {
+                first = false;
+            }
+            url << encoded;
+        }
+    } else {
+        qm.append("?");
+    }
+    if ( m_Scope == 1 ) {
+        url << qm << "?one";
+        qm = "";
+    } else if ( m_Scope == 2 ) {
+        url << qm << "?sub";
+        qm = "";
+    } else {
+        qm.append("?");
+    }
+    if (m_Filter != "" ){
+        this->percentEncode( m_Filter, encoded );
+        url << qm << "?" << encoded;
+        qm = "";
+    } else {
+        qm.append("?");
+    }
+
+    if ( ! m_Extensions.empty() ){
+        url << qm << "?";
+        bool first = true;
+        for ( StringList::const_iterator i = m_Extensions.begin();
+                i != m_Extensions.end(); i++) 
+        {
+            this->percentEncode( *i, encoded, 1);
+            if ( ! first ) {
+                url << ",";
+            } else {
+                first = false;
+            }
+            url << encoded;
+        }
+    }
+    m_urlString=url.str();  
+}
+
+
+void LDAPUrl::percentEncode( const std::string &src, 
+        std::string &dest, 
+        int flags) const
+{
+    std::ostringstream o;
+    o.setf(std::ios::hex, std::ios::basefield);
+    o.setf(std::ios::uppercase);
+    o.unsetf(std::ios::showbase);
+    bool escape=false;
+    for ( std::string::const_iterator i = src.begin(); i != src.end(); i++ ){
+        switch(*i){
+            /* reserved */
+            case '?' :
+                escape = true;
+            break;
+            case ',' :
+                if ( flags & PCT_ENCFLAG_COMMA ) {
+                    escape = true;
+                } else {
+                    escape = false;
+                }
+            break;
+            case ':' :
+            case '/' :
+                if ( flags & PCT_ENCFLAG_SLASH ) {
+                    escape = true;
+                } else {
+                    escape = false;
+                }
+            break;
+            case '#' :
+            case '[' :
+            case ']' :
+            case '@' :
+            case '!' :
+            case '$' :
+            case '&' :
+            case '\'' :
+            case '(' :
+            case ')' :
+            case '*' :
+            case '+' :
+            case ';' :
+            case '=' :
+            /* unreserved */
+            case '-' :
+            case '.' :
+            case '_' :
+            case '~' :
+                escape = false;
+            break;
+            default :
+                if (  std::isalnum(*i) ) {
+                    escape = false;
+                } else {
+                    escape = true;
+                }
+            break;
+        }
+        if ( escape ) {
+            o << "%" << (int)(unsigned char)*i ;
+        } else {
+            o.put(*i);
+        }
+    }
+    dest = o.str();
+}
+
+const code2string_s LDAPUrlException::code2string[] = {
+   { INVALID_SCHEME,            "Invalid URL Scheme" },
+   { INVALID_PORT,              "Invalid Port in Url" },
+   { INVALID_SCOPE,             "Invalid Search Scope in Url" },
+   { INVALID_URL,               "Invalid LDAP Url" },
+   { URL_DECODING_ERROR,        "Url-decoding Error" },
+   { 0, 0 }
+};
+
+LDAPUrlException::LDAPUrlException( int code, const std::string &msg) :
+    m_code(code), m_addMsg(msg) {}
+
+int LDAPUrlException::getCode() const
+{
+    return m_code;
+}
+
+const std::string LDAPUrlException::getAdditionalInfo() const
+{
+    return m_addMsg;
+}
+
+const std::string LDAPUrlException::getErrorMessage() const
+{
+    for ( int i = 0; code2string[i].string != 0; i++ ) {
+        if ( code2string[i].code == m_code ) {
+            return std::string(code2string[i].string);
+        }
+    }
+    return "";
+
+}

Modified: openldap/trunk/contrib/ldapc++/src/LDAPUrl.h
===================================================================
--- openldap/trunk/contrib/ldapc++/src/LDAPUrl.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/LDAPUrl.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000, OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2000-2006, OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -7,9 +7,9 @@
 #ifndef LDAP_URL_H
 #define LDAP_URL_H
 
-#include <ldap.h>
 #include <StringList.h>
 
+class LDAPUrlException;
 /**
  * This class is used to analyze and store LDAP-Urls as returned by a
  * LDAP-Server as Referrals and Search References. LDAP-URLs are defined
@@ -22,9 +22,10 @@
 
     public : 
         /**
-         * Create a new object from a c-string that contains a LDAP-Url
+         * Create a new object from a string that contains a LDAP-Url
+         * @param url The URL String
          */
-        LDAPUrl(const char *url);
+        LDAPUrl(const std::string &url="");
 
         /**
          * Destructor
@@ -36,6 +37,12 @@
          * port
          */
         int getPort() const;
+        
+        /**
+         * Set the port value of the URL
+         * @param dn The port value
+         */
+        void setPort(int port);
 
         /**
          * @return The scope part of the URL is returned. 
@@ -43,40 +50,155 @@
         int getScope() const;
 
         /**
+         * Set the Scope part of the URL
+         * @param scope The new scope
+         */
+        void setScope(const std::string& scope);
+
+        /**
          * @return The complete URL as a string
          */
         const std::string& getURLString() const;
 
         /**
+         * Set the URL member attribute
+         * @param url The URL String
+         */
+        void setURLString(const std::string &url);
+
+        /**
          * @return The hostname or IP-Address of the destination host.
          */
         const std::string& getHost() const;
 
         /**
+         * Set the Host part of the URL
+         * @param host The new host part
+         */
+        void setHost( const std::string &host);
+
+        /**
+         * @return The Protocol Scheme of the URL.
+         */
+        const std::string& getScheme() const;
+
+        /**
+         * Set the Protocol Scheme of the URL
+         * @param host The Protcol scheme. Allowed values are 
+         *       ldap,ldapi,ldaps and cldap
+         */
+        void setScheme( const std::string &scheme );
+
+        /**
          * @return The Base-DN part of the URL
          */
         const std::string& getDN() const;
+        
+        /**
+         * Set the DN part of the URL
+         * @param dn The new DN part
+         */
+        void setDN( const std::string &dn);
 
         
         /**
          * @return The Filter part of the URL
          */
         const std::string& getFilter() const;
+        
+        /**
+         * Set the Filter part of the URL
+         * @param filter The new Filter
+         */
+        void setFilter( const std::string &filter);
 
         /**
          * @return The List of attributes  that was in the URL
          */
         const StringList& getAttrs() const;
-    
+        
+        /**
+         * Set the Attributes part of the URL
+         * @param attrs StringList constaining the List of Attributes
+         */
+        void setAttrs( const StringList &attrs);
+        void setExtensions( const StringList &ext);
+        const StringList& getExtensions() const;
+
+        /**
+         * Percent-decode a string
+         * @param src The string that is to be decoded
+         * @param dest The decoded result string
+         */
+        void percentDecode( const std::string& src, std::string& dest );
+        
+        /**
+         * Percent-encoded a string
+         * @param src The string that is to be encoded
+         * @param dest The encoded result string
+         * @param flags
+         */
+        void percentEncode( const std::string& src, 
+                    std::string& dest, 
+                    int flags=0 ) const;
+   
+    protected : 
+        /**
+         * Split the url string that is associated with this Object into
+         * it components. The compontens of the URL can be access via the 
+         * get...() methods.
+         * (this function is mostly for internal use and gets called 
+         * automatically whenever necessary)
+         */
+        void parseUrl();
+        
+        /**
+         * Generate an URL string from the components that were set with
+         * the various set...() methods
+         * (this function is mostly for internal use and gets called 
+         * automatically whenever necessary)
+         */
+        void components2Url() const;
+        
+        void string2list(const std::string &src, StringList& sl,
+                bool percentDecode=false);
+
     protected :
+        mutable bool regenerate;
         int m_Port;
         int m_Scope;
         std::string m_Host;
         std::string m_DN;
         std::string m_Filter;
         StringList m_Attrs;
-        LDAPURLDesc *m_urlDesc;
-        std::string m_urlString;
+        StringList m_Extensions;
+        mutable std::string m_urlString;
+        std::string m_Scheme;
+        enum mode { base, attrs, scope, filter, extensions };
 };
 
+struct code2string_s {
+    int code;
+    const char* string;
+};
+
+class LDAPUrlException {
+    public :
+        LDAPUrlException(int code, const std::string &msg="" );
+
+        int getCode() const;
+        const std::string getErrorMessage() const;
+        const std::string getAdditionalInfo() const;
+
+        static const int INVALID_SCHEME      = 1;
+        static const int INVALID_PORT        = 2;
+        static const int INVALID_SCOPE       = 3;
+        static const int INVALID_URL         = 4;
+        static const int URL_DECODING_ERROR  = 5; 
+        static const code2string_s code2string[]; 
+
+    private:
+        int m_code;
+        std::string m_addMsg;
+};
 #endif //LDAP_URL_H

Modified: openldap/trunk/contrib/ldapc++/src/Makefile.am
===================================================================
--- openldap/trunk/contrib/ldapc++/src/Makefile.am	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/Makefile.am	2007-12-15 10:25:31 UTC (rev 892)
@@ -85,5 +85,5 @@
                 LDAPSearchRequest.h 
 
 libldapcpp_la_LIBADD = -lldap -llber
-libldapcpp_la_LDFLAGS = -version-info 0:4:0
+libldapcpp_la_LDFLAGS = -version-info 0:5:0
 

Modified: openldap/trunk/contrib/ldapc++/src/Makefile.in
===================================================================
--- openldap/trunk/contrib/ldapc++/src/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# Makefile.in generated by automake 1.10 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -18,15 +18,11 @@
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 
 
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
 install_sh_SCRIPT = $(install_sh) -c
@@ -48,7 +44,7 @@
 am__aclocal_m4_deps = $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = config.h
 CONFIG_CLEAN_FILES =
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -75,17 +71,21 @@
 	LDAPSearchRequest.lo LDAPSearchResult.lo LDAPSearchResults.lo \
 	LDAPUrl.lo LDAPUrlList.lo StringList.lo
 libldapcpp_la_OBJECTS = $(am_libldapcpp_la_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+libldapcpp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(libldapcpp_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I. at am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
 CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
 SOURCES = $(libldapcpp_la_SOURCES)
 DIST_SOURCES = $(libldapcpp_la_SOURCES)
 includeHEADERS_INSTALL = $(INSTALL_HEADER)
@@ -94,8 +94,6 @@
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
@@ -122,6 +120,8 @@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FFLAGS = @FFLAGS@
+GREP = @GREP@
+INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -133,6 +133,7 @@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
 OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@@ -142,20 +143,18 @@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
-ac_ct_AR = @ac_ct_AR@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
 ac_ct_F77 = @ac_ct_F77@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
@@ -167,28 +166,39 @@
 build_cpu = @build_cpu@
 build_os = @build_os@
 build_vendor = @build_vendor@
+builddir = @builddir@
 datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
 host_os = @host_os@
 host_vendor = @host_vendor@
+htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
 libdir = @libdir@
 libexecdir = @libexecdir@
+localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
+psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
 lib_LTLIBRARIES = libldapcpp.la
 libldapcpp_la_SOURCES = LDAPAddRequest.cpp \
                         LDAPAsynConnection.cpp \
@@ -270,7 +280,7 @@
                 LDAPSearchRequest.h 
 
 libldapcpp_la_LIBADD = -lldap -llber
-libldapcpp_la_LDFLAGS = -version-info 0:4:0
+libldapcpp_la_LDFLAGS = -version-info 0:5:0
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -309,13 +319,13 @@
 config.h: stamp-h1
 	@if test ! -f $@; then \
 	  rm -f stamp-h1; \
-	  $(MAKE) stamp-h1; \
+	  $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
 	else :; fi
 
 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
 	@rm -f stamp-h1
 	cd $(top_builddir) && $(SHELL) ./config.status src/config.h
-$(srcdir)/config.h.in:  $(am__configure_deps) $(top_srcdir)/acconfig.h
+$(srcdir)/config.h.in:  $(am__configure_deps) 
 	cd $(top_srcdir) && $(AUTOHEADER)
 	rm -f stamp-h1
 	touch $@
@@ -324,7 +334,7 @@
 	-rm -f config.h stamp-h1
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
 	@$(NORMAL_INSTALL)
-	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
 	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
 	  if test -f $$p; then \
 	    f=$(am__strip_dir) \
@@ -335,7 +345,7 @@
 
 uninstall-libLTLIBRARIES:
 	@$(NORMAL_UNINSTALL)
-	@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
 	  p=$(am__strip_dir) \
 	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
 	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
@@ -350,7 +360,7 @@
 	  rm -f "$${dir}/so_locations"; \
 	done
 libldapcpp.la: $(libldapcpp_la_OBJECTS) $(libldapcpp_la_DEPENDENCIES) 
-	$(CXXLINK) -rpath $(libdir) $(libldapcpp_la_LDFLAGS) $(libldapcpp_la_OBJECTS) $(libldapcpp_la_LIBADD) $(LIBS)
+	$(libldapcpp_la_LINK) -rpath $(libdir) $(libldapcpp_la_OBJECTS) $(libldapcpp_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -398,22 +408,22 @@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/StringList.Plo at am__quote@
 
 .cpp.o:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
 
 .cpp.obj:
- at am__fastdepCXX_TRUE@	if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .cpp.lo:
- at am__fastdepCXX_TRUE@	if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
- at am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
@@ -423,13 +433,9 @@
 
 clean-libtool:
 	-rm -rf .libs _libs
-
-distclean-libtool:
-	-rm -f libtool
-uninstall-info-am:
 install-includeHEADERS: $(include_HEADERS)
 	@$(NORMAL_INSTALL)
-	test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)"
+	test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
 	@list='$(include_HEADERS)'; for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  f=$(am__strip_dir) \
@@ -494,22 +500,21 @@
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
 distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
 	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkdir_p) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
 	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
 	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
 	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
 	    fi; \
@@ -525,7 +530,7 @@
 all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h
 installdirs:
 	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
-	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
 install-exec: install-exec-am
@@ -560,7 +565,7 @@
 	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-hdr distclean-libtool distclean-tags
+	distclean-hdr distclean-tags
 
 dvi: dvi-am
 
@@ -574,12 +579,20 @@
 
 install-data-am: install-includeHEADERS
 
+install-dvi: install-dvi-am
+
 install-exec-am: install-libLTLIBRARIES
 
+install-html: install-html-am
+
 install-info: install-info-am
 
 install-man:
 
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
@@ -600,22 +613,25 @@
 
 ps-am:
 
-uninstall-am: uninstall-includeHEADERS uninstall-info-am \
-	uninstall-libLTLIBRARIES
+uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES
 
+.MAKE: install-am install-strip
+
 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
 	clean-libLTLIBRARIES clean-libtool ctags distclean \
 	distclean-compile distclean-generic distclean-hdr \
 	distclean-libtool distclean-tags distdir dvi dvi-am html \
 	html-am info info-am install install-am install-data \
-	install-data-am install-exec install-exec-am \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am \
 	install-includeHEADERS install-info install-info-am \
-	install-libLTLIBRARIES install-man install-strip installcheck \
+	install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
 	installcheck-am installdirs maintainer-clean \
 	maintainer-clean-generic mostlyclean mostlyclean-compile \
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags uninstall uninstall-am uninstall-includeHEADERS \
-	uninstall-info-am uninstall-libLTLIBRARIES
+	uninstall-libLTLIBRARIES
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.

Modified: openldap/trunk/contrib/ldapc++/src/StringList.cpp
===================================================================
--- openldap/trunk/contrib/ldapc++/src/StringList.cpp	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/StringList.cpp	2007-12-15 10:25:31 UTC (rev 892)
@@ -6,6 +6,8 @@
 #include "StringList.h"
 #include "debug.h"
 
+#include <cstdlib>
+
 using namespace std;
 
 StringList::StringList(){

Modified: openldap/trunk/contrib/ldapc++/src/ac/time.h
===================================================================
--- openldap/trunk/contrib/ldapc++/src/ac/time.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/ac/time.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic time.h */
-/* $OpenLDAP: pkg/ldap/contrib/ldapc++/src/ac/time.h,v 1.5.2.3 2007/01/02 21:43:42 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/contrib/ldapc++/src/ac/time.h,v 1.7.2.3 2007/10/02 02:24:57 ralf Exp $ */
 /*
  * Copyright 1998-2007 The OpenLDAP Foundation, Redwood City, California, USA
  * All rights reserved.
@@ -13,10 +13,10 @@
 #ifndef _AC_TIME_H
 #define _AC_TIME_H
 
-#if TIME_WITH_SYS_TIME
+#ifdef TIME_WITH_SYS_TIME
 # include <sys/time.h>
 # include <time.h>
-#elif HAVE_SYS_TIME_H
+#elif defined HAVE_SYS_TIME_H
 # include <sys/time.h>
 # ifdef HAVE_SYS_TIMEB_H
 #  include <sys/timeb.h>

Modified: openldap/trunk/contrib/ldapc++/src/config.h.in
===================================================================
--- openldap/trunk/contrib/ldapc++/src/config.h.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/src/config.h.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,5 @@
 /* src/config.h.in.  Generated from configure.in by autoheader.  */
-#undef WITH_DEBUG
 
-
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
@@ -61,3 +59,6 @@
 
 /* Version number of package */
 #undef VERSION
+
+/* Define to 1 ot enable debug logging */
+#undef WITH_DEBUG

Deleted: openldap/trunk/contrib/ldapc++/stamp-h.in
===================================================================
--- openldap/trunk/contrib/ldapc++/stamp-h.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/ldapc++/stamp-h.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1 +0,0 @@
-timestamp

Copied: openldap/trunk/contrib/ldaptcl (from rev 891, openldap/vendor/openldap-2.4.7/contrib/ldaptcl)

Modified: openldap/trunk/contrib/slapd-modules/acl/posixgroup.c
===================================================================
--- openldap/trunk/contrib/slapd-modules/acl/posixgroup.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/slapd-modules/acl/posixgroup.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/acl/posixgroup.c,v 1.1.2.5 2007/01/02 21:43:42 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/acl/posixgroup.c,v 1.3.2.3 2007/08/31 23:13:51 quanah Exp $ */
 /*
  * Copyright 1998-2007 The OpenLDAP Foundation.
  * All rights reserved.
@@ -247,7 +247,7 @@
 		Attribute	*a_uid,
 				*a_member;
 
-		a_uid = attr_find( user->e_attrs, pg_uidNumber);
+		a_uid = attr_find( user->e_attrs, pg_uidNumber );
 		if ( !a_uid || !BER_BVISNULL( &a_uid->a_nvals[ 1 ] ) ) {
 			rc = LDAP_NO_SUCH_ATTRIBUTE;
 

Copied: openldap/trunk/contrib/slapd-modules/addpartial (from rev 891, openldap/vendor/openldap-2.4.7/contrib/slapd-modules/addpartial)

Copied: openldap/trunk/contrib/slapd-modules/allop (from rev 891, openldap/vendor/openldap-2.4.7/contrib/slapd-modules/allop)

Modified: openldap/trunk/contrib/slapd-modules/comp_match/Makefile
===================================================================
--- openldap/trunk/contrib/slapd-modules/comp_match/Makefile	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/slapd-modules/comp_match/Makefile	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/contrib/slapd-modules/comp_match/Makefile,v 1.3.2.6 2007/01/02 21:43:42 kurt Exp $
+# $OpenLDAP: pkg/ldap/contrib/slapd-modules/comp_match/Makefile,v 1.11.2.2 2007/08/31 23:13:51 quanah Exp $
 # This work is part of OpenLDAP Software <http://www.openldap.org/>.
 #
 # Copyright 2003-2007 The OpenLDAP Foundation.
@@ -15,12 +15,11 @@
 # top-level directory of the distribution or, alternatively, at
 # <http://www.OpenLDAP.org/license.html>.
 
-topbuilddir = ../../../../build
 topsrcdir = ../../..
-snaccdir = /usr/local/snacc
+snaccdir = ../$(topsrcdir)/snacc
 openssldir = /usr/local/include/openssl
 
-LIBTOOL=$(topbuilddir)/libtool
+LIBTOOL=$(topsrcdir)/libtool
 OPT=-g -O2 -DLDAP_COMPONENT
 CC=gcc
 

Copied: openldap/trunk/contrib/slapd-modules/denyop (from rev 891, openldap/vendor/openldap-2.4.7/contrib/slapd-modules/denyop)

Modified: openldap/trunk/contrib/slapd-modules/dsaschema/dsaschema.c
===================================================================
--- openldap/trunk/contrib/slapd-modules/dsaschema/dsaschema.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/slapd-modules/dsaschema/dsaschema.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/dsaschema/dsaschema.c,v 1.3.2.3 2007/01/02 21:43:42 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/dsaschema/dsaschema.c,v 1.5.2.2 2007/08/31 23:13:51 quanah Exp $ */
 /*
  * Copyright 2004-2007 The OpenLDAP Foundation.
  * All rights reserved.

Copied: openldap/trunk/contrib/slapd-modules/lastmod (from rev 891, openldap/vendor/openldap-2.4.7/contrib/slapd-modules/lastmod)

Modified: openldap/trunk/contrib/slapd-modules/passwd/README
===================================================================
--- openldap/trunk/contrib/slapd-modules/passwd/README	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/slapd-modules/passwd/README	2007-12-15 10:25:31 UTC (rev 892)
@@ -6,7 +6,7 @@
 
 This directory contains native slapd plugins for password mechanisms that
 are not actively supported by the project. Currently this includes the
-Kerberos and Netscape MTA-MD5 password mechanisms.
+Kerberos, Netscape MTA-MD5 and RADIUS password mechanisms.
 
 To use the Kerberos plugin, add:
 
@@ -20,6 +20,15 @@
 
 to your slapd configuration file.
 
+To use the RADIUS plugin, add:
+
+moduleload pw-radius.so
+
+to your slapd configuration file; optionally, the path to a configuration
+file can be appended in the form
+
+moduleload pw-radius.so config="/etc/radius.conf"
+
 No Makefile is provided. Use a command line similar to:
 
 gcc -shared -I../../../include -Wall -g -DHAVE_KRB5 -o pw-kerberos.so kerberos.c
@@ -32,3 +41,10 @@
 
 gcc -shared -I../../../include -Wall -g -o pw-netscape.so netscape.c
 
+The corresponding command for the RADIUS plugin would be:
+
+gcc -shared -I../../../include -Wall -g -o pw-radius.so radius.c -lradius
+
+(Actually, you might want to statically link the RADIUS client library 
+libradius.a into the module).
+

Modified: openldap/trunk/contrib/slapd-modules/passwd/kerberos.c
===================================================================
--- openldap/trunk/contrib/slapd-modules/passwd/kerberos.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/slapd-modules/passwd/kerberos.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/passwd/kerberos.c,v 1.2.2.4 2007/01/02 21:43:42 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/passwd/kerberos.c,v 1.5.2.2 2007/08/31 23:13:52 quanah Exp $ */
 /*
  * Copyright 1998-2007 The OpenLDAP Foundation.
  * All rights reserved.

Modified: openldap/trunk/contrib/slapd-modules/passwd/netscape.c
===================================================================
--- openldap/trunk/contrib/slapd-modules/passwd/netscape.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/slapd-modules/passwd/netscape.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/passwd/netscape.c,v 1.2.2.4 2007/01/02 21:43:42 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/passwd/netscape.c,v 1.5.2.2 2007/08/31 23:13:52 quanah Exp $ */
 /*
  * Copyright 1998-2007 The OpenLDAP Foundation.
  * All rights reserved.

Copied: openldap/trunk/contrib/slapd-modules/passwd/radius.c (from rev 891, openldap/vendor/openldap-2.4.7/contrib/slapd-modules/passwd/radius.c)
===================================================================
--- openldap/trunk/contrib/slapd-modules/passwd/radius.c	                        (rev 0)
+++ openldap/trunk/contrib/slapd-modules/passwd/radius.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,143 @@
+/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/passwd/radius.c,v 1.2.2.3 2007/08/31 23:13:52 quanah Exp $ */
+/*
+ * Copyright 1998-2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <lber.h>
+#include <lber_pvt.h>	/* BER_BVC definition */
+#include "lutil.h"
+#include <ldap_pvt_thread.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+
+#include <radlib.h>
+
+static LUTIL_PASSWD_CHK_FUNC chk_radius;
+static const struct berval scheme = BER_BVC("{RADIUS}");
+static char *config_filename;
+static ldap_pvt_thread_mutex_t libradius_mutex;
+
+static int
+chk_radius(
+	const struct berval	*sc,
+	const struct berval	*passwd,
+	const struct berval	*cred,
+	const char		**text )
+{
+	unsigned int		i;
+	int			rc = LUTIL_PASSWD_ERR;
+
+	struct rad_handle	*h = NULL;
+
+	for ( i = 0; i < cred->bv_len; i++ ) {
+		if ( cred->bv_val[ i ] == '\0' ) {
+			return LUTIL_PASSWD_ERR;	/* NUL character in cred */
+		}
+	}
+
+	if ( cred->bv_val[ i ] != '\0' ) {
+		return LUTIL_PASSWD_ERR;	/* cred must behave like a string */
+	}
+
+	for ( i = 0; i < passwd->bv_len; i++ ) {
+		if ( passwd->bv_val[ i ] == '\0' ) {
+			return LUTIL_PASSWD_ERR;	/* NUL character in password */
+		}
+	}
+
+	if ( passwd->bv_val[ i ] != '\0' ) {
+		return LUTIL_PASSWD_ERR;	/* passwd must behave like a string */
+	}
+
+	ldap_pvt_thread_mutex_lock( &libradius_mutex );
+
+	h = rad_auth_open();
+	if ( h == NULL ) {
+		ldap_pvt_thread_mutex_unlock( &libradius_mutex );
+		return LUTIL_PASSWD_ERR;
+	}
+
+	if ( rad_config( h, config_filename ) != 0 ) {
+		goto done;
+	}
+
+	if ( rad_create_request( h, RAD_ACCESS_REQUEST ) ) {
+		goto done;
+	}
+
+	if ( rad_put_string( h, RAD_USER_NAME, passwd->bv_val ) != 0 ) {
+		goto done;
+	}
+
+	if ( rad_put_string( h, RAD_USER_PASSWORD, cred->bv_val ) != 0 ) {
+		goto done;
+	}
+
+	switch ( rad_send_request( h ) ) {
+	case RAD_ACCESS_ACCEPT:
+		rc = LUTIL_PASSWD_OK;
+		break;
+
+	case RAD_ACCESS_REJECT:
+		rc = LUTIL_PASSWD_ERR;
+		break;
+
+	case RAD_ACCESS_CHALLENGE:
+		rc = LUTIL_PASSWD_ERR;
+		break;
+
+	case -1:
+		/* no valid response is received */
+		break;
+	}
+
+done:;
+	rad_close( h );
+
+	ldap_pvt_thread_mutex_unlock( &libradius_mutex );
+	return rc;
+}
+
+int
+term_module()
+{
+	return ldap_pvt_thread_mutex_destroy( &libradius_mutex );
+}
+
+int
+init_module( int argc, char *argv[] )
+{
+	int	i;
+
+	for ( i = 0; i < argc; i++ ) {
+		if ( strncasecmp( argv[ i ], "config=", STRLENOF( "config=" ) ) == 0 ) {
+			/* FIXME: what if multiple loads of same module?
+			 * does it make sense (e.g. override an existing one)? */
+			if ( config_filename == NULL ) {
+				config_filename = ber_strdup( &argv[ i ][ STRLENOF( "config=" ) ] );
+			}
+
+		} else {
+			fprintf( stderr, "init_module(radius): unknown arg#%d=\"%s\".\n",
+				i, argv[ i ] );
+			return 1;
+		}
+	}
+
+	ldap_pvt_thread_mutex_init( &libradius_mutex );
+
+	return lutil_passwd_add( (struct berval *)&scheme, chk_radius, NULL );
+}

Copied: openldap/trunk/contrib/slapd-modules/proxyOld (from rev 891, openldap/vendor/openldap-2.4.7/contrib/slapd-modules/proxyOld)

Modified: openldap/trunk/contrib/slapd-modules/smbk5pwd/smbk5pwd.c
===================================================================
--- openldap/trunk/contrib/slapd-modules/smbk5pwd/smbk5pwd.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/contrib/slapd-modules/smbk5pwd/smbk5pwd.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* smbk5pwd.c - Overlay for managing Samba and Heimdal passwords */
-/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/smbk5pwd/smbk5pwd.c,v 1.1.2.10 2006/12/15 15:39:35 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/contrib/slapd-modules/smbk5pwd/smbk5pwd.c,v 1.17.2.5 2007/10/09 00:18:47 quanah Exp $ */
 /*
  * Copyright 2004-2005 by Howard Chu, Symas Corp.
  * All rights reserved.
@@ -13,8 +13,8 @@
  * <http://www.OpenLDAP.org/license.html>.
  */
 /*
- * Support for sambaPwdMustChange added by Marco D'Ettorre.
  * Support for table-driven configuration added by Pierangelo Masarati.
+ * Support for sambaPwdMustChange and sambaPwdCanChange added by Marco D'Ettorre.
  *
  * The conditions of the OpenLDAP Public License apply.
  */
@@ -71,6 +71,7 @@
 static AttributeDescription *ad_sambaNTPassword;
 static AttributeDescription *ad_sambaPwdLastSet;
 static AttributeDescription *ad_sambaPwdMustChange;
+static AttributeDescription *ad_sambaPwdCanChange;
 static ObjectClass *oc_sambaSamAccount;
 #endif
 
@@ -90,6 +91,8 @@
 #ifdef DO_SAMBA
 	/* How many seconds before forcing a password change? */
 	time_t	smb_must_change;
+        /* How many seconds after allowing a password change? */
+        time_t  smb_can_change;
 #endif
 } smbk5pwd_t;
 
@@ -428,6 +431,7 @@
 #ifdef SLAP_MOD_INTERNAL
 		ml->sml_flags = SLAP_MOD_INTERNAL;
 #endif
+		ml->sml_numvals = i;
 		ml->sml_values = keys;
 		ml->sml_nvalues = NULL;
 		
@@ -440,6 +444,7 @@
 #ifdef SLAP_MOD_INTERNAL
 		ml->sml_flags = SLAP_MOD_INTERNAL;
 #endif
+		ml->sml_numvals = 1;
 		ml->sml_values = ch_malloc( 2 * sizeof(struct berval));
 		ml->sml_values[0].bv_val = ch_malloc( 64 );
 		ml->sml_values[0].bv_len = sprintf(ml->sml_values[0].bv_val,
@@ -489,6 +494,7 @@
 #ifdef SLAP_MOD_INTERNAL
 		ml->sml_flags = SLAP_MOD_INTERNAL;
 #endif
+		ml->sml_numvals = 1;
 		ml->sml_values = keys;
 		ml->sml_nvalues = NULL;
 
@@ -515,6 +521,7 @@
 #ifdef SLAP_MOD_INTERNAL
 		ml->sml_flags = SLAP_MOD_INTERNAL;
 #endif
+		ml->sml_numvals = 1;
 		ml->sml_values = keys;
 		ml->sml_nvalues = NULL;
 
@@ -536,6 +543,7 @@
 #ifdef SLAP_MOD_INTERNAL
 		ml->sml_flags = SLAP_MOD_INTERNAL;
 #endif
+		ml->sml_numvals = 1;
 		ml->sml_values = keys;
 		ml->sml_nvalues = NULL;
 
@@ -557,9 +565,33 @@
 #ifdef SLAP_MOD_INTERNAL
 			ml->sml_flags = SLAP_MOD_INTERNAL;
 #endif
+			ml->sml_numvals = 1;
 			ml->sml_values = keys;
 			ml->sml_nvalues = NULL;
 		}
+
+                if (pi->smb_can_change)
+                {
+                        ml = ch_malloc(sizeof(Modifications));
+                        ml->sml_next = qpw->rs_mods;
+                        qpw->rs_mods = ml;
+
+                        keys = ch_malloc( 2 * sizeof(struct berval) );
+                        keys[0].bv_val = ch_malloc( STRLENOF( "9223372036854775807L" ) + 1 );
+                        keys[0].bv_len = snprintf(keys[0].bv_val,
+                                        STRLENOF( "9223372036854775807L" ) + 1,
+                                        "%ld", slap_get_time() + pi->smb_can_change);
+                        BER_BVZERO( &keys[1] );
+
+                        ml->sml_desc = ad_sambaPwdCanChange;
+                        ml->sml_op = LDAP_MOD_REPLACE;
+#ifdef SLAP_MOD_INTERNAL
+                        ml->sml_flags = SLAP_MOD_INTERNAL;
+#endif
+						ml->sml_numvals = 1;
+                        ml->sml_values = keys;
+                        ml->sml_nvalues = NULL;
+                }
 	}
 #endif /* DO_SAMBA */
 	be_entry_release_r( op, e );
@@ -572,38 +604,45 @@
 /* back-config stuff */
 enum {
 	PC_SMB_MUST_CHANGE = 1,
+	PC_SMB_CAN_CHANGE,
 	PC_SMB_ENABLE
 };
 
 static ConfigDriver smbk5pwd_cf_func;
 
 /*
- * NOTE: uses OID arcs OLcfgOvAt:6 and OLcfgOvOc:6
+ * NOTE: uses OID arcs OLcfgCtAt:1 and OLcfgCtOc:1
  */
 
 static ConfigTable smbk5pwd_cfats[] = {
 	{ "smbk5pwd-enable", "arg",
 		2, 0, 0, ARG_MAGIC|PC_SMB_ENABLE, smbk5pwd_cf_func,
-		"( OLcfgOvAt:6.1 NAME 'olcSmbK5PwdEnable' "
+		"( OLcfgCtAt:1.1 NAME 'olcSmbK5PwdEnable' "
 		"DESC 'Modules to be enabled' "
 		"SYNTAX OMsDirectoryString )", NULL, NULL },
 	{ "smbk5pwd-must-change", "time",
 		2, 2, 0, ARG_MAGIC|ARG_INT|PC_SMB_MUST_CHANGE, smbk5pwd_cf_func,
-		"( OLcfgOvAt:6.2 NAME 'olcSmbK5PwdMustChange' "
+		"( OLcfgCtAt:1.2 NAME 'olcSmbK5PwdMustChange' "
 		"DESC 'Credentials validity interval' "
 		"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+        { "smbk5pwd-can-change", "time",
+                2, 2, 0, ARG_MAGIC|ARG_INT|PC_SMB_CAN_CHANGE, smbk5pwd_cf_func,
+                "( OLcfgCtAt:1.3 NAME 'olcSmbK5PwdCanChange' "
+                "DESC 'Credentials minimum validity interval' "
+                "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
 
 	{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
 };
 
 static ConfigOCs smbk5pwd_cfocs[] = {
-	{ "( OLcfgOvOc:6.1 "
+	{ "( OLcfgCtOc:1.1 "
 		"NAME 'olcSmbK5PwdConfig' "
 		"DESC 'smbk5pwd overlay configuration' "
 		"SUP olcOverlayConfig "
 		"MAY ( "
 			"olcSmbK5PwdEnable "
 			"$ olcSmbK5PwdMustChange "
+			"$ olcSmbK5PwdCanChange "
 		") )", Cft_Overlay, smbk5pwd_cfats },
 
 	{ NULL, 0, NULL }
@@ -637,6 +676,14 @@
 #endif /* ! DO_SAMBA */
 			break;
 
+                case PC_SMB_CAN_CHANGE:
+#ifdef DO_SAMBA
+                        c->value_int = pi->smb_can_change;
+#else /* ! DO_SAMBA */
+                        c->value_int = 0;
+#endif /* ! DO_SAMBA */
+                        break;
+
 		case PC_SMB_ENABLE:
 			c->rvalue_vals = NULL;
 			if ( pi->mode ) {
@@ -658,6 +705,9 @@
 		case PC_SMB_MUST_CHANGE:
 			break;
 
+                case PC_SMB_CAN_CHANGE:
+                        break;
+
 		case PC_SMB_ENABLE:
 			if ( !c->line ) {
 				pi->mode = 0;
@@ -696,6 +746,24 @@
 #endif /* ! DO_SAMBA */
 		break;
 
+        case PC_SMB_CAN_CHANGE:
+#ifdef DO_SAMBA
+                if ( c->value_int < 0 ) {
+                        Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: "
+                                "<%s> invalid negative value \"%d\".",
+                                c->log, c->argv[ 0 ], 0 );
+                        return 1;
+                }
+                pi->smb_can_change = c->value_int;
+#else /* ! DO_SAMBA */
+                Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: "
+                        "<%s> only meaningful "
+                        "when compiled with -DDO_SAMBA.\n",
+                        c->log, c->argv[ 0 ], 0 );
+                return 1;
+#endif /* ! DO_SAMBA */
+                break;
+
 	case PC_SMB_ENABLE: {
 		slap_mask_t	mode = pi->mode, m;
 
@@ -775,6 +843,7 @@
 		{ "sambaNTPassword",		&ad_sambaNTPassword },
 		{ "sambaPwdLastSet",		&ad_sambaPwdLastSet },
 		{ "sambaPwdMustChange",		&ad_sambaPwdMustChange },
+                { "sambaPwdCanChange",          &ad_sambaPwdCanChange },
 		{ NULL }
 	},
 #endif /* DO_SAMBA */
@@ -881,7 +950,7 @@
 }
 
 static int
-smbk5pwd_db_init(BackendDB *be)
+smbk5pwd_db_init(BackendDB *be, ConfigReply *cr)
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
 	smbk5pwd_t	*pi;
@@ -896,7 +965,7 @@
 }
 
 static int
-smbk5pwd_db_open(BackendDB *be)
+smbk5pwd_db_open(BackendDB *be, ConfigReply *cr)
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
 	smbk5pwd_t	*pi = (smbk5pwd_t *)on->on_bi.bi_private;
@@ -916,7 +985,7 @@
 }
 
 static int
-smbk5pwd_db_destroy(BackendDB *be)
+smbk5pwd_db_destroy(BackendDB *be, ConfigReply *cr)
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
 	smbk5pwd_t	*pi = (smbk5pwd_t *)on->on_bi.bi_private;

Copied: openldap/trunk/contrib/slapd-modules/trace (from rev 891, openldap/vendor/openldap-2.4.7/contrib/slapd-modules/trace)

Modified: openldap/trunk/debian/changelog
===================================================================
--- openldap/trunk/debian/changelog	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/debian/changelog	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,12 +1,13 @@
-openldap2.3 (2.3.39-2) UNRELEASED; urgency=low
+openldap2.3 (2.4.7-1) UNRELEASED; urgency=low
 
+  * New upstream version.
   * slapd.conf and DB_CONFIG are used in the postinst, they shouldn't be
-    shipped under doc/examples because /usr/share/doc can't be depended 
+    shipped under doc/examples because /usr/share/doc can't be depended
     on per policy; ship the files under /usr/share/slapd and symlink the
     /other/ way, which also spares us from dh_compress trying to gzip
     slapd.conf.  Closes: #452749.
 
- -- Steve Langasek <vorlon at debian.org>  Sat, 24 Nov 2007 15:09:23 -0800
+ -- Steve Langasek <vorlon at debian.org>  Sat, 15 Dec 2007 02:24:25 -0800
 
 openldap2.3 (2.3.39-1) unstable; urgency=medium
 

Added: openldap/trunk/debian/schema/collective.schema
===================================================================
--- openldap/trunk/debian/schema/collective.schema	                        (rev 0)
+++ openldap/trunk/debian/schema/collective.schema	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,65 @@
+# collective.schema -- Collective attribute schema
+# $OpenLDAP: pkg/ldap/servers/slapd/schema/collective.schema,v 1.12.2.2 2007/08/31 23:14:06 quanah Exp $
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 1998-2007 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+#
+
+# The version of this file as distributed by the OpenLDAP Foundation
+# contains text from an IETF RFC explaining the schema.  Unfortunately,
+# that text is covered by a license that doesn't meet Debian's Free
+# Software Guidelines.  This is a stripped version of the schema that
+# contains only the functional schema definition, not the text of the
+# RFC.
+#
+# For an explanation of this schema, see RFC 3671, at (among other
+# places):  http://www.ietf.org/rfc/rfc3671.txt
+
+attributeType      ( 2.5.4.7.1 NAME 'c-l'
+	SUP l COLLECTIVE )
+
+attributeType      ( 2.5.4.8.1 NAME 'c-st'
+	SUP st COLLECTIVE )
+
+attributeType      ( 2.5.4.9.1 NAME 'c-street'
+	SUP street COLLECTIVE )
+
+attributeType      ( 2.5.4.10.1 NAME 'c-o'
+	SUP o COLLECTIVE )
+
+attributeType      ( 2.5.4.11.1 NAME 'c-ou'
+	SUP ou COLLECTIVE )
+
+attributeType      ( 2.5.4.16.1 NAME 'c-PostalAddress'
+	SUP postalAddress COLLECTIVE )
+
+attributeType      ( 2.5.4.17.1 NAME 'c-PostalCode'
+	SUP postalCode COLLECTIVE )
+
+attributeType ( 2.5.4.18.1 NAME 'c-PostOfficeBox'
+	SUP postOfficeBox COLLECTIVE )
+
+attributeType ( 2.5.4.19.1 NAME 'c-PhysicalDeliveryOfficeName'
+	SUP physicalDeliveryOfficeName COLLECTIVE )
+
+attributeType ( 2.5.4.20.1 NAME 'c-TelephoneNumber'
+	SUP telephoneNumber COLLECTIVE )
+
+attributeType ( 2.5.4.21.1 NAME 'c-TelexNumber'
+	SUP telexNumber COLLECTIVE )
+
+attributeType ( 2.5.4.23.1 NAME 'c-FacsimileTelephoneNumber'
+	SUP facsimileTelephoneNumber COLLECTIVE )
+
+attributeType ( 2.5.4.25.1 NAME 'c-InternationalISDNNumber'
+	SUP internationalISDNNumber COLLECTIVE )
+

Modified: openldap/trunk/doc/Makefile.in
===================================================================
--- openldap/trunk/doc/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 ## doc Makefile.in for OpenLDAP
-# $OpenLDAP: pkg/ldap/doc/Makefile.in,v 1.8.2.4 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/ldap/doc/Makefile.in,v 1.11.2.2 2007/08/31 23:13:52 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/doc/devel/args
===================================================================
--- openldap/trunk/doc/devel/args	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/devel/args	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,15 +1,15 @@
 Tools           ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-ldapcompare      * DE**HI*K M*OPQR  UVWXYZ   de *h**k *n*p*    vwxyz
-ldapdelete       *CDE**HI*K M*OPQR  UVWXYZ  cdef*h**k *n*p*    vwxy
-ldapmodify       *CDE**HI*K M*OPQRS UVWXYZabcde *h**k *n*p*r t vwxy
-ldapmodrdn       *CDE**HI*K M*OPQR  UVWXYZ  cdef*h**k *n*p*rs  vwxy
-ldappasswd      A*CDE**HI*   *O QRS UVWXYZa  def*h**  * * * s  vwxy  
-ldapsearch      A*CDE**HI*KLM*OPQRSTUVWXYZab def*h**kl*n*p* stuvwxyz
-ldapwhoami       * DE**HI*   *O QR  UVWXYZ   def*h**  *n*p*    vwxy 
+ldapcompare      * DE**HI*K M*OPQR  UVWXYZ   de *h**k *nop*    vwxyz
+ldapdelete       *CDE**HI*K M*OPQR  UVWXYZ  cdef*h**k *nop*    vwxy
+ldapmodify       *CDE**HI*K M*OPQRS UVWXYZabcde *h**k *nop*r t vwxy
+ldapmodrdn       *CDE**HI*K M*OPQR  UVWXYZ  cdef*h**k *nop*rs  vwxy
+ldappasswd      A*CDE**HI*   *O QRS UVWXYZa  def*h**  * o * s  vwxy  
+ldapsearch      A*CDE**HI*KLM*OPQRSTUVWXYZab def*h**kl*nop* stuvwxyz
+ldapwhoami       * DE**HI*   *O QR  UVWXYZ   def*h**  *nop*    vwxy 
 
 
 * reserved
-	BFGJgijmoq01235789
+	BFGJgijmq01235789
 
 * General flags:
 	-C Chase Referrals
@@ -25,6 +25,7 @@
 	-h host
 	-n no-op
 	-N no (SASLprep) normalization of simple bind password
+	-o general connection options (currently nettimeout only)
 	-p port
 	-v verbose
 	-V version
@@ -55,4 +56,4 @@
 
 
 ---
-$OpenLDAP: pkg/ldap/doc/devel/args,v 1.26.4.3 2006/02/12 03:19:48 kurt Exp $
+$OpenLDAP: pkg/ldap/doc/devel/args,v 1.29.2.2 2007/08/31 23:13:52 quanah Exp $

Modified: openldap/trunk/doc/devel/todo
===================================================================
--- openldap/trunk/doc/devel/todo	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/devel/todo	2007-12-15 10:25:31 UTC (rev 892)
@@ -37,7 +37,7 @@
 
 Medium projects
 ---------------
-Add syncrepl "turn" support
+Add syncrepl turn
 Implement DIT Structure Rules and Name Forms
 Implement LDAPprep
 Implement native support for simple SASL mechanisms
@@ -70,4 +70,4 @@
   http://www.openldap.org/devel/cvsweb.cgi/~checkout~/design/todo.txt?rev=1&cvsroot=JLDAP
 
 ---
-$OpenLDAP: pkg/ldap/doc/devel/todo,v 1.132.2.5 2006/02/12 03:19:48 kurt Exp $
+$OpenLDAP: pkg/ldap/doc/devel/todo,v 1.138.2.3 2007/08/31 23:13:52 quanah Exp $

Modified: openldap/trunk/doc/devel/toolargs
===================================================================
--- openldap/trunk/doc/devel/toolargs	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/devel/toolargs	2007-12-15 10:25:31 UTC (rev 892)
@@ -24,4 +24,4 @@
 	-v verbose
 
 ---
-$Header$
+$OpenLDAP: pkg/ldap/doc/devel/toolargs,v 1.1.6.1 2007/08/31 23:13:52 quanah Exp $

Modified: openldap/trunk/doc/guide/COPYRIGHT
===================================================================
--- openldap/trunk/doc/guide/COPYRIGHT	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/COPYRIGHT	2007-12-15 10:25:31 UTC (rev 892)
@@ -36,9 +36,11 @@
 
 ---
 
-Portions Copyright 1999-2005 Howard Y.H. Chu.
-Portions Copyright 1999-2005 Symas Corporation.
+Portions Copyright 1999-2007 Howard Y.H. Chu.
+Portions Copyright 1999-2007 Symas Corporation.
 Portions Copyright 1998-2003 Hallvard B. Furuseth.
+Portions Copyright 2007 Gavin Henry
+Portions Copyright 2007 Suretec Systems
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without

Modified: openldap/trunk/doc/guide/admin/Makefile
===================================================================
--- openldap/trunk/doc/guide/admin/Makefile	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/Makefile	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 ## Makefile for OpenLDAP Administrator's Guide
-# $OpenLDAP: pkg/openldap-guide/admin/Makefile,v 1.4.2.3 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/Makefile,v 1.5.2.6 2007/11/29 22:51:25 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 2005-2007 The OpenLDAP Foundation.
@@ -14,19 +14,33 @@
 ## <http://www.OpenLDAP.org/license.html>.
 all: guide.html index.html
 
+# for website building (for webmaster use, don't change)
+www: guide.html index.html OpenLDAP-Admin-Guide.pdf
+
 sdf-src: \
 	../plain.sdf \
 	../preamble.sdf \
 	abstract.sdf \
+	appendix-changes.sdf \
+	appendix-common-errors.sdf \
+	appendix-configs.sdf \
+	appendix-contrib.sdf \
+	appendix-deployments.sdf \
+	appendix-ldap-result-codes.sdf \
+	appendix-recommended-versions.sdf \
+	appendix-upgrading.sdf \
+	backends.sdf \
 	config.sdf \
 	dbtools.sdf \
+	glossary.sdf \
 	guide.sdf \
 	install.sdf \
 	intro.sdf \
+	maintenance.sdf \
 	master.sdf \
 	monitoringslapd.sdf \
+	overlays.sdf \
 	preface.sdf \
-	proxycache.sdf \
 	quickstart.sdf \
 	referrals.sdf \
 	replication.sdf \
@@ -35,21 +49,23 @@
 	schema.sdf \
 	security.sdf \
 	slapdconfig.sdf \
-	syncrepl.sdf \
 	title.sdf \
 	tls.sdf \
+	troubleshooting.sdf \
 	tuning.sdf
 
 sdf-img: \
 	../images/LDAPlogo.gif \
-	config_local.gif \
-	config_ref.gif \
+	allmail-en.png \
+	allusersgroup-en.png \
+	config_dit.png \
+	config_local.png \
+	config_ref.png \
 	config_repl.gif \
-	config_x500fe.gif \
-	config_x500ref.gif \
-	intro_dctree.gif \
-	intro_tree.gif \
-	replication.gif
+	dual_dc.png \
+	intro_dctree.png \
+	intro_tree.png \
+	refint.png 
 
 guide.html: guide.sdf sdf-src sdf-img
 	sdf -2html guide.sdf
@@ -60,7 +76,11 @@
 admin.html: admin.sdf sdf-src sdf-img
 	sdf -DPDF -2html admin.sdf
 
-guide.pdf: admin.html
-	htmldoc --book --duplex --bottom 36 --top 36 \
-		--toclevels 2 \
-		-f guide.pdf admin.html
+guide.pdf: admin.html guide.book
+	htmldoc --batch guide.book -f guide.pdf
+
+OpenLDAP-Admin-Guide.pdf: admin.html guide.book
+	htmldoc --batch guide.book -f OpenLDAP-Admin-Guide.pdf
+
+clean: 
+	rm -f *.pdf *.html *~ *.bak

Copied: openldap/trunk/doc/guide/admin/README.spellcheck (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/README.spellcheck)
===================================================================
--- openldap/trunk/doc/guide/admin/README.spellcheck	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/README.spellcheck	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,16 @@
+# $OpenLDAP: pkg/openldap-guide/admin/README.spellcheck,v 1.2.2.2 2007/10/23 19:06:09 quanah Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+#
+# README.spellcheck 
+#
+
+aspell.en.pws
+	We use aspell to spell check the Admin Guide and Man Pages.
+	
+	Please move aspell.en.pws to ~/.aspell.en.pws and run:
+	
+	aspell --lang=en_US -c <filename>
+	
+	If you add additional words and terms, please add
+	them or copy them to aspell.en.pws and commit.

Modified: openldap/trunk/doc/guide/admin/abstract.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/abstract.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/abstract.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/admin/abstract.sdf,v 1.6.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/abstract.sdf,v 1.7.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 # 

Modified: openldap/trunk/doc/guide/admin/admin.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/admin.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/admin.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,12 +1,10 @@
-# $OpenLDAP: pkg/openldap-guide/admin/admin.sdf,v 1.1.2.3 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/admin.sdf,v 1.2.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 #
 # guide.sdf 
 #
 
-!define DOC_TOC 0
-
 !macro build_html_cover
 !endmacro
 

Copied: openldap/trunk/doc/guide/admin/allmail-en.png (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/allmail-en.png)
===================================================================
(Binary files differ)

Copied: openldap/trunk/doc/guide/admin/allusersgroup-en.png (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/allusersgroup-en.png)
===================================================================
(Binary files differ)

Copied: openldap/trunk/doc/guide/admin/appendix-changes.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/appendix-changes.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/appendix-changes.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/appendix-changes.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,214 @@
+# $OpenLDAP: pkg/openldap-guide/admin/appendix-changes.sdf,v 1.8.2.3 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Changes Since Previous Release
+
+The following sections attempt to summarize the new features and changes in OpenLDAP
+software since the 2.3.x release and the OpenLDAP Admin Guide.
+
+H2: New Guide Sections
+
+In order to make the Admin Guide more thorough and cover the majority of questions
+asked on the OpenLDAP mailing lists and scenarios discussed there, we have added the following new sections:
+
+* {{SECT:When should I use LDAP?}}
+* {{SECT:When should I not use LDAP?}}
+* {{SECT:LDAP vs RDBMS}}
+* {{SECT:Backends}}
+* {{SECT:Overlays}}
+* {{SECT:Replication}}
+* {{SECT:Maintenance}}
+* {{SECT:Monitoring}}
+* {{SECT:Tuning}}
+* {{SECT:Troubleshooting}}
+* {{SECT:Changes Since Previous Release}}
+* {{SECT:Upgrading from 2.3.x}}
+* {{SECT:Common errors encountered when using OpenLDAP Software}}
+* {{SECT:Recommended OpenLDAP Software Dependency Versions}}
+* {{SECT:Real World OpenLDAP Deployments and Examples}}
+* {{SECT:OpenLDAP Software Contributions}}
+* {{SECT:Configuration File Examples}}
+* {{SECT:LDAP Result Codes}}
+* {{SECT:Glossary}}
+
+Also, the table of contents is now 3 levels deep to ease navigation.
+
+
+H2: New Features and Enhancements in 2.4
+
+H3: Better {{B:cn=config}} functionality
+
+There is a new slapd-config(5) manpage for the {{B:cn=config}} backend. The 
+original design called for auto-renaming of config entries when you insert or 
+delete entries with ordered names, but that was not implemented in 2.3. It is 
+now in 2.4. This means, e.g., if you have
+
+>   olcDatabase={1}bdb,cn=config
+>   olcSuffix: dc=example,dc=com
+
+and you want to add a new subordinate, now you can ldapadd:
+
+>   olcDatabase={1}bdb,cn=config
+>   olcSuffix: dc=foo,dc=example,dc=com
+
+This will insert a new BDB database in slot 1 and bump all following databases
+ down one, so the original BDB database will now be named:
+
+>   olcDatabase={2}bdb,cn=config
+>   olcSuffix: dc=example,dc=com
+
+H3: Better {{B:cn=schema}} functionality
+
+In 2.3 you were only able to add new schema elements, not delete or modify 
+existing elements. In 2.4 you can modify schema at will. (Except for the 
+hardcoded system schema, of course.)
+
+H3: More sophisticated Syncrepl configurations
+
+The original implementation of Syncrepl in OpenLDAP 2.2 was intended to support 
+multiple consumers within the same database, but that feature never worked and 
+was removed from OpenLDAP 2.3; you could only configure a single consumer in 
+any database.
+
+In 2.4 you can configure multiple consumers in a single database. The configuration 
+possibilities here are quite complex and numerous. You can configure consumers 
+over arbitrary subtrees of a database (disjoint or overlapping). Any portion 
+of the database may in turn be provided to other consumers using the Syncprov 
+overlay. The Syncprov overlay works with any number of consumers over a single 
+database or over arbitrarily many glued databases.
+
+H3: N-Way Multimaster Replication
+
+As a consequence of the work to support multiple consumer contexts, the syncrepl 
+system now supports full N-Way multimaster replication with entry-level conflict 
+resolution. There are some important constraints, of course: In order to maintain 
+consistent results across all servers, you must maintain tightly synchronized 
+clocks across all participating servers (e.g., you must use NTP on all servers). 
+
+The entryCSNs used for replication now record timestamps with microsecond resolution, 
+instead of just seconds. The delta-syncrepl code has not been updated to support 
+multimaster usage yet, that will come later in the 2.4 cycle.
+
+H3: Replicating {{slapd}} Configuration (syncrepl and {{B:cn=config}})
+
+Syncrepl was explicitly disabled on cn=config in 2.3. It is now fully supported 
+in 2.4; you can use syncrepl to replicate an entire server configuration from 
+one server to arbitrarily many other servers. It's possible to clone an entire 
+running slapd using just a small (less than 10 lines) seed configuration, or 
+you can just replicate the schema subtrees, etc. Tests 049 and 050 in the test 
+suite provide working examples of these capabilities.
+
+
+H3: Push-Mode Replication
+
+In 2.3 you could configure syncrepl as a full push-mode replicator by using it 
+in conjunction with a back-ldap pointed at the target server. But because the 
+back-ldap database needs to have a suffix corresponding to the target's suffix, 
+you could only configure one instance per slapd.
+
+In 2.4 you can define a database to be "hidden", which means that its suffix is 
+ignored when checking for name collisions, and the database will never be used 
+to answer requests received by the frontend. Using this "hidden" database feature 
+allows you to configure multiple databases with the same suffix, allowing you to 
+set up multiple back-ldap instances for pushing replication of a single database 
+to multiple targets. There may be other uses for hidden databases as well (e.g., 
+using a syncrepl consumer to maintain a *local* mirror of a database on a separate filesystem).
+
+
+H3: More extensive TLS configuration control
+
+In 2.3, the TLS configuration in slapd was only used by the slapd listeners. For 
+outbound connections used by e.g. back-ldap or syncrepl their TLS parameters came 
+from the system's ldap.conf file.
+
+In 2.4 all of these sessions inherit their settings from the main slapd configuration, 
+but settings can be individually overridden on a per-config-item basis. This is 
+particularly helpful if you use certificate-based authentication and need to use a 
+different client certificate for different destinations.
+
+
+H3: Performance enhancements
+
+Too many to list. Some notable changes - ldapadd used to be a couple of orders 
+of magnitude slower than "slapadd -q". It's now at worst only about half the 
+speed of slapadd -q. Some comparisons of all the 2.x OpenLDAP releases are available 
+at {{URL:http://www.openldap.org/pub/hyc/scale2007.pdf}}
+
+That compared 2.0.27, 2.1.30, 2.2.30, 2.3.33, and HEAD). Toward the latter end 
+of the "Cached Search Performance" chart it gets hard to see the difference 
+because the run times are so small, but the new code is about 25% faster than 2.3, 
+which was about 20% faster than 2.2, which was about 100% faster than 2.1, which 
+was about 100% faster than 2.0, in that particular search scenario. That test 
+basically searched a 1.3GB DB of 380836 entries (all in the slapd entry cache) 
+in under 1 second. i.e., on a 2.4GHz CPU with DDR400 ECC/Registered RAM we can 
+search over 500 thousand entries per second. The search was on an unindexed 
+attribute using a filter that would not match any entry, forcing slapd to examine 
+every entry in the DB, testing the filter for a match.
+
+Essentially the slapd entry cache in back-bdb/back-hdb is so efficient the search 
+processing time is almost invisible; the runtime is limited only by the memory 
+bandwidth of the machine. (The search data rate corresponds to about 3.5GB/sec; 
+the memory bandwidth on the machine is only about 4GB/sec due to ECC and register latency.)
+
+H3: New overlays
+
+* slapo-constraint (Attribute value constraints)
+* slapo-dds (Dynamic Directory Services, RFC 2589)
+* slapo-memberof (reverse group membership maintenance)
+
+H3: New features in existing Overlays
+
+* slapo-pcache
+  - Inspection/Maintenance 
+    -- the cache database can be directly accessed via
+       LDAP by adding a specific control to each LDAP request; a specific
+       extended operation allows to consistently remove cached entries and entire
+       cached queries
+  - Hot Restart
+    -- cached queries are saved on disk at shutdown, and reloaded if
+      not expired yet at subsequent restart
+
+* slapo-rwm can safely interoperate with other overlays
+* Dyngroup/Dynlist merge, plus security enhancements
+  - added dgIdentity support (draft-haripriya-dynamicgroup)
+
+H3: New features in slapd
+
+* monitoring of back-{b,h}db: cache fill-in, non-indexed searches,
+* session tracking control (draft-wahl-ldap-session)
+* subtree delete in back-sql (draft-armijo-ldap-treedelete)
+
+H3: New features in libldap
+
+* ldap_sync client API (LDAP Content Sync Operation, RFC 4533)
+
+H3: New clients, tools and tool enhancements
+
+* ldapexop for arbitrary extended operations
+* Complete support of controls in request/response for all clients
+* LDAP Client tools now honor SRV records 
+
+H3: New build options
+
+* Support for building against GnuTLS
+
+
+H2: Obsolete Features Removed From 2.4
+
+These features were strongly deprecated in 2.3 and removed in 2.4.
+
+H3: Slurpd
+
+Please read the {{SECT:Replication}} section as to why this is no longer in
+OpenLDAP
+
+H3: back-ldbm
+
+back-ldbm was both slow and unreliable. Its byzantine indexing code was
+prone to spontaneous corruption, as were the underlying database libraries
+that were commonly used (e.g. GDBM or NDBM). back-bdb and back-hdb are
+superior in every aspect, with simplified indexing to avoid index corruption,
+fine-grained locking for greater concurrency, hierarchical caching for
+greater performance, streamlined on-disk format for greater efficiency
+and portability, and full transaction support for greater reliability.

Copied: openldap/trunk/doc/guide/admin/appendix-common-errors.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/appendix-common-errors.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/appendix-common-errors.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/appendix-common-errors.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,661 @@
+# $OpenLDAP: pkg/openldap-guide/admin/appendix-common-errors.sdf,v 1.4.2.2 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Common errors encountered when using OpenLDAP Software
+
+The following sections attempt to summarize the most common causes of LDAP errors 
+when using OpenLDAP
+
+H2: Common causes of LDAP errors
+
+H3: ldap_*: Can't contact LDAP server
+
+The {[B:Can't contact LDAP server}} error is usually returned when the LDAP 
+server cannot be contacted. This may occur for many reasons:
+
+* the LDAP server is not running; this can be checked by running, for example,
+
+>      telnet <host> <port>
+
+replacing {{<host>}} and {{<port>}} with the hostname and the port the server 
+is supposed to listen on.
+* the client has not been instructed to contact a running server; with OpenLDAP 
+command-line tools this is accomplished by providing the -H switch, whose 
+argument is a valid LDAP url corresponding to the interface the server is 
+supposed to be listening on.
+
+H3: ldap_*: No such object
+
+The {{B:no such object}} error is generally returned when the target DN of the 
+operation cannot be located. This section details reasons common to all 
+operations. You should also look for answers specific to the operation 
+(as indicated in the error message).
+
+The most common reason for this error is non-existence of the named object. First, 
+check for typos.
+
+Also note that, by default, a new directory server holds no objects 
+(except for a few system entries). So, if you are setting up a new directory 
+server and get this message, it may simply be that you have yet to add the 
+object you are trying to locate.
+
+The error commonly occurs because a DN was not specified and a default was not 
+properly configured.
+
+If you have a suffix specified in slapd.conf eg.
+
+>      suffix "dc=example,dc=com"
+
+You should use
+
+>      ldapsearch -b 'dc=example,dc=com' '(cn=jane*)'
+
+to tell it where to start the search.
+
+The {{F:-b}} should be specified for all LDAP commands unless you have an 
+{{ldap.conf}}(5) default configured.
+
+See {{ldapsearch}}(1), {{ldapmodify}}(1) 
+
+Also, {{slapadd}}(8) and its ancillary programs are very strict about the 
+syntax of the LDIF file. 
+
+Some liberties in the LDIF file may result in an apparently successful creation 
+of the database, but accessing some parts of it may be difficult.
+
+One known common error in database creation is putting a blank line before the 
+first entry in the LDIF file. {{B:There must be no leading blank lines in the 
+LDIF file.}}
+
+It is generally recommended that {{ldapadd}}(1) be used instead of {{slapadd}}(8) 
+when adding new entries your directory. {{slapadd}}(8) should be used to bulk 
+load entries known to be valid.
+
+Another cause of this message is a referral 
+({SECT:Constructing a Distributed Directory Service}}) entry to an unpopulated 
+directory. 
+
+Either remove the referral, or add a single record with the referral base DN 
+to the empty directory.
+
+This error may also occur when slapd is unable to access the contents of its 
+database because of file permission problems. For instance, on a Red Hat Linux 
+system, slapd runs as user 'ldap'. When slapadd is run as root to create a 
+database from scratch, the contents of {{F:/var/lib/ldap}} are created with 
+user and group root and with permission 600, making the contents inaccessible 
+to the slapd server.
+
+H3: ldap_*: Can't chase referral
+
+This is caused by the line
+
+>      referral        ldap://root.openldap.org
+
+In {{F:slapd.conf}}, it was provided as an example for how to use referrals 
+in the original file. However if your machine is not permanently connected to 
+the Internet, it will fail to find the server, and hence produce an error message.
+
+To resolve, just place a # in front of line and restart slapd or point it to 
+an available ldap server.
+
+See also: {{ldapadd}}(1), {{ldapmodify}}(1) and {{slapd.conf}}(5)
+
+H3: ldap_*: server is unwilling to perform
+
+slapd will return an unwilling to perform error if the backend holding the 
+target entry does not support the given operation.
+
+The password backend is only willing to perform searches. It will return an 
+unwilling to perform error for all other operations.
+
+The shell backend is configurable and may support a limited subset of operations.
+Check for other errors indicating a shortage of resources required by the 
+directory server. i.e. you may have a full disk etc
+
+H3: ldap_*: Insufficient access
+
+This error occurs when server denies the operation due to insufficient access. 
+This is usually caused by binding to a DN with insufficient privileges 
+(or binding anonymously) to perform the operation. 
+
+You can bind as the rootdn/rootpw specified in {{slapd.conf}}(5) to gain full 
+access. Otherwise, you must bind to an entry which has been granted the 
+appropriate rights through access controls.
+
+
+H3: ldap_*: Invalid DN syntax
+
+The target (or other) DN of the operation is invalid. This implies that either 
+the string representation of the DN is not in the required form, one of the 
+types in the attribute value assertions is not defined, or one of the values 
+in the attribute value assertions does not conform to the appropriate syntax.
+
+H3: ldap_*: Referral hop limit exceeded
+
+This error generally occurs when the client chases a referral which refers 
+itself back to a server it already contacted. The server responds as it did 
+before and the client loops. This loop is detected when the hop limit is exceeded.
+
+This is most often caused through misconfiguration of the server's default 
+referral. The default referral should not be itself:
+
+That is, on {{F:ldap://myldap/}} the default referral should not be {{F:ldap://myldap/}}
+ (or any hostname/ip which is equivalent to myldap).
+
+H3: ldap_*: operations error
+
+In some versions of {{slapd}}(8), {{operationsError}} was returned instead of other.
+
+H3: ldap_*: other error
+
+The other result code indicates an internal error has occurred. 
+While the additional information provided with the result code might provide 
+some hint as to the problem, often one will need to consult the server's log files.
+
+H3: ldap_add/modify: Invalid syntax
+
+This error is reported when a value of an attribute does not conform to syntax 
+restrictions. Additional information is commonly provided stating which value 
+of which attribute was found to be invalid. Double check this value and other 
+values (the server will only report the first error it finds).
+
+Common causes include:
+
+* extraneous white space (especially trailing white space)
+* improperly encoded characters (LDAPv3 uses UTF-8 encoded Unicode)
+* empty values (few syntaxes allow empty values)
+
+
+For certain syntax, like OBJECT IDENTIFIER (OID), this error can indicate that 
+the OID descriptor (a "short name") provided is unrecognized. For instance, 
+this error is returned if the {{objectClass}} value provided is unrecognized.
+
+H3: ldap_add/modify: Object class violation
+
+This error is returned with the entry to be added or the entry as modified 
+violates the object class schema rules. Normally additional information is 
+returned the error detailing the violation. Some of these are detailed below.
+
+Violations related to the entry's attributes:
+
+>      Attribute not allowed
+
+A provided attribute is not allowed by the entry's object class(es). 
+
+>      Missing required attribute
+
+An attribute required by the entry's object class(es) was not provided. 
+
+Violations related to the entry's class(es):
+
+>      Entry has no objectClass attribute
+
+The entry did not state which object classes it belonged to. 
+
+>      Unrecognized objectClass
+
+One (or more) of the listed objectClass values is not recognized. 
+
+>      No structural object class provided
+
+None of the listed objectClass values is structural. 
+
+>      Invalid structural object class chain
+
+Two or more structural objectClass values are not in same structural object 
+class chain. 
+
+>      Structural object class modification
+
+Modify operation attempts to change the structural class of the entry. 
+
+>      Instanstantiation of abstract objectClass.
+
+An abstract class is not subordinate to any listed structural or auxiliary class. 
+
+>      Invalid structural object class
+
+Other structural object class problem. 
+
+>      No structuralObjectClass operational attribute
+
+This is commonly returned when a shadow server is provided an entry which does 
+not contain the structuralObjectClass operational attribute. 
+
+
+Note that the above error messages as well as the above answer assumes basic 
+knowledge of LDAP/X.500 schema.
+
+H3: ldap_add: No such object
+
+The "ldap_add: No such object" error is commonly returned if parent of the 
+entry being added does not exist. Add the parent entry first...
+
+For example, if you are adding "cn=bob,dc=domain,dc=com" and you get:
+
+>      ldap_add: No such object
+
+The entry "dc=domain,dc=com" likely doesn't exist. You can use ldapsearch to 
+see if does exist:
+
+>      ldapsearch -b 'dc=domain,dc=com' -s base '(objectclass=*)'
+
+If it doesn't, add it. See {{SECT:A Quick-Start Guide}} for assistance.
+
+Note: if the entry being added is the same as database suffix, it's parent 
+isn't required. i.e.: if your suffix is "dc=domain,dc=com", "dc=com" doesn't 
+need to exist to add "dc=domain,dc=com".
+
+This error will also occur if you try to add any entry that the server is not 
+configured to hold.
+
+For example, if your database suffix is "dc=domain,dc=com" and you attempt to 
+add "dc=domain2,dc=com", "dc=com", "dc=domain,dc=org", "o=domain,c=us", or an 
+other DN in the "dc=domain,dc=com" subtree, the server will return a
+ "No such object" (or referral) error.
+
+{{slapd}}(8) will generally return "no global superior knowledge" as additional 
+information indicating its return noSuchObject instead of a referral as the 
+server is not configured with knowledge of a global superior server.
+
+
+H3: ldap add: invalid structural object class chain
+
+This particular error refers to the rule about STRUCTURAL objectclasses, which 
+states that an object is of one STRUCTURAL class, the structural class of the 
+object. The object is said to belong to this class, zero or more auxiliaries
+ classes, and their super classes. 
+
+While all of these classes are commonly listed in the objectClass attribute of 
+the entry, one of these classes is the structural object class of the entry. 
+Thus, it is OK for an objectClass attribute 
+to contain inetOrgPerson, organizationalPerson, and person because they inherit
+ one from another to form a single super class chain. That is, inetOrgPerson SUPs 
+organizationPerson SUPs person. On the other hand, it is invalid for both inetOrgPerson 
+and account to be listed in objectClass as inetOrgPerson and account are not 
+part of the same super class chain (unless some other class is also listed 
+with is a subclass of both).
+
+To resolve this problem, one must determine which class will better serve 
+structural object class for the entry, adding this class to the objectClass 
+attribute (if not already present), and remove any other structural class from 
+the entry's objectClass attribute which is not a super class of the structural 
+object class.
+
+Which object class is better depends on the particulars of the situation. 
+One generally should consult the documentation for the applications one is 
+using for help in making the determination.
+
+H3: ldap_add: no structuralObjectClass operational attribute
+
+ldapadd(1) may error:
+
+>      adding new entry "uid=XXX,ou=People,o=campus,c=ru"
+>        ldap_add: Internal (implementation specific) error (80)
+>           additional info: no structuralObjectClass operational attribute
+
+when slapd(8) cannot determine, based upon the contents of the objectClass 
+attribute, what the structural class of the object should be.
+
+
+H3: ldap_add/modify/rename: Naming violation
+
+OpenLDAP's slapd checks for naming attributes and distinguished values consistency, 
+according to RFC 4512.
+
+Naming attributes are those attributeTypes that appear in an entry's RDN;
+ distinguished values are the values of the naming attributes that appear in 
+an entry's RDN, e.g, in
+
+>      cn=Someone+mail=someone at example.com,dc=example,dc=com
+
+the naming attributes are cn and mail, and the distinguished values are 
+Someone and someone at example.com.
+
+OpenLDAP's slapd checks for consistency when:
+
+* adding an entry
+* modifying an entry, if the values of the naming attributes are changed
+* renaming an entry, if the RDN of the entry changes
+
+Possible causes of error are:
+
+* the naming attributes are not present in the entry; for example:
+
+>                dn: dc=example,dc=com
+>                objectClass: organization
+>                o: Example
+>                # note: "dc: example" is missing
+
+* the naming attributes are present in the entry, but in the attributeType 
+definition they are marked as:
+- collective
+- operational
+- obsolete
+
+* the naming attributes are present in the entry, but the distinguished values 
+are not; for example:
+
+>                dn: dc=example,dc=com
+>                objectClass: domain
+>                dc: foobar
+>                # note: "dc" is present, but the value is not "example"
+
+* the naming attributes are present in the entry, with the distinguished values, but the naming attributes:
+- do not have an equality field, so equality cannot be asserted
+- the matching rule is not supported (yet)
+- the matching rule is not appropriate
+
+* the given distinguished values do not comply with their syntax
+
+* other errors occurred during the validation/normalization/match process; 
+this is a catchall: look at previous logs for details in case none of the above 
+apply to your case.
+
+In any case, make sure that the attributeType definition for the naming attributes 
+contains an appropriate EQUALITY field; or that of the superior, if they are 
+defined based on a superior attributeType (look at the SUP field). See RFC 4512 for details.
+
+
+H3: ldap_add/delete/modify/rename: no global superior knowledge
+
+If the target entry name places is not within any of the databases the server 
+is configured to hold and the server has no knowledge of a global superior, 
+the server will indicate it is unwilling to perform the operation and provide 
+the text "no global superior knowledge" as additional text.
+
+Likely the entry name is incorrect, or the server is not properly configured 
+to hold the named entry, or, in distributed directory environments, a default 
+referral was not configured.
+
+
+H3: ldap_bind: Insufficient access
+
+Current versions of slapd(8) requires that clients have authentication 
+permission to attribute types used for authentication purposes before accessing 
+them to perform the bind operation. As all bind operations are done anonymously 
+(regardless of previous bind success), the auth access must be granted to anonymous.
+
+In the example ACL below grants the following access:
+
+* to anonymous users:
+- permission to authenticate using values of userPassword
+* to authenticated users:
+- permission to update (but not read) their userPassword
+- permission to read any object excepting values of userPassword 
+
+All other access is denied.
+
+>        access to attr=userPassword
+>          by self =w
+>          by anonymous auth
+
+>        access *
+>          by self write
+>          by users read
+
+
+H3: ldap_bind: Invalid credentials
+
+The error usually occurs when the credentials (password) provided does not 
+match the userPassword held in entry you are binding to.
+
+The error can also occur when the bind DN specified is not known to the server.
+
+Check both! In addition to the cases mentioned above you should check if the 
+server denied access to userPassword on selected parts of the directory. In 
+fact, slapd always returns "Invalid credentials" in case of failed bind, 
+regardless of the failure reason, since other return codes could reveal the 
+validity of the user's name.
+
+To debug access rules defined in slapd.conf, add "ACL" to log level.
+
+H3: ldap_bind: Protocol error
+
+There error is generally occurs when the LDAP version requested by the 
+client is not supported by the server.
+
+The OpenLDAP Software 2.x server, by default, only accepts version 3 LDAP Bind 
+requests but can be configured to accept a version 2 LDAP Bind request. 
+
+Note: The 2.x server expects LDAPv3 [RFC4510] to be used when the client 
+requests version 3 and expects a limited LDAPv3 variant (basically, LDAPv3 
+syntax and semantics in an LDAPv2 PDUs) to be used when version 2 is expected. 
+
+This variant is also sometimes referred to as LDAPv2+, but differs from the U-Mich 
+LDAP variant in a number of ways.
+
+H3: ldap_modify: cannot modify object class
+
+This message is commonly returned when attempting to modify the objectClass 
+attribute in a manner inconsistent with the LDAP/X.500 information model. In 
+particular, it commonly occurs when one tries to change the structure of the 
+object from one class to another, for instance, trying to change an 'apple' 
+into a 'pear' or a 'fruit' into a 'pear'. 
+
+Such changes are disallowed by the slapd(8) in accordance with LDAP and X.500 restrictions.
+
+
+H3: ldap_sasl_interactive_bind_s: ...
+
+If you intended to bind using a DN and password and get an error from 
+ldap_sasl_interactive_bind_s, you likely forgot to provide a '-x' option to 
+the command. By default, SASL authentication is used. '-x' is necessary to 
+select "simple" authentication.
+
+
+H3: ldap_sasl_interactive_bind_s: No such Object
+
+This indicates that LDAP SASL authentication function could not read the 
+Root DSE.
+The error will occur when the server doesn't provide a root DSE. This may be 
+due to access controls.
+
+
+H3: ldap_sasl_interactive_bind_s: No such attribute
+
+This indicates that LDAP SASL authentication function could read the Root 
+DSE but it contained no supportedSASLMechanism attribute.
+
+The supportedSASLmechanism attribute lists mechanisms currently available. 
+The list may be empty because none of the supported mechanisms are currently 
+available. For example, EXTERNAL is listed only if the client has established 
+its identity by authenticating at a lower level (e.g. TLS).
+
+Note: the attribute may not be visible due to access controls
+
+Note: SASL bind is the default for all OpenLDAP tools, e.g. ldapsearch(1), ldapmodify(1). To force use of "simple" bind, use the "-x" option. Use of "simple" bind is not recommended unless one has adequate confidentiality protection in place (e.g. TLS/SSL, IPSEC).
+
+H3: ldap_sasl_interactive_bind_s: Unknown authentication method
+
+This indicates that none of the SASL authentication supported by the server 
+are supported by the client, or that they are too weak or otherwise inappropriate 
+for use by the client. Note that the default security options disallows the use 
+of certain mechanisms such as ANONYMOUS and PLAIN (without TLS).
+
+Note: SASL bind is the default for all OpenLDAP tools. To force use of "simple" bind, use the "-x" option. Use of "simple" bind is not recommended unless one has adequate confidentiality protection in place (e.g. TLS/SSL, IPSEC).
+
+H3: ldap_sasl_interactive_bind_s: Local error (82)
+
+Apparently not having forward and reverse DNS entries for the LDAP server can result in this error.
+
+
+H3: ldap_search: Partial results and referral received
+
+This error is returned with the server responses to an LDAPv2 search query 
+with both results (zero or more matched entries) and references (referrals to other servers).
+See also: ldapsearch(1).
+
+If the updatedn on the replica does not exist, a referral will be returned. 
+It may do this as well if the ACL needs tweaking.
+
+H3: ldap_start_tls: Operations error
+
+ldapsearch(1) and other tools will return
+
+>        ldap_start_tls: Operations error (1)
+>              additional info: TLS already started
+
+When the user (though command line options and/or ldap.conf(5)) has requested 
+TLS (SSL) be started twice. For instance, when specifying both "-H ldaps://server.do.main" and "-ZZ".
+
+H2: Other Errors
+
+H3: ber_get_next on fd X failed errno=34 (Numerical result out of range)
+
+This slapd error generally indicates that the client sent a message that 
+exceeded an administrative limit. See sockbuf_max_incoming and sockbuf_max_incoming_auth 
+configuration directives in slapd.conf(5).
+
+H3: ber_get_next on fd X failed errno=11 (Resource temporarily unavailable)
+
+This message is not indicative of abnormal behavior or error. It simply means 
+that expected data is not yet available from the resource, in this context, a 
+network socket. slapd(8) will process the data once it does becomes available.
+
+H3: daemon: socket() failed errno=97 (Address family not supported)
+
+This message indicates that the operating system does not support one of the 
+(protocol) address families which slapd(8) was configured to support. Most 
+commonly, this occurs when slapd(8) was configured to support IPv6 yet the 
+operating system kernel wasn't. In such cases, the message can be ignored.
+
+H3: GSSAPI: gss_acquire_cred: Miscellaneous failure; Permission denied;
+
+This message means that slapd is not running as root and, thus, it cannot get 
+its Kerberos 5 key from the keytab, usually file /etc/krb5.keytab.
+
+A keytab file is used to store keys that are to be used by services or daemons 
+that are started at boot time. It is very important that these secrets are kept 
+beyond reach of intruders.
+
+That's why the default keytab file is owned by root and protected from being 
+read by others. Do not mess with these permissions, build a different keytab 
+file for slapd instead.
+
+To do this, start kadmin, and enter the following commands:
+
+>     addprinc -randkey ldap/ldap.example.com at EXAMPLE.COM
+>     ktadd -k /etc/openldap/ldap.keytab ldap/ldap.example.com at EXAMPLE.COM 
+
+Then, on the shell, do:
+
+>     chown ldap.ldap /etc/openldap/ldap.keytab
+>     chmod 600 /etc/openldap/ldap.keytab 
+
+Now you have to tell slapd (well, actually tell the gssapi library in Kerberos 5 
+that is invoked by Cyrus SASL) where to find the new keytab. You do this by 
+setting the environment variable KRB5_KTNAME like this:
+
+>     export KRB5_KTNAME="FILE:/etc/openldap/ldap.keytab"
+
+Set that environment variable on the slapd start script (Red Hat users might 
+find /etc/sysconfig/ldap a perfect place).
+
+This only works if you are using MIT kerberos. It doesn't work with Heimdal, 
+for instance.
+
+
+In Heimdal there is a function gsskrb5_register_acceptor_identity() that sets 
+the path of the keytab file you want to use. In Cyrus SASL 2 you can add
+
+>    keytab: /path/to/file
+
+to your application's SASL config file to use this feature. This only works with Heimdal.
+
+
+H3: access from unknown denied
+
+This related to TCP wrappers. See hosts_access(5) for more information.
+in the log file: "access from unknown denied" This related to TCP wrappers. 
+See hosts_access(5) for more information.
+for example: add the line "slapd: .hosts.you.want.to.allow" in /etc/hosts.allow 
+to get rid of the error.
+
+H3: ldap_read: want=# error=Resource temporarily unavailable
+
+This message occurs normally. It means that pending data is not yet available 
+from the resource, a network socket. slapd(8) will process the data once it 
+becomes available.
+
+H3: `make test' fails
+
+Some times, `make test' fails at the very first test with an obscure message like
+
+>    make test
+>    make[1]: Entering directory `/ldap_files/openldap-2.4.6/tests'
+>    make[2]: Entering directory `/ldap_files/openldap-2.4.6/tests'
+>    Initiating LDAP tests for BDB...
+>    Cleaning up test run directory leftover from previous run.
+>     Running ./scripts/all...
+>    >>>>> Executing all LDAP tests for bdb
+>    >>>>> Starting test000-rootdse ...
+>    running defines.sh
+>    Starting slapd on TCP/IP port 9011...
+>    Using ldapsearch to retrieve the root DSE...
+>    Waiting 5 seconds for slapd to start...
+>    ./scripts/test000-rootdse: line 40: 10607 Segmentation fault $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING >$LOG1 2>&1
+>    Waiting 5 seconds for slapd to start...
+>    Waiting 5 seconds for slapd to start...
+>    Waiting 5 seconds for slapd to start...
+>    Waiting 5 seconds for slapd to start...
+>    Waiting 5 seconds for slapd to start...
+>    ./scripts/test000-rootdse: kill: (10607) - No such pid
+>    ldap_sasl_bind_s: Can't contact LDAP server (-1)
+>    >>>>> Test failed
+>    >>>>> ./scripts/test000-rootdse failed (exit 1)
+>    make[2]: *** [bdb-yes] Error 1
+>    make[2]: Leaving directory `/ldap_files/openldap-2.4.6/tests'
+>    make[1]: *** [test] Error 2
+>    make[1]: Leaving directory `/ldap_files/openldap-2.4.6/tests'
+>    make: *** [test] Error 2
+
+or so. Usually, the five lines
+
+    Waiting 5 seconds for slapd to start...
+
+indicate that slapd didn't start at all.
+
+In tests/testrun/slapd.1.log there is a full log of what slapd wrote while 
+trying to start. The log level can be increased by setting the environment 
+variable SLAPD_DEBUG to the corresponding value; see loglevel in slapd.conf(5) 
+for the meaning of log levels.
+
+A typical reason for this behavior is a runtime link problem, i.e. slapd cannot 
+find some dynamic libraries it was linked against. Try running ldd(1) on slapd 
+(for those architectures that support runtime linking).
+
+There might well be other reasons; the contents of the log file should help 
+clarifying them.
+
+Tests that fire up multiple instances of slapd typically log to tests/testrun/slapd.<n>.log, 
+with a distinct <n> for each instance of slapd; list tests/testrun/ for possible 
+values of <n>.
+
+H3: ldap_*: Internal (implementation specific) error (80) - additional info: entry index delete failed
+
+This seems to be related with wrong ownership of the BDB's dir (/var/lib/ldap) 
+and files.
+
+>    chmod -R openldap:openldap /var/lib/ldap 
+
+fixes it in Debian
+
+
+H3: ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1)
+
+Using SASL, when a client contacts LDAP server, the slapd service dies 
+immediately and client gets an error :
+
+>     SASL/GSSAPI authentication started ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1)
+
+Then check the slapd service, it stopped.
+
+This may come from incompatible of using different versions of BerkeleyDB for 
+installing of SASL and installing of OpenLDAP. The problem arises in case of 
+using multiple version of BerkeleyDB. Solution: - Check which version of 
+BerkeleyDB when install Cyrus SASL. 
+
+Reinstall OpenLDAP with the version of BerkeleyDB above.
+

Copied: openldap/trunk/doc/guide/admin/appendix-configs.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/appendix-configs.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/appendix-configs.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/appendix-configs.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,14 @@
+# $OpenLDAP: pkg/openldap-guide/admin/appendix-configs.sdf,v 1.2.2.3 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Configuration File Examples
+
+
+H2: slapd.conf
+
+
+H2: ldap.conf
+
+
+H2: a-n-other.conf

Copied: openldap/trunk/doc/guide/admin/appendix-contrib.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/appendix-contrib.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/appendix-contrib.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/appendix-contrib.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,53 @@
+# $OpenLDAP: pkg/openldap-guide/admin/appendix-contrib.sdf,v 1.1.2.2 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: OpenLDAP Software Contributions
+
+The following sections attempt to summarize the various contributions in OpenLDAP
+software, as found in {{F:openldap_src/contrib}}
+
+H2: Client APIs
+
+Intro and discuss
+
+H3: ldapc++
+
+Intro and discuss
+
+H3: ldaptcl
+
+Intro and discuss
+
+H2: Overlays
+
+Intro and complete/expand correct names for below:
+
+H3: acl
+H3: addpartial
+H3: allop
+H3: comp_match
+H3: denyop
+H3: dsaschema
+H3: lastmod
+H3: passwd
+H3: proxyOld
+H3: smbk5pwd
+H3: trace
+
+
+H2: Tools
+
+Intro and discuss
+
+H3: Statistic Logging
+
+statslog
+
+H2: SLAPI Plugins
+
+Intro and discuss
+
+H3: addrdnvalues
+
+More

Copied: openldap/trunk/doc/guide/admin/appendix-deployments.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/appendix-deployments.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/appendix-deployments.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/appendix-deployments.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,7 @@
+# $OpenLDAP: pkg/openldap-guide/admin/appendix-deployments.sdf,v 1.1.2.2 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Real World OpenLDAP Deployments and Examples
+
+Examples and discussions

Copied: openldap/trunk/doc/guide/admin/appendix-ldap-result-codes.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/appendix-ldap-result-codes.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/appendix-ldap-result-codes.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/appendix-ldap-result-codes.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,265 @@
+# $OpenLDAP: pkg/openldap-guide/admin/appendix-ldap-result-codes.sdf,v 1.1.2.3 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1:  LDAP Result Codes
+
+For the purposes of this guide, we have incorporated the standard LDAP result 
+codes from {{Appendix A.  LDAP Result Codes}} of rfc4511. A copy of which can 
+be found in {{F:doc/rfc}} of the OpenLDAP source code.
+
+We have expanded the description of each error in relation to the OpenLDAP 
+toolsets.
+
+H2:  Non-Error Result Codes
+
+These result codes (called "non-error" result codes) do not indicate
+an error condition:
+
+>        success (0),
+>        compareFalse (5),
+>        compareTrue (6),
+>        referral (10), and
+>        saslBindInProgress (14).
+
+The {{success}}, {{compareTrue}}, and {{compareFalse}} result codes indicate
+successful completion (and, hence, are referred to as "successful"
+result codes).
+
+The {{referral}} and {{saslBindInProgress}} result codes indicate the client
+needs to take additional action to complete the operation.
+
+H2:  Result Codes
+
+Existing LDAP result codes are described as follows:
+
+H2: {{success (0)}}
+
+Indicates the successful completion of an operation.  
+
+Note: this code is not used with the Compare operation.  See {{SECT:compareFalse (5)}} 
+and {{SECT:compareTrue (6)}}.
+
+H2: {{operationsError (1)}}
+
+Indicates that the operation is not properly sequenced with
+relation to other operations (of same or different type).
+
+For example, this code is returned if the client attempts to
+StartTLS [RFC4346] while there are other uncompleted operations
+or if a TLS layer was already installed.
+
+H2: {{protocolError (2)}}
+
+Indicates the server received data that is not well-formed.
+
+For Bind operation only, this code is also used to indicate
+that the server does not support the requested protocol
+version.
+
+For Extended operations only, this code is also used to
+indicate that the server does not support (by design or
+configuration) the Extended operation associated with the
+{{requestName}}.
+
+For request operations specifying multiple controls, this may
+be used to indicate that the server cannot ignore the order
+of the controls as specified, or that the combination of the
+specified controls is invalid or unspecified.
+
+H2: {{timeLimitExceeded (3)}}
+
+Indicates that the time limit specified by the client was
+exceeded before the operation could be completed.
+
+H2: {{sizeLimitExceeded (4)}}
+
+Indicates that the size limit specified by the client was
+exceeded before the operation could be completed.
+
+H2: {{compareFalse (5)}}
+
+Indicates that the Compare operation has successfully
+completed and the assertion has evaluated to FALSE or
+Undefined.
+
+H2: {{compareTrue (6)}}
+
+Indicates that the Compare operation has successfully
+completed and the assertion has evaluated to TRUE.
+
+H2: {{authMethodNotSupported (7)}}
+
+Indicates that the authentication method or mechanism is not
+supported.
+
+H2: {{strongerAuthRequired (8)}}
+
+Indicates the server requires strong(er) authentication in
+order to complete the operation.
+
+When used with the Notice of Disconnection operation, this
+code indicates that the server has detected that an
+established security association between the client and
+server has unexpectedly failed or been compromised.
+
+H2: {{referral (10)}}
+
+Indicates that a referral needs to be chased to complete the
+operation (see Section 4.1.10).
+
+H2: {{adminLimitExceeded (11)}}
+
+Indicates that an administrative limit has been exceeded.
+
+H2: {{unavailableCriticalExtension (12)}}
+
+Indicates a critical control is unrecognized (see Section
+4.1.11).
+
+H2: {{confidentialityRequired (13)}}
+
+Indicates that data confidentiality protections are required.
+
+H2: {{saslBindInProgress (14)}}
+
+Indicates the server requires the client to send a new bind
+request, with the same SASL mechanism, to continue the
+authentication process (see Section 4.2).
+
+H2: {{noSuchAttribute (16)}}
+
+Indicates that the named entry does not contain the specified
+attribute or attribute value.
+
+H2: {{undefinedAttributeType (17)}}
+
+Indicates that a request field contains an unrecognized
+attribute description.
+
+H2: {{inappropriateMatching (18)}}
+
+Indicates that an attempt was made (e.g., in an assertion) to
+use a matching rule not defined for the attribute type
+concerned.
+
+H2: {{constraintViolation (19)}}
+
+Indicates that the client supplied an attribute value that
+does not conform to the constraints placed upon it by the
+data model.
+
+For example, this code is returned when multiple values are
+supplied to an attribute that has a SINGLE-VALUE constraint.
+
+H2: {{attributeOrValueExists (20)}}
+
+Indicates that the client supplied an attribute or value to
+be added to an entry, but the attribute or value already
+exists.
+
+H2: {{invalidAttributeSyntax (21)}}
+
+Indicates that a purported attribute value does not conform
+to the syntax of the attribute.
+
+H2: {{noSuchObject (32)}}
+
+Indicates that the object does not exist in the DIT.
+
+H2: {{aliasProblem (33)}}
+
+Indicates that an alias problem has occurred.  For example,
+the code may used to indicate an alias has been dereferenced
+that names no object.
+
+H2: {{invalidDNSyntax (34)}}
+
+Indicates that an LDAPDN or RelativeLDAPDN field (e.g., search
+base, target entry, ModifyDN newrdn, etc.) of a request does
+not conform to the required syntax or contains attribute
+values that do not conform to the syntax of the attribute's
+type.
+
+H2: {{aliasDereferencingProblem (36)}}
+
+Indicates that a problem occurred while dereferencing an
+alias.  Typically, an alias was encountered in a situation
+where it was not allowed or where access was denied.
+
+H2: {{inappropriateAuthentication (48)}}
+
+Indicates the server requires the client that had attempted
+to bind anonymously or without supplying credentials to
+provide some form of credentials.
+
+H2: {{invalidCredentials (49)}}
+
+Indicates that the provided credentials (e.g., the user's name
+and password) are invalid.
+
+H2: {{insufficientAccessRights (50)}}
+
+Indicates that the client does not have sufficient access
+rights to perform the operation.
+
+H2: {{busy (51)}}
+
+Indicates that the server is too busy to service the
+operation.
+
+H2: {{unavailable (52)}}
+
+Indicates that the server is shutting down or a subsystem
+necessary to complete the operation is offline.
+
+H2: {{unwillingToPerform (53)}}
+
+Indicates that the server is unwilling to perform the
+operation.
+
+H2: {{loopDetect (54)}}
+
+Indicates that the server has detected an internal loop (e.g.,
+while dereferencing aliases or chaining an operation).
+
+H2: {{namingViolation (64)}}
+
+Indicates that the entry's name violates naming restrictions.
+
+H2: {{objectClassViolation (65)}}
+
+Indicates that the entry violates object class restrictions.
+
+H2: {{notAllowedOnNonLeaf (66)}}
+
+Indicates that the operation is inappropriately acting upon a
+non-leaf entry.
+
+H2: {{notAllowedOnRDN (67)}}
+
+Indicates that the operation is inappropriately attempting to
+remove a value that forms the entry's relative distinguished
+name.
+
+H2: {{entryAlreadyExists (68)}}
+
+Indicates that the request cannot be fulfilled (added, moved,
+or renamed) as the target entry already exists.
+
+H2: {{objectClassModsProhibited (69)}}
+
+Indicates that an attempt to modify the object class(es) of
+an entry's 'objectClass' attribute is prohibited.
+
+For example, this code is returned when a client attempts to
+modify the structural object class of an entry.
+
+H2: {{affectsMultipleDSAs (71)}}
+
+Indicates that the operation cannot be performed as it would
+affect multiple servers (DSAs).
+
+H2: {{other (80)}}
+
+Indicates the server has encountered an internal error.

Copied: openldap/trunk/doc/guide/admin/appendix-recommended-versions.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/appendix-recommended-versions.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/appendix-recommended-versions.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/appendix-recommended-versions.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,35 @@
+# $OpenLDAP: pkg/openldap-guide/admin/appendix-recommended-versions.sdf,v 1.3.2.2 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Recommended OpenLDAP Software Dependency Versions
+
+This appendix details the recommended versions of the software 
+that OpenLDAP depends on. 
+
+Please read the {{SECT:Prerequisite software}} section for more 
+information on the following software dependencies.
+
+H2: Dependency Versions
+
+!block table; align=Center; coltags="N,EX,EX"; title="Table 8.5: OpenLDAP Software Dependency Versions"
+Feature|Software|Version
+{{TERM[expand]TLS}}:
+|{{PRD:OpenSSL}}|0.9.7+
+|{{PRD:GnuTLS}}|2.0.1
+{{TERM[expand]SASL}}|{{PRD:Cyrus SASL}}|2.1.21+
+{{TERM[expand]Kerberos}}:
+|{{PRD:Heimdal}}|Version
+|{{PRD:MIT Kerberos}}|Version
+Database Software|{{PRD:Berkeley DB}}:|
+||4.2
+||4.4
+||4.5
+||4.6
+||Note: It is highly recommended to apply the patches from for a given release.
+Threads:
+|POSIX {{pthreads}}|Version
+|Mach {{CThreads}}|Version
+TCP Wrappers|Name|Version
+!endblock
+

Copied: openldap/trunk/doc/guide/admin/appendix-upgrading.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/appendix-upgrading.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/appendix-upgrading.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/appendix-upgrading.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,44 @@
+# $OpenLDAP: pkg/openldap-guide/admin/appendix-upgrading.sdf,v 1.1.2.3 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Upgrading from 2.3.x
+
+The following sections attempt to document the steps you will need to take in order 
+to upgrade from the latest 2.3.x OpenLDAP version.
+
+The normal upgrade procedure, as discussed in the {{SECT:Maintenance}} section, should 
+of course still be followed prior to doing any of this.
+
+H2: Monitor Backend
+
+Note: This is a temporary requirement and is subject to change over the next 2.4.x beta release cycle
+
+A monitor ({{slapd-monitor(5)}}) now needs a {{rootdn}} entry. If you do not have
+one, {{slapd}} will fail to start up with an error message like so:
+
+>           monitor_back_register_entry_attrs(""): base="cn=databases,cn=monitor" scope=one
+>           filter="(namingContexts:distinguishedNameMatch:=dc=example,dc=com)": unable to find entry
+>           backend_startup_one: bi_db_open failed! (1)
+>           slap_startup failed (test would succeed using the -u switch)
+
+Here is a complete {{database monitor}} example:
+
+
+>           database monitor
+>           rootdn cn=monitor
+>           rootpw change_me
+
+
+H2: {{B:cn=config}} olc* attributes
+
+Quite a few {{olc*}} attributes have now become obsolete, if you see in your logs 
+entries like below, just remove them from the relevant ldif file.
+
+>           olcReplicationInterval: value #0: <olcReplicationInterval> keyword is obsolete (ignored)
+
+
+
+
+ADD MORE HERE
+

Copied: openldap/trunk/doc/guide/admin/aspell.en.pws (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/aspell.en.pws)
===================================================================
--- openldap/trunk/doc/guide/admin/aspell.en.pws	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/aspell.en.pws	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,1492 @@
+personal_ws-1.1 en 1491 
+nattrsets
+inappropriateAuthentication
+api
+olcAttributeTypes
+BhY
+reqEnd
+olcOverlayConfig
+shoesize
+olcTLSCACertificateFile
+CGI
+cdx
+DCE
+DAP
+attributename
+lsei
+dbconfig
+arg
+kurt
+authzID
+authzid
+authzId
+DAs
+ddd
+userApplications
+BNF
+attrs
+mixin
+wholeSubtree
+chainingRequired
+ldapport
+hallvard
+ASN
+acknowledgements
+Chu
+ava
+monitorCounter
+del
+DDR
+testObject
+OrgPerson
+IGJlZ
+olcUpdateref
+ECC
+deleteDN
+cli
+ltdl
+CAPI
+dev
+serverctrls
+olcDbDirectory
+xvfB
+BSI
+modv
+nonleaf
+errCode
+PhotoURI
+buf
+cdef
+monitorConnectionLocalAddress
+dir
+EGD
+dit
+retoidp
+ando
+edu
+caseExactSubstringsMatch
+bvstrdup
+AUTHNAME
+memrealloc
+auditExtended
+replog
+ludp
+metainformation
+CRL
+CRP
+olcReferral
+XLDFLAGS
+metadirectory
+csn
+siiiib
+stateful
+olcModulePath
+maxentries
+authc
+seeAlso
+searchbase
+searchBase
+realnamingcontext
+dn's
+DNs
+DN's
+dns
+dereference
+sortKey
+authzTo
+lossy
+gcc
+CWD
+lssl
+organizationalRole
+DSA
+derefInSearching
+pwdGraceUseTime
+DSE
+groupOfURLs
+modrdn
+ModRDN
+modrDN
+pwdFailureCountInterval
+homePhone
+eng
+paramName
+errUnsolicitedData
+Heimdal
+EOF
+authz
+XINCPATH
+LTFINISH
+plaintext
+indices
+reqAssertion
+olcDbUri
+dst
+env
+oplist
+MirrorMode
+mirrormode
+objclass
+Bint
+dup
+hdb
+gid
+stderr
+caseIgnoreOrderingMatch
+moduledir
+gif
+jpegPhoto
+lsasl
+judgmentday
+prepend
+subentry
+dbcache
+mkversion
+objectClasses
+objectclasses
+adminLimitExceeded
+searchResultReference
+fmt
+qdescrs
+olcSuffix
+objectClassModsProhibited
+unavailableCriticalExtension
+supportedControl
+GHz
+libpath
+INADDR
+compareDN
+sizelimit
+unixODBC
+notAllowedOnNonLeaf
+APIs
+blen
+attrsOnly
+attrsonly
+slappasswd
+referralsPreferred
+oids
+OIDs
+wBDARESEhgVG
+syncIdSet
+olcTLSCipherSuite
+username
+aliasProblem
+sizeLimitExceeded
+subst
+idl
+chroot
+iff
+auditDelete
+numbits
+ZKKuqbEKJfKSXhUbHG
+reqRespControls
+TLSCertificateKeyFile
+olcAccess
+aliasDereferencingProblem
+proxyTemplates
+neverDerefaliases
+RootDN
+rootdn
+loglevel
+args
+caseExactOrderingMatch
+olcDbQuarantine
+RELEASEDATE
+baseDN
+basedn
+argv
+gss
+schemachecking
+whoami
+WhoAmI
+syslogd
+dataflow
+subentries
+attrpair
+balancer
+entryAlreadyExists
+BerkeleyDB's
+notAllowedOnRDN
+singleLevel
+entryDN
+dSAOperation
+includedir
+inplace
+LDAPAPIFeatureInfo
+logbase
+ldapmaster
+ing
+moduleload
+IPC
+Makefile
+getpid
+GETREALM
+numericString
+MANSECT
+XXXX
+domainstyle
+bvarray
+Choi
+iscritical
+subschema
+slapindex
+plugin
+distinguishedNameMatch
+derefAliases
+baseObject
+kdz
+reqMod
+ldb
+srcdir
+pwdExpireWarning
+ldd
+localstatedir
+sockbuf
+PENs
+ipv
+IPv
+ghenry
+hyc
+multimaster
+noop
+DEFS
+joe
+testAttr
+syncrepl
+pwdFailureTime
+timestamp
+whitespaces
+ISP
+ldp
+monitorInfo
+PDUs
+bjensen
+newPasswd
+irresponsive
+len
+perl
+dynlist
+browseable
+posixGroup
+attrvalue
+pers
+retcode
+rootpw
+matchedDN
+auditReadObject
+idletimeout
+intermediateResponse
+myOID
+structuralObjectClass
+integerMatch
+openldap
+OpenLDAP
+moddn
+rewriteEngine
+AVAs
+accesslog
+searchDN
+reqOld
+MDn
+aspell
+TLSCACertificateFile
+mem
+peername
+syncUUIDs
+database's
+krb
+bool
+logins
+jts
+memberAttr
+newpasswdfile
+newPasswdFile
+ucdata
+LLL
+confdir
+invalidCredentials
+BerValues
+olcDbLinearIndex
+Elfrink
+AUTOREMOVE
+countp
+realloc
+bsize
+CThreads
+structs
+desc
+LTCOMPILE
+bindmethod
+olcDbCheckpoint
+addprinc
+modme
+refreshOnly
+PIII
+pwdPolicySubentry
+supportedSASLmechanism
+supportedSASLMechanism
+FIXME
+realanonymous
+caseExactMatch
+olcSizeLimit
+Bourne
+attr
+objectidentifier
+objectIdentifier
+refint
+msgtype
+OBJEXT
+LRL
+subtrees
+realdnattr
+entrymods
+admittable
+libtool's
+dupbv
+searchResultEntry
+lud
+modifyTimestamp
+TLSEphemeralDHParamFile
+LRU
+syncprov
+strvals
+preread
+auth
+nis
+regexec
+adamsom
+objclasses
+deallocation
+strdup
+gsMatch
+adamson
+UniqueName
+LVL
+ppErrStr
+DESTDIR
+oid
+saslpasswd
+interoperate
+bindwhen
+Solaris
+oOjM
+msg
+submatch
+refreshAndPersist
+monitorServer
+attributeUsage
+soelim
+objectIdentiferMatch
+olc
+PEM
+Autoconf
+alloc
+PDU
+OLF
+inetorgperson
+inetOrgPerson
+deleteoldrdn
+monitorCounterObject
+pid
+CPAN
+sharedstatedir
+OLP
+LDFLAGS
+dereferencing
+allop
+errcodep
+xeXBkeFxlZ
+accessor's
+extendedop
+ple
+NTP
+reqSizeLimit
+ORed
+NUL
+namingContexts
+num
+reqAttrsOnly
+ldappasswd
+online
+libdir
+unindexed
+ObjectClassDescription
+attrdesc
+jsmith
+efgh
+exopPasswdDN
+ranlib
+olcAttributeOptions
+lineno
+storages
+nameAndOptionalUID
+png
+INCPATH
+organizationalPerson
+integerOrderingMatch
+OSI
+subschemaSubentry
+cond
+conf
+rfc
+bvec
+rdn
+ECHOPROMPT
+RDBM
+subany
+runningslapd
+configs
+datagram
+crlcheck
+conn
+builddir
+OTP
+entrylimit
+attrdescN
+logold
+pos
+sbi
+PRD
+reqEntries
+pre
+bvals
+unixusers
+olcReadonly
+olcReadOnly
+pwdChangedTime
+mySQL
+DITs
+sdf
+suffixmassage
+referralDN
+sed
+statslog
+perror
+ldapexop
+bvecadd
+distributedOperation
+sel
+versa
+TBC
+telephonenumber
+telephoneNumber
+DLDAP
+peernamestyle
+Sep
+SHA
+filename
+rpath
+argsfile
+ptr
+INCDIR
+pwd
+dctree
+rnd
+quanah
+lastmod
+TCL
+sprintf
+shm
+logops
+dnattr
+subdir
+searchAttrDN
+cctrls
+tcp
+kadmin
+undefinedAttributeType
+strlen
+spellcheck
+ludpp
+typedef
+olcDbIDLcacheSize
+ostring
+toolsets
+mwrscdx
+SMD
+UCD
+cancelled
+crit
+organizationalUnit
+lucyB
+slp
+rdns
+CPUs
+TGT
+modulepath
+quickstart
+mySNMP
+tgz
+UDP
+RDBMs
+rdbms
+Matic
+qdstring
+gunzip
+librewrite
+UFl
+src
+lastName
+ufn
+cron
+RelativeLDAPDN
+sql
+pwdPolicyChecker
+uid
+olcDbConfig
+refreshDone
+ssf
+replogfile
+rwm
+TOC
+vec
+LDAPDN
+compareAttrDN
+endmacro
+tls
+repl
+monitoringslapd
+referralsp
+tmp
+SRP
+olcDbNosync
+conns
+SSL
+PDkzODdASFxOQ
+SRV
+rwx
+sss
+deallocators
+Contribware
+URLlist
+str
+subinitial
+CSNs
+sbin
+dbtools
+datasource
+sbio
+posp
+errText
+prepended
+labeledURI
+scdx
+startup
+const
+wBDABALD
+octetStringSubstringsStringMatch
+ttl
+bvalue
+bvdup
+stringa
+stringb
+hasSubordinates
+oldPasswd
+sys
+pwdPolicy
+slapd
+affectsMultipleDSAs
+sasl
+slapauth
+MANCOMPRESS
+octetStringOrderingStringMatch
+updatedn
+UpdateDN
+slapdindex
+searchFilter
+uri
+slapi
+tty
+liblunicode
+url
+entryExpireTimestamp
+priv
+slapo
+UTF
+vlv
+ctrl
+TXN
+virtualnamingcontext
+eatBlanks
+slimit
+ldaprc
+usr
+txt
+proc
+generalizedTime
+loopback
+unmassaged
+mechs
+freemods
+initgroups
+auditCompare
+GDBM
+DSAs
+DSA's
+dsaschema
+compareFalse
+resultCode
+resultcode
+noSuchObject
+params
+groupnummer
+searchEntryDN
+negttl
+chainingPreferred
+TABs
+retdatap
+errAuxObject
+postoperation
+realself
+olcPasswordHash
+concat
+debuglevel
+addAttrDN
+credp
+ldaphost
+pwdMaxFailure
+octetStringMatch
+extparam
+auditWriteObject
+colaligns
+Diffie
+offsite
+attributevalue
+AttributeValue
+SIGTERM
+MyCompany
+al
+AAQSkZJRgABAAAAAQABAAD
+cd
+contextCSN
+ar
+pthreads
+monitorTimestamp
+de
+reqAuthzID
+backend's
+backends
+requestName
+cn
+lcrypto
+infodir
+groupstyle
+ldapsearch
+cp
+displayName
+eg
+bv
+olcBackendConfig
+dn
+fd
+LDAPSync
+olcReplicationInterval
+fG
+gidNumber
+fi
+Instanstantiation
+eq
+FIPS
+dx
+et
+eu
+hh
+olcLogLevel
+slurpd
+logevels
+IG
+addDN
+tbls
+ldapmodify
+kb
+syslog
+io
+ip
+dynacl
+aXRoIGEgc
+enum
+slapdconf
+reqFilter
+ld
+xyz
+TLSCertificateFile
+idassert
+failover
+kerberos
+lookups
+md
+iZ
+SysNet
+BerValue
+idlcachesize
+struct
+UCASE
+errno
+syslogged
+mk
+ng
+oc
+invalidAttributeSyntax
+errOp
+pwdMaxAge
+insufficientAccessRights
+truelies
+NL
+mr
+reindex
+newentry
+ok
+mv
+preinstalled
+regex
+saslmech
+rc
+config
+ou
+policyDN
+sb
+olcSyncrepl
+QN
+strtol
+runtime
+NOSYNC
+slapover
+RL
+sockname
+noSuchAttribute
+MANCOMPRESSSUFFIX
+makeinfo
+coltags
+ro
+rp
+EXEEXT
+sockurl
+th
+sn
+ru
+UG
+ss
+su
+TP
+reqMethod
+XLIBS
+PhotoObject
+tt
+keycol
+namingContext
+rlookups
+searchstack
+NOECHOPROMPT
+sldb
+wi
+AlmostASearchRequest
+xf
+param
+MChAODQ
+caseExactIA
+Za
+Vu
+idlecachesize
+objectClassViolation
+allusers
+ws
+errSleepTime
+INSTALLFLAGS
+pthread
+pwdHistory
+x's
+Debian
+slen
+errUnsolicitedOID
+dyngroup
+filtertype
+rewriteRules
+criticality
+preoperation
+smbk
+subord
+reqVersion
+errp
+ZZ
+entryCSNs
+dlopen
+continuated
+newsuperior
+newSuperior
+Preprocessor
+XXLIBS
+deallocate
+reqScope
+llber
+bitstringa
+sbindir
+apache's
+noidlen
+monitorContext
+testrun
+resync
+fqdn
+authPassword
+LDAPMatchingRule
+olcIdleTimeout
+treedelete
+auditAdd
+reqSession
+derated
+LDVERSION
+IANA
+olcDbSearchStack
+bitstrings
+rscdx
+schemas
+minssf
+ldapadd
+pseudorootdn
+lldap
+gssapi
+applicatio
+nelems
+liblutil
+wrscdx
+scherr
+internet
+logfilter
+lutil
+themself
+libexec
+dnpattern
+proxying
+reqType
+Kartik
+libexecdir
+inetd
+pwdSafeModify
+contrib
+FQDNs
+bjorn
+myldap
+myLDAP
+peercred
+SNMP
+myObjectClass
+thru
+olcLastMod
+commonName
+testTwo
+olcFrontendConfig
+LDAPObjectClass
+attributeTypes
+LTINSTALL
+hostname
+Symas
+numattrsets
+msgid
+ldapmodrdn
+ldapbis
+attributeoptions
+serverID
+memberOf
+memberof
+pseudorootpw
+allmail
+CFLAGS
+operationsError
+substr
+pwdAllowUserChange
+rewriteRule
+XXXXXXXXXX
+credlen
+departmentNumber
+rewriteMap
+logfile
+vals
+LDAPAVA
+modifyAttrDN
+dcedn
+olcOverlay
+exop
+berelement
+BerElement
+olcRootDN
+octetString
+SampleLDAP
+expr
+allusersgroup
+PostgreSQL
+bvstr
+filesystem
+pathtest
+objectClass
+objectclass
+submatches
+newrdn
+armijo
+addBlanks
+reqMessage
+exts
+SSHA
+func
+filterlist
+modifyDN
+jane
+syncuser
+Masarati
+LDAPSyntax
+oldpasswdfile
+oldPasswdFile
+reqDN
+SSFs
+ietf
+unwillingToPerform
+oidlen
+searchFilterAttrDN
+CPPFLAGS
+slapadd
+Clatworthy
+urldesc
+substrings
+Apurva
+slapacl
+multiclassing
+monitoredInfo
+LTLINK
+addrdnvalues
+KTNAME
+ETCDIR
+reqId
+setspec
+scanf
+TLSv
+distinguishedname
+distinguishedName
+BerVarray
+caseIgnoreSubstrin
+ldapwhoami
+URLattr
+generalizedTimeOrderingMatch
+requestdata
+timelimit
+subr
+cachesize
+olcRootPW
+SSLv
+proxyOld
+domainScope
+LDAPMessage
+LTVERSION
+memalloc
+refreshDeletes
+BerkeleyDB
+pathspec
+uint
+Poitou
+whitespace
+dynstyle
+slaptest
+zeilenga
+WebUpdate
+numericoid
+changelog
+ChangeLog
+creatorsName
+ascii
+wahl
+uniqueMember
+slapcat
+lwrap
+ldapfilter
+errDisconnect
+sermersheim
+rootdns
+searchResult
+libtool
+servercredp
+AttributeTypeDescription
+LTFLAGS
+simplebinddn
+authcDN
+TLSCipherSuite
+supportedSASLMechanisms
+rootdse
+rootDSE
+dsaparam
+cachefree
+UMich's
+uidNumber
+schemadir
+attribute's
+extern
+varchar
+olcDbCacheSize
+olcDbCachesize
+authcid
+authcID
+POSIX
+hnPk
+ldapext
+authzFrom
+Google
+olcSchemaConfig
+newsup
+sbiod
+XXXLIBS
+LDAPBASE
+Supr
+olcDatabaseConfig
+rwxrwxrwx
+aeeiib
+SUPs
+reqStart
+sasldb
+somevalue
+LIBRELEASE
+randkey
+starttls
+StartTLS
+LDAPSchemaExtensionItem
+reqReferral
+shtool
+Pierangelo
+attrstyle
+backend
+portnumber
+subjectAltName
+errObject
+gsskrb
+valsort
+bervals
+berval's
+derefFindingBaseObj
+checkpointed
+keytab
+groupnaam
+frontend
+sctrls
+dbnum
+olcLdapConfig
+sessionlog
+attrset
+organizationPerson
+entryCSN
+strcast
+kbyte
+modifiersName
+keytbl
+olcHdbConfig
+constraintViolation
+README
+memcalloc
+inet
+saslargs
+givenname
+givenName
+olcDbMode
+pidfile
+olcLimits
+memvfree
+tuple
+superset
+directoryString
+ktadd
+proxyTemplate
+proxytemplate
+wildcards
+monitoredObject
+TTLs
+LxsdLy
+olcTimeLimit
+stringal
+init
+Locators
+bvalues
+reqResult
+impl
+strongerAuthRequired
+outvalue
+returnCode
+returncode
+attributeDescription
+attrval
+dnssrv
+ciphersuite
+auditlog
+reqControls
+protocolError
+notypes
+myAttributeType
+stringbv
+keyval
+calloc
+chmod
+Subbarao
+setstyle
+subdirectories
+errlist
+addpartial
+slapdn
+uncached
+ldapapiinfo
+groupOfUniqueNames
+dhparam
+slapd's
+slapds
+inputfile
+RDBMSes
+wildcard
+Locator
+errAbsObject
+errABsObject
+SASL's
+html
+searchResultDone
+olcBdbConfig
+ldapmod
+LDAPMod
+olcHidden
+userPassword
+TLSRandFile
+use'd
+auditBind
+requestDN
+lockdetect
+selfstyle
+liblber
+ERXRTc
+printf
+AutoConfig
+localhost
+lber
+noprompt
+databasenumber
+hasSubordintes
+URIs
+denyop
+lang
+auditSearch
+ldapdelete
+reqTimeLimit
+cacertdir
+queryid
+Warper
+XDEFS
+urls
+URL's
+postalAddress
+postaladdress
+passwd
+plugins
+george
+http
+uppercased
+Poobah
+libldap
+invalidDNSyntax
+ldap
+ldbm
+ursula
+LDAPModifying
+slapdconfig
+sysconfig
+dnSubtreeMatch
+olcSaslSecProps
+olcSaslSecprops
+auditModify
+groupOfNames
+jensen
+reloadHint
+prepending
+olcGlobal
+matchingRule
+matchingrule
+SmVuc
+MSSQL
+nisMailAlias
+hostnames
+ctrlp
+lltdl
+ctrls
+rewriter
+secprops
+namespace
+whsp
+realusers
+dnstyle
+suffixalias
+proxyAttrset
+proxyAttrSet
+proxyattrset
+pwdMustChange
+ldif
+bvfree
+sleeptime
+pwdCheckQuality
+msgidp
+confidentialityRequired
+pwdAttribute
+authMethodNotSupported
+chown
+PRNGD
+LDAPRDN
+entryUUIDs
+proxycache
+proxyCache
+SERATGCgaGBYWGDEjJR
+noanonymous
+accessee
+createTimestamp
+nretries
+auditAbandon
+LDAPAttributeType
+logdb
+procs
+realdn
+alwaysDerefAliases
+ppolicy
+jpeg
+functionalities
+pcache
+caseIgnoreMatch
+sysconfdir
+checkpointing
+rebindproc
+dryrun
+noplain
+exattrs
+Jong
+ldaptcl
+proxied
+firstName
+accesslevel
+login
+rewriteContext
+dcObject
+newparent
+numericStringMatch
+TLSVerifyClient
+subtree
+multi
+immSupr
+manpage
+assciated
+wZFQrDD
+serverctrlsp
+onelevel
+abcd
+reqcert
+referralsRequired
+Hyuk
+olcServerID
+reqDerefAliases
+newSuperiorDN
+passwdfile
+errMatchedDN
+everytime
+mkdep
+olcDbindex
+olcDbIndex
+syntaxOID
+reqData
+databasetype
+woid
+numericStringOrderingMatch
+clientctrls
+inappropriateMatching
+RetCodes
+ldapc
+pwdAccountLockedTime
+attrtype
+LIBVERSION
+proto
+endif
+logfiles
+reqNewRDN
+ldapi
+notoc
+matcheddnp
+mkdir
+mech
+pwdMinAge
+ldaps
+userCertificate
+LDAPv
+IPsec
+tokenization
+olcModuleList
+robert
+generalizedTimeMatch
+UMLDAP
+OpenLDAP's
+lookup
+ABNF
+olcDbShmKey
+pwdLockoutDuration
+TLSCACertificatePath
+ldapuri
+ldapurl
+ACIs
+behera
+olcObjectIdentifier
+endblock
+proxyAuthz
+pagedResults
+saslBindInProgress
+bitstring
+ACLs
+berptr
+olcModuleLoad
+namingViolation
+attributetype
+attributeType
+auditModRDN
+cacert
+memberUid
+freebuf
+IDSET
+pwdGraceAuthnLimit
+invalue
+XKYnrjvGT
+srvtab
+referralAttrDN
+requestoid
+basename
+substring
+booleanMatch
+babs
+pPasswd
+msgfree
+slapdconfigfile
+olcDatabase
+builtin
+hardcoded
+SIGINT
+MAXLEN
+xpasswd
+cleartext
+extensibleObject
+pwdLockout
+SIGHUP
+reqDeleteOldRDN
+reqAttr
+subfinal
+berval
+octothorpe
+LTONLY
+filesystems
+urandom
+NDBM
+abcdefgh
+olcBackend
+errmsgp
+boolean
+updateref
+regcomp
+contextp
+filtercomp
+LDAPNOINIT
+deref
+preallocated
+syntaxes
+memberURL
+monitorRuntimeConfig
+bindDn
+bindDN
+binddn
+methodp
+timeLimitExceeded
+timelimitExceeded
+pwdInHistory
+LTSTATIC
+requestors
+requestor's
+LDAPCONF
+saslauthd
+MKDEPFLAG
+gecos
+entryUUID
+gnutls
+GNUtls
+GnuTLS
+postread
+timeval
+DHAVE
+loopDetect
+caseIgnoreSubstringsMatch
+monitorIsShadow
+syncdata
+BDB's
+olcPidFile
+hostport
+backload
+bindir
+olcObjectClasses
+auditObject
+LDIFv
+strcasecmp
+LTHREAD
+dereferenced
+entryTtl
+LDAPControl
+pwdMinLength
+ldapcompare
+readonly
+readOnly
+RANDFILE
+attrlist
+aci
+directoryOperation
+compareTrue
+selfwrite
+pwdReset
+acl
+attrname
+ADH
+searchable
+bindmethods
+logpurge
+reqNewSuperior
+multiproxy
+dereferences
+datadir
+malloc
+UUIDs
+veryclean
+userid
+Kumar
+AES
+bdb
+attributeOrValueExists
+manageDSAit
+ManageDsaIT
+bindpw
+monitorContainer
+pEntry
+baz
+memfree
+lresolv
+objectIdentifierMatch
+Blowfish
+mkln
+numericStringSubstringsMatch
+testgroup
+openssl
+OpenSSL
+ModName
+cacheable
+freeit
+pathname
+ber
+ali
+mandir
+changetype
+CAs
+CA's
+typeA
+bvecfree
+ODBC
+typeB
+unescaped
+devel
+pwdCheckModule
+LDAPURLDesc
+authzDN

Copied: openldap/trunk/doc/guide/admin/backends.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/backends.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/backends.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/backends.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,262 @@
+# $OpenLDAP: pkg/openldap-guide/admin/backends.sdf,v 1.8.2.3 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Backends
+
+
+H2: Berkeley DB Backends
+
+
+H3: Overview
+
+The {{bdb}} backend to {{slapd}}(8) is the recommended primary backend for a 
+normal {{slapd}} database.  It uses the Oracle Berkeley DB ({{TERM:BDB}}) 
+package to store data. It makes extensive use of indexing and caching 
+(see the {{SECT:Tuning}} section) to speed data access.
+
+{{hdb}} is a variant of the {{bdb}} backend that uses a hierarchical database 
+layout which supports subtree renames. It is otherwise identical to the {{bdb}}
+ behavior, and all the same configuration options apply.
+
+Note: An {{hdb}} database needs a large {{idlcachesize}} for good search performance, 
+typically three times the {{cachesize}} (entry cache size) or larger.
+
+H3: back-bdb/back-hdb Configuration
+
+MORE LATER
+
+H3: Further Information
+
+{{slapd-bdb}}(5)
+
+H2: LDAP
+
+
+H3: Overview
+
+The LDAP backend to {{slapd}}(8) is not an actual database; instead it acts 
+as a proxy to forward incoming requests to another LDAP server. While 
+processing requests it will also chase referrals, so that referrals are fully
+processed instead of being returned to the {{slapd}} client.
+
+Sessions that explicitly {{Bind}} to the {{back-ldap}} database always create 
+their own private connection to the remote LDAP server. Anonymous sessions 
+will share a single anonymous connection to the remote server. For sessions 
+bound through other mechanisms, all sessions with the same DN will share the 
+same connection. This connection pooling strategy can enhance the proxy’s 
+efficiency by reducing the overhead of repeatedly making/breaking multiple 
+connections.
+
+The ldap database can also act as an information service, i.e. the identity 
+of locally authenticated clients is asserted to the remote server, possibly 
+in some modified form. For this purpose, the proxy binds to the remote server 
+with some administrative identity, and, if required, authorizes the asserted 
+identity. 
+
+H3: back-ldap Configuration
+
+LATER
+
+H3: Further Information
+
+{{slapd-ldap}}(5)
+
+H2: LDIF
+
+
+H3: Overview
+
+The LDIF backend to {{slapd}}(8) is a basic storage backend that stores 
+entries in text files in LDIF format, and exploits the filesystem to create 
+the tree structure of the database. It is intended as a cheap, low performance 
+easy to use backend.
+
+When using the {{cn=config}} dynamic configuration database with persistent
+storage, the configuration data is stored using this backend. See {{slapd-config}}(5)
+for more information
+
+H3: back-ldif Configuration
+
+LATER
+
+H3: Further Information
+
+{{slapd-ldif}}(5)
+
+H2: Metadirectory
+
+
+H3: Overview
+
+The meta backend to {{slapd}}(8) performs basic LDAP proxying with respect 
+to a set of remote LDAP servers, called "targets". The information contained 
+in these servers can be presented as belonging to a single Directory Information 
+Tree ({{TERM:DIT}}).
+
+A basic knowledge of the functionality of the {{slapd-ldap}}(5) backend is 
+recommended. This backend has been designed as an enhancement of the ldap 
+backend. The two backends share many features (actually they also share portions
+ of code). While the ldap backend is intended to proxy operations directed 
+ to a single server, the meta backend is mainly intended for proxying of 
+ multiple servers and possibly naming context  masquerading.
+
+These features, although useful in many scenarios, may result in excessive 
+overhead for some applications, so its use should be carefully considered.
+
+
+H3: back-meta Configuration
+
+LATER
+
+H3: Further Information
+
+{{slapd-meta}}(5)
+
+H2: Monitor
+
+
+H3: Overview
+
+The monitor backend to {{slapd}}(8) is not an actual database; if enabled, 
+it is automatically generated and dynamically maintained by slapd with 
+information about the running status of the daemon.
+
+To inspect all monitor information, issue a subtree search with base {{cn=Monitor}}, 
+requesting that attributes "+" and "*" are returned. The monitor backend produces 
+mostly operational attributes, and LDAP only returns operational attributes 
+that are explicitly requested.  Requesting attribute "+" is an extension which 
+requests all operational attributes.
+
+See the {{SECT:Monitoring}} section.
+
+H3: back-monitor Configuration
+
+LATER
+
+H3: Further Information
+
+{{slapd-monitor}}(5)
+
+H2: Null
+
+
+H3: Overview
+
+The Null backend to {{slapd}}(8) 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 other than as the rootdn fail unless the database option "bind on" is given.
+* The slapadd(8) and slapcat(8) tools are equally exciting.
+
+Inspired by the {{F:/dev/null}} device.
+
+H3: back-null Configuration
+
+LATER
+
+H3: Further Information
+
+{{slapd-null}}(5)
+
+H2: Passwd
+
+
+H3: Overview
+
+The PASSWD backend to {{slapd}}(8) serves up the user account information 
+listed in the system {{passwd}}(5) file.
+
+This backend is provided for demonstration purposes only. The DN of each entry 
+is "uid=<username>,<suffix>".
+
+H3: back-passwd Configuration
+
+LATER
+
+H3: Further Information
+
+{{slapd-passwd}}(5)
+
+H2: Perl/Shell
+
+H3: Overview
+
+The Perl backend to {{slapd}}(8) works by embedding a {{perl}}(1) interpreter 
+into {{slapd}}(8). Any perl database section of the configuration file 
+{{slapd.conf}}(5) must then specify what Perl module to use. Slapd then creates 
+a new Perl object that handles all the requests for that particular instance of the backend.
+
+The Shell backend to {{slapd}}(8) executes external programs to implement 
+operations, and is designed to make it easy to tie an existing database to the 
+slapd front-end. This backend is is primarily intended to be used in prototypes.
+
+H3: back-perl/back-shell Configuration
+
+LATER
+
+H3: Further Information
+
+{{slapd-shell}}(5) and {{slapd-perl}}(5)
+
+H2: Relay
+
+
+H3: Overview
+
+The primary purpose of this {{slapd}}(8) backend is to map a naming context 
+defined in a database running in the same {{slapd}}(8) instance into a 
+virtual naming context, with attributeType and objectClass manipulation, if
+required. It requires the rwm overlay.
+
+This backend and the above mentioned overlay are experimental.
+
+H3: back-relay Configuration
+
+LATER
+
+H3: Further Information
+
+{{slapd-relay}}(5)
+
+H2: SQL
+
+
+H3: Overview
+
+The primary purpose of this {{slapd}}(8) backend is to PRESENT information 
+stored in some RDBMS as an LDAP subtree without any programming (some SQL and 
+maybe stored procedures can’t be considered programming, anyway ;).
+
+That is, for example, when you (some ISP) have account information you use in 
+an RDBMS, and want to use modern solutions that expect such information in LDAP 
+(to authenticate users, make email lookups etc.). Or you want to synchronize or 
+distribute information between different sites/applications that use RDBMSes 
+and/or LDAP. Or whatever else...
+
+It is {{B:NOT}} designed as a general-purpose backend that uses RDBMS instead of 
+BerkeleyDB (as the standard BDB backend does), though it can be used as such with 
+several limitations. Please see {{SECT: LDAP vs RDBMS}} for discussion.
+
+The idea is to use some meta-information to translate LDAP queries to SQL queries, 
+leaving relational schema untouched, so that old applications can continue using 
+it without any modifications. This allows SQL and LDAP applications to interoperate 
+without replication, and exchange data as needed.
+
+The SQL backend is designed to be tunable to virtually any relational schema without 
+having to change source (through that meta-information mentioned). Also, it uses 
+ODBC to connect to RDBMSes, and is highly configurable for SQL dialects RDBMSes 
+may use, so it may be used for integration and distribution of data on different 
+RDBMSes, OSes, hosts etc., in other words, in highly heterogeneous environment.
+
+This backend is experimental.
+
+H3: back-sql Configuration
+
+LATER
+
+H3: Further Information
+
+{{slapd-sql}}(5)

Modified: openldap/trunk/doc/guide/admin/config.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/config.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/config.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,20 +1,21 @@
-# $OpenLDAP: pkg/openldap-guide/admin/config.sdf,v 1.13.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/config.sdf,v 1.14.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 H1: The Big Picture - Configuration Choices
 
 This section gives a brief overview of various {{TERM:LDAP}} directory
-configurations, and how your stand-alone LDAP server {{slapd}}(8)
+configurations, and how your Standalone LDAP Daemon {{slapd}}(8)
 fits in with the rest of the world.
 
 
 H2: Local Directory Service
 
-In this configuration, you run a {{slapd}} which provides directory
-service for your local domain only. It does not interact with other
-directory servers in any way. This configuration is shown in Figure 3.1.
+In this configuration, you run a {{slapd}}(8) instance which provides
+directory service for your local domain only. It does not interact
+with other directory servers in any way. This configuration is shown
+in Figure 3.1.
 
-!import "config_local.gif"; align="center"; title="Local service via slapd configuration"
+!import "config_local.png"; align="center"; title="Local service via slapd(8) configuration"
 FT[align="Center"] Figure 3.1: Local service configuration.
 
 Use this configuration if you are just starting out (it's the one the
@@ -25,31 +26,35 @@
 
 H2: Local Directory Service with Referrals
 
-In this configuration, you run a slapd which provides directory service
-for your local domain and configure it to return referrals to a
-{{superior}} service capable of handling requests outside your local domain.
-You may run this service yourself or use one provided to you.
+In this configuration, you run a {{slapd}}(8) instance which provides
+directory service for your local domain and configure it to return
+referrals to other servers capable of handling requests.  You may
+run this service (or services) yourself or use one provided to you.
 This configuration is shown in Figure 3.2.
 
-!import "config_ref.gif"; align="center"; title="Local service with referrals"
+!import "config_ref.png"; align="center"; title="Local service with referrals"
 FT[align="Center"] Figure 3.2: Local service with referrals 
 
-Use this configuration if you want to provide local service and 
-participate in the Global Directory.
+Use this configuration if you want to provide local service and
+participate in the Global Directory,  or you want to delegate
+responsibility for {{subordinate}} entries to another server.
 
 
 H2: Replicated Directory Service
 
-The slurpd daemon is used to propagate changes from a master slapd
-to one or more slave slapds. An example master-slave configuration
-is shown in figure 3.3.
+slapd(8) includes support for {{LDAP Sync}}-based replication, called
+{{syncrepl}}, which may be used to maintain shadow copies of directory
+information on multiple directory servers.   In its most basic
+configuration, the {{master}} is a syncrepl provider and one or more
+{{slave}} (or {{shadow}}) are syncrepl consumers.  An example
+master-slave configuration is shown in figure 3.3.
 
 !import "config_repl.gif"; align="center"; title="Replicated Directory Services"
 FT[align="Center"] Figure 3.3: Replicated Directory Services
 
-This configuration can be used in conjunction with either of the first
-two configurations in situations where a single slapd does not
-provide the required reliability or availability.
+This configuration can be used in conjunction with either of the
+first two configurations in situations where a single {{slapd}}(8)
+instance does not provide the required reliability or availability.
 
 H2: Distributed Local Directory Service
 

Deleted: openldap/trunk/doc/guide/admin/config_dit.gif
===================================================================
(Binary files differ)

Copied: openldap/trunk/doc/guide/admin/config_dit.png (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/config_dit.png)
===================================================================
(Binary files differ)

Deleted: openldap/trunk/doc/guide/admin/config_local.gif
===================================================================
(Binary files differ)

Copied: openldap/trunk/doc/guide/admin/config_local.png (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/config_local.png)
===================================================================
(Binary files differ)

Deleted: openldap/trunk/doc/guide/admin/config_ref.gif
===================================================================
(Binary files differ)

Copied: openldap/trunk/doc/guide/admin/config_ref.png (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/config_ref.png)
===================================================================
(Binary files differ)

Deleted: openldap/trunk/doc/guide/admin/config_x500fe.gif
===================================================================
(Binary files differ)

Deleted: openldap/trunk/doc/guide/admin/config_x500ref.gif
===================================================================
(Binary files differ)

Modified: openldap/trunk/doc/guide/admin/dbtools.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/dbtools.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/dbtools.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/admin/dbtools.sdf,v 1.23.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/dbtools.sdf,v 1.24.2.5 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -7,18 +7,18 @@
 This section tells you how to create a slapd database from scratch,
 and how to do trouble shooting if you run into problems. There are
 two ways to create a database. First, you can create the database
-on-line using LDAP. With this method, you simply start up slapd
+on-line using {{TERM:LDAP}}. With this method, you simply start up slapd
 and add entries using the LDAP client of your choice. This method
 is fine for relatively small databases (a few hundred or thousand
 entries, depending on your requirements). This method works for
 database types which support updates.
 
 The second method of database creation is to do it off-line using
-special utilities provided with slapd. This method is best if you
+special utilities provided with {{slapd}}(8). This method is best if you
 have many thousands of entries to create, which would take an
 unacceptably long time using the LDAP method, or if you want to
 ensure the database is not accessed while it is being created. Note
-that not all database types support these utilitites.
+that not all database types support these utilities.
 
 
 H2: Creating a database over LDAP
@@ -187,6 +187,15 @@
 Specifies the slapd configuration file that tells where to create
 the indices, what indices to create, etc.
 
+>	-F <slapdconfdirectory>
+
+Specifies a config directory.  If both {{EX:-f}} and {{EX:-F}} are specified, 
+the config file will be read and converted to config  directory format and 
+written to the specified directory.  If neither option is specified, an attempt 
+to read the default config directory will be made before trying to use the 
+default config file. If a valid config directory exists then the default 
+config file is ignored. If dryrun mode is also specified, no conversion will occur.
+
 >	-d <debuglevel>
 
 Turn on debugging, as specified by {{EX:<debuglevel>}}. The debug

Copied: openldap/trunk/doc/guide/admin/dual_dc.png (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/dual_dc.png)
===================================================================
(Binary files differ)

Copied: openldap/trunk/doc/guide/admin/glossary.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/glossary.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/glossary.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/glossary.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,16 @@
+# $OpenLDAP: pkg/openldap-guide/admin/glossary.sdf,v 1.5.2.4 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2006-2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+H1: Glossary
+
+H2: Terms
+!catalog terms ''; headings; columns="Term,Definition"
+
+H2: Related Organizations
+!catalog organisations ''; headings; columns="ORG:Name,Long,URL:Jump"
+
+H2: Related Products
+!catalog products ''; headings; columns="PRD:Name,URL:Jump"
+
+H2: References
+!catalog references ''; headings; columns="REF:Reference,Document,Status,URL:Jump"

Copied: openldap/trunk/doc/guide/admin/guide.book (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/guide.book)
===================================================================
--- openldap/trunk/doc/guide/admin/guide.book	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/guide.book	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,3 @@
+#HTMLDOC 1.8.27
+-t pdf14 --book --toclevels 3 --no-numbered --toctitle "Table of Contents" --title --titleimage "../images/LDAPwww.gif" --linkstyle plain --size Universal --left 1.00in --right 0.50in --top 0.50in --bottom 0.50in --header .t. --header1 ... --footer ..1 --nup 1 --tocheader .t. --tocfooter ..i --duplex --portrait --color --no-pscommands --no-xrxcomments --compression=1 --jpeg=0 --fontsize 11.0 --fontspacing 1.2 --headingfont Helvetica --bodyfont Times --headfootsize 11.0 --headfootfont Helvetica --charset iso-8859-1 --links --embedfonts --pagemode outline --pagelayout single --firstpage p1 --pageeffect none --pageduration 10 --effectduration 1.0 --no-encryption --permissions all  --owner-password ""  --user-password "" --browserwidth 680 --no-strict --no-overflow
+admin.html

Modified: openldap/trunk/doc/guide/admin/guide.html
===================================================================
--- openldap/trunk/doc/guide/admin/guide.html	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/guide.html	2007-12-15 10:25:31 UTC (rev 892)
@@ -7,7 +7,7 @@
      available from http://www.mincom.com/mtr/sdf. -->
 
 <HEAD>
-<TITLE>OpenLDAP Software 2.3 Administrator's Guide</TITLE>
+<TITLE>OpenLDAP Software 2.4 Administrator's Guide</TITLE>
 </HEAD>
 <BODY>
 
@@ -21,9 +21,9 @@
 <BR CLEAR="Left">
 </DIV>
 <DIV CLASS="title">
-<H1 CLASS="doc-title">OpenLDAP Software 2.3 Administrator's Guide</H1>
+<H1 CLASS="doc-title">OpenLDAP Software 2.4 Administrator's Guide</H1>
 <ADDRESS CLASS="doc-author">The OpenLDAP Project &lt;<A HREF="http://www.openldap.org/">http://www.openldap.org/</A>&gt;</ADDRESS>
-<ADDRESS CLASS="doc-modified">26 October 2007</ADDRESS>
+<ADDRESS CLASS="doc-modified">13 December 2007</ADDRESS>
 <BR CLEAR="All">
 </DIV>
 <DIV CLASS="contents">
@@ -37,16 +37,20 @@
 <BR>
 <A HREF="#What is LDAP">1.2. What is LDAP?</A>
 <BR>
-<A HREF="#How does LDAP work">1.3. How does LDAP work?</A>
+<A HREF="#When should I use LDAP">1.3. When should I use LDAP?</A>
 <BR>
-<A HREF="#What about X.500">1.4. What about X.500?</A>
+<A HREF="#When should I not use LDAP">1.4. When should I not use LDAP?</A>
 <BR>
-<A HREF="#What is the difference between LDAPv2 and LDAPv3">1.5. What is the difference between LDAPv2 and LDAPv3?</A>
+<A HREF="#How does LDAP work">1.5. How does LDAP work?</A>
 <BR>
-<A HREF="#What is slapd and what can it do">1.6. What is slapd and what can it do?</A>
+<A HREF="#What about X.500">1.6. What about X.500?</A>
 <BR>
-<A HREF="#What is slurpd and what can it do">1.7. What is slurpd and what can it do?</A></UL>
+<A HREF="#What is the difference between LDAPv2 and LDAPv3">1.7. What is the difference between LDAPv2 and LDAPv3?</A>
 <BR>
+<A HREF="#LDAP vs RDBMS">1.8. LDAP vs RDBMS</A>
+<BR>
+<A HREF="#What is slapd and what can it do">1.9. What is slapd and what can it do?</A></UL>
+<BR>
 <A HREF="#A Quick-Start Guide">2. A Quick-Start Guide</A>
 <BR>
 <A HREF="#The Big Picture - Configuration Choices">3. The Big Picture - Configuration Choices</A><UL>
@@ -61,8 +65,19 @@
 <A HREF="#Building and Installing OpenLDAP Software">4. Building and Installing OpenLDAP Software</A><UL>
 <A HREF="#Obtaining and Extracting the Software">4.1. Obtaining and Extracting the Software</A>
 <BR>
-<A HREF="#Prerequisite software">4.2. Prerequisite software</A>
+<A HREF="#Prerequisite software">4.2. Prerequisite software</A><UL>
+<A HREF="#{{TERM[expand]TLS}}">4.2.1. <TERM>Transport Layer Security</TERM></A>
 <BR>
+<A HREF="#{{TERM[expand]SASL}}">4.2.2. <TERM>Simple Authentication and Security Layer</TERM></A>
+<BR>
+<A HREF="#{{TERM[expand]Kerberos}}">4.2.3. <TERM>Kerberos Authentication Service</TERM></A>
+<BR>
+<A HREF="#Database Software">4.2.4. Database Software</A>
+<BR>
+<A HREF="#Threads">4.2.5. Threads</A>
+<BR>
+<A HREF="#TCP Wrappers">4.2.6. TCP Wrappers</A></UL>
+<BR>
 <A HREF="#Running configure">4.3. Running configure</A>
 <BR>
 <A HREF="#Building the Software">4.4. Building the Software</A>
@@ -74,19 +89,59 @@
 <A HREF="#Configuring slapd">5. Configuring slapd</A><UL>
 <A HREF="#Configuration Layout">5.1. Configuration Layout</A>
 <BR>
-<A HREF="#Configuration Directives">5.2. Configuration Directives</A>
+<A HREF="#Configuration Directives">5.2. Configuration Directives</A><UL>
+<A HREF="#cn=config">5.2.1. cn=config</A>
 <BR>
-<A HREF="#Access Control">5.3. Access Control</A>
+<A HREF="#cn=module">5.2.2. cn=module</A>
 <BR>
-<A HREF="#Configuration Example">5.4. Configuration Example</A></UL>
+<A HREF="#cn=schema">5.2.3. cn=schema</A>
 <BR>
+<A HREF="#Backend-specific Directives">5.2.4. Backend-specific Directives</A>
+<BR>
+<A HREF="#Database-specific Directives">5.2.5. Database-specific Directives</A>
+<BR>
+<A HREF="#BDB and HDB Database Directives">5.2.6. BDB and HDB Database Directives</A></UL>
+<BR>
+<A HREF="#Access Control">5.3. Access Control</A><UL>
+<A HREF="#What to control access to">5.3.1. What to control access to</A>
+<BR>
+<A HREF="#Who to grant access to">5.3.2. Who to grant access to</A>
+<BR>
+<A HREF="#The access to grant">5.3.3. The access to grant</A>
+<BR>
+<A HREF="#Access Control Evaluation">5.3.4. Access Control Evaluation</A>
+<BR>
+<A HREF="#Access Control Examples">5.3.5. Access Control Examples</A>
+<BR>
+<A HREF="#Access Control Ordering">5.3.6. Access Control Ordering</A></UL>
+<BR>
+<A HREF="#Configuration Example">5.4. Configuration Example</A>
+<BR>
+<A HREF="#Converting from slapd.conf(8) to a {{B:cn=config}} directory format">5.5. Converting from slapd.conf(8) to a <B>cn=config</B> directory format</A></UL>
+<BR>
 <A HREF="#The slapd Configuration File">6. The slapd Configuration File</A><UL>
 <A HREF="#Configuration File Format">6.1. Configuration File Format</A>
 <BR>
-<A HREF="#Configuration File Directives">6.2. Configuration File Directives</A>
+<A HREF="#Configuration File Directives">6.2. Configuration File Directives</A><UL>
+<A HREF="#Global Directives">6.2.1. Global Directives</A>
 <BR>
-<A HREF="#Access Control">6.3. Access Control</A>
+<A HREF="#General Backend Directives">6.2.2. General Backend Directives</A>
 <BR>
+<A HREF="#General Database Directives">6.2.3. General Database Directives</A>
+<BR>
+<A HREF="#BDB and HDB Database Directives">6.2.4. BDB and HDB Database Directives</A></UL>
+<BR>
+<A HREF="#The access Configuration Directive">6.3. The access Configuration Directive</A><UL>
+<A HREF="#What to control access to">6.3.1. What to control access to</A>
+<BR>
+<A HREF="#Who to grant access to">6.3.2. Who to grant access to</A>
+<BR>
+<A HREF="#The access to grant">6.3.3. The access to grant</A>
+<BR>
+<A HREF="#Access Control Evaluation">6.3.4. Access Control Evaluation</A>
+<BR>
+<A HREF="#Access Control Examples">6.3.5. Access Control Examples</A></UL>
+<BR>
 <A HREF="#Configuration File Example">6.4. Configuration File Example</A></UL>
 <BR>
 <A HREF="#Running slapd">7. Running slapd</A><UL>
@@ -99,86 +154,656 @@
 <A HREF="#Database Creation and Maintenance Tools">8. Database Creation and Maintenance Tools</A><UL>
 <A HREF="#Creating a database over LDAP">8.1. Creating a database over LDAP</A>
 <BR>
-<A HREF="#Creating a database off-line">8.2. Creating a database off-line</A>
+<A HREF="#Creating a database off-line">8.2. Creating a database off-line</A><UL>
+<A HREF="#The {{EX:slapadd}} program">8.2.1. The <TT>slapadd</TT> program</A>
 <BR>
+<A HREF="#The {{EX:slapindex}} program">8.2.2. The <TT>slapindex</TT> program</A>
+<BR>
+<A HREF="#The {{EX:slapcat}} program">8.2.3. The <TT>slapcat</TT> program</A></UL>
+<BR>
 <A HREF="#The LDIF text entry format">8.3. The LDIF text entry format</A></UL>
 <BR>
-<A HREF="#Schema Specification">9. Schema Specification</A><UL>
-<A HREF="#Distributed Schema Files">9.1. Distributed Schema Files</A>
+<A HREF="#Backends">9. Backends</A><UL>
+<A HREF="#Berkeley DB Backends">9.1. Berkeley DB Backends</A><UL>
+<A HREF="#Overview">9.1.1. Overview</A>
 <BR>
-<A HREF="#Extending Schema">9.2. Extending Schema</A></UL>
+<A HREF="#back-bdb/back-hdb Configuration">9.1.2. back-bdb/back-hdb Configuration</A>
 <BR>
-<A HREF="#Security Considerations">10. Security Considerations</A><UL>
-<A HREF="#Network Security">10.1. Network Security</A>
+<A HREF="#Further Information">9.1.3. Further Information</A></UL>
 <BR>
-<A HREF="#Data Integrity and Confidentiality Protection">10.2. Data Integrity and Confidentiality Protection</A>
+<A HREF="#LDAP">9.2. LDAP</A><UL>
+<A HREF="#Overview">9.2.1. Overview</A>
 <BR>
-<A HREF="#Authentication Methods">10.3. Authentication Methods</A></UL>
+<A HREF="#back-ldap Configuration">9.2.2. back-ldap Configuration</A>
 <BR>
-<A HREF="#Using SASL">11. Using SASL</A><UL>
-<A HREF="#SASL Security Considerations">11.1. SASL Security Considerations</A>
+<A HREF="#Further Information">9.2.3. Further Information</A></UL>
 <BR>
-<A HREF="#SASL Authentication">11.2. SASL Authentication</A>
+<A HREF="#LDIF">9.3. LDIF</A><UL>
+<A HREF="#Overview">9.3.1. Overview</A>
 <BR>
-<A HREF="#SASL Proxy Authorization">11.3. SASL Proxy Authorization</A></UL>
+<A HREF="#back-ldif Configuration">9.3.2. back-ldif Configuration</A>
 <BR>
-<A HREF="#Using TLS">12. Using TLS</A><UL>
-<A HREF="#TLS Certificates">12.1. TLS Certificates</A>
+<A HREF="#Further Information">9.3.3. Further Information</A></UL>
 <BR>
-<A HREF="#TLS Configuration">12.2. TLS Configuration</A></UL>
+<A HREF="#Metadirectory">9.4. Metadirectory</A><UL>
+<A HREF="#Overview">9.4.1. Overview</A>
 <BR>
-<A HREF="#Constructing a Distributed Directory Service">13. Constructing a Distributed Directory Service</A><UL>
-<A HREF="#Subordinate Knowledge Information">13.1. Subordinate Knowledge Information</A>
+<A HREF="#back-meta Configuration">9.4.2. back-meta Configuration</A>
 <BR>
-<A HREF="#Superior Knowledge Information">13.2. Superior Knowledge Information</A>
+<A HREF="#Further Information">9.4.3. Further Information</A></UL>
 <BR>
-<A HREF="#The ManageDsaIT Control">13.3. The ManageDsaIT Control</A></UL>
+<A HREF="#Monitor">9.5. Monitor</A><UL>
+<A HREF="#Overview">9.5.1. Overview</A>
 <BR>
-<A HREF="#Replication with slurpd">14. Replication with slurpd</A><UL>
-<A HREF="#Overview">14.1. Overview</A>
+<A HREF="#back-monitor Configuration">9.5.2. back-monitor Configuration</A>
 <BR>
-<A HREF="#Replication Logs">14.2. Replication Logs</A>
+<A HREF="#Further Information">9.5.3. Further Information</A></UL>
 <BR>
-<A HREF="#Command-Line Options">14.3. Command-Line Options</A>
+<A HREF="#Null">9.6. Null</A><UL>
+<A HREF="#Overview">9.6.1. Overview</A>
 <BR>
-<A HREF="#Configuring slurpd and a slave slapd instance">14.4. Configuring slurpd and a slave slapd instance</A>
+<A HREF="#back-null Configuration">9.6.2. back-null Configuration</A>
 <BR>
-<A HREF="#Advanced slurpd Operation">14.5. Advanced slurpd Operation</A></UL>
+<A HREF="#Further Information">9.6.3. Further Information</A></UL>
 <BR>
-<A HREF="#LDAP Sync Replication">15. LDAP Sync Replication</A><UL>
-<A HREF="#The LDAP Content Synchronization Protocol">15.1. The LDAP Content Synchronization Protocol</A>
+<A HREF="#Passwd">9.7. Passwd</A><UL>
+<A HREF="#Overview">9.7.1. Overview</A>
 <BR>
-<A HREF="#Syncrepl Details">15.2. Syncrepl Details</A>
+<A HREF="#back-passwd Configuration">9.7.2. back-passwd Configuration</A>
 <BR>
-<A HREF="#Configuring Syncrepl">15.3. Configuring Syncrepl</A></UL>
+<A HREF="#Further Information">9.7.3. Further Information</A></UL>
 <BR>
-<A HREF="#The Proxy Cache Engine">16. The Proxy Cache Engine</A><UL>
-<A HREF="#Overview">16.1. Overview</A>
+<A HREF="#Perl/Shell">9.8. Perl/Shell</A><UL>
+<A HREF="#Overview">9.8.1. Overview</A>
 <BR>
-<A HREF="#Proxy Cache Configuration">16.2. Proxy Cache Configuration</A></UL>
+<A HREF="#back-perl/back-shell Configuration">9.8.2. back-perl/back-shell Configuration</A>
 <BR>
-<A HREF="#Generic configure Instructions">A. Generic configure Instructions</A>
+<A HREF="#Further Information">9.8.3. Further Information</A></UL>
 <BR>
-<A HREF="#OpenLDAP Software Copyright Notices">B. OpenLDAP Software Copyright Notices</A><UL>
-<A HREF="#OpenLDAP Copyright Notice">B.1. OpenLDAP Copyright Notice</A>
+<A HREF="#Relay">9.9. Relay</A><UL>
+<A HREF="#Overview">9.9.1. Overview</A>
 <BR>
-<A HREF="#Additional Copyright Notice">B.2. Additional Copyright Notice</A>
+<A HREF="#back-relay Configuration">9.9.2. back-relay Configuration</A>
 <BR>
-<A HREF="#University of Michigan Copyright Notice">B.3. University of Michigan Copyright Notice</A></UL>
+<A HREF="#Further Information">9.9.3. Further Information</A></UL>
 <BR>
-<A HREF="#OpenLDAP Public License">C. OpenLDAP Public License</A></UL>
+<A HREF="#SQL">9.10. SQL</A><UL>
+<A HREF="#Overview">9.10.1. Overview</A>
+<BR>
+<A HREF="#back-sql Configuration">9.10.2. back-sql Configuration</A>
+<BR>
+<A HREF="#Further Information">9.10.3. Further Information</A></UL></UL>
+<BR>
+<A HREF="#Overlays">10. Overlays</A><UL>
+<A HREF="#Access Logging">10.1. Access Logging</A><UL>
+<A HREF="#Overview">10.1.1. Overview</A>
+<BR>
+<A HREF="#Access Logging Configuration">10.1.2. Access Logging Configuration</A></UL>
+<BR>
+<A HREF="#Audit Logging">10.2. Audit Logging</A><UL>
+<A HREF="#Overview">10.2.1. Overview</A>
+<BR>
+<A HREF="#Audit Logging Configuration">10.2.2. Audit Logging Configuration</A></UL>
+<BR>
+<A HREF="#Chaining">10.3. Chaining</A><UL>
+<A HREF="#Overview">10.3.1. Overview</A>
+<BR>
+<A HREF="#Chaining Configuration">10.3.2. Chaining Configuration</A>
+<BR>
+<A HREF="#Handling Chaining Errors">10.3.3. Handling Chaining Errors</A></UL>
+<BR>
+<A HREF="#Constraints">10.4. Constraints</A><UL>
+<A HREF="#Overview">10.4.1. Overview</A>
+<BR>
+<A HREF="#Constraint Configuration">10.4.2. Constraint Configuration</A></UL>
+<BR>
+<A HREF="#Dynamic Directory Services">10.5. Dynamic Directory Services</A><UL>
+<A HREF="#Overview">10.5.1. Overview</A>
+<BR>
+<A HREF="#Dynamic Directory Service Configuration">10.5.2. Dynamic Directory Service Configuration</A></UL>
+<BR>
+<A HREF="#Dynamic Groups">10.6. Dynamic Groups</A><UL>
+<A HREF="#Overview">10.6.1. Overview</A>
+<BR>
+<A HREF="#Dynamic Group Configuration">10.6.2. Dynamic Group Configuration</A></UL>
+<BR>
+<A HREF="#Dynamic Lists">10.7. Dynamic Lists</A><UL>
+<A HREF="#Overview">10.7.1. Overview</A>
+<BR>
+<A HREF="#Dynamic List Configuration">10.7.2. Dynamic List Configuration</A></UL>
+<BR>
+<A HREF="#Reverse Group Membership Maintenance">10.8. Reverse Group Membership Maintenance</A><UL>
+<A HREF="#Overview">10.8.1. Overview</A>
+<BR>
+<A HREF="#Member Of Configuration">10.8.2. Member Of Configuration</A></UL>
+<BR>
+<A HREF="#The Proxy Cache Engine">10.9. The Proxy Cache Engine</A><UL>
+<A HREF="#Overview">10.9.1. Overview</A>
+<BR>
+<A HREF="#Proxy Cache Configuration">10.9.2. Proxy Cache Configuration</A></UL>
+<BR>
+<A HREF="#Password Policies">10.10. Password Policies</A><UL>
+<A HREF="#Overview">10.10.1. Overview</A>
+<BR>
+<A HREF="#Password Policy Configuration">10.10.2. Password Policy Configuration</A></UL>
+<BR>
+<A HREF="#Referential Integrity">10.11. Referential Integrity</A><UL>
+<A HREF="#Overview">10.11.1. Overview</A>
+<BR>
+<A HREF="#Referential Integrity Configuration">10.11.2. Referential Integrity Configuration</A></UL>
+<BR>
+<A HREF="#Return Code">10.12. Return Code</A><UL>
+<A HREF="#Overview">10.12.1. Overview</A>
+<BR>
+<A HREF="#Return Code Configuration">10.12.2. Return Code Configuration</A></UL>
+<BR>
+<A HREF="#Rewrite/Remap">10.13. Rewrite/Remap</A><UL>
+<A HREF="#Overview">10.13.1. Overview</A>
+<BR>
+<A HREF="#Rewrite/Remap Configuration">10.13.2. Rewrite/Remap Configuration</A></UL>
+<BR>
+<A HREF="#Sync Provider">10.14. Sync Provider</A><UL>
+<A HREF="#Overview">10.14.1. Overview</A>
+<BR>
+<A HREF="#Sync Provider Configuration">10.14.2. Sync Provider Configuration</A></UL>
+<BR>
+<A HREF="#Translucent Proxy">10.15. Translucent Proxy</A><UL>
+<A HREF="#Overview">10.15.1. Overview</A>
+<BR>
+<A HREF="#Translucent Proxy Configuration">10.15.2. Translucent Proxy Configuration</A></UL>
+<BR>
+<A HREF="#Attribute Uniqueness">10.16. Attribute Uniqueness</A><UL>
+<A HREF="#Overview">10.16.1. Overview</A>
+<BR>
+<A HREF="#Attribute Uniqueness Configuration">10.16.2. Attribute Uniqueness Configuration</A></UL>
+<BR>
+<A HREF="#Value Sorting">10.17. Value Sorting</A><UL>
+<A HREF="#Overview">10.17.1. Overview</A>
+<BR>
+<A HREF="#Value Sorting Configuration">10.17.2. Value Sorting Configuration</A></UL>
+<BR>
+<A HREF="#Overlay Stacking">10.18. Overlay Stacking</A><UL>
+<A HREF="#Overview">10.18.1. Overview</A>
+<BR>
+<A HREF="#Example Scenarios">10.18.2. Example Scenarios</A></UL></UL>
+<BR>
+<A HREF="#Schema Specification">11. Schema Specification</A><UL>
+<A HREF="#Distributed Schema Files">11.1. Distributed Schema Files</A>
+<BR>
+<A HREF="#Extending Schema">11.2. Extending Schema</A><UL>
+<A HREF="#Object Identifiers">11.2.1. Object Identifiers</A>
+<BR>
+<A HREF="#Naming Elements">11.2.2. Naming Elements</A>
+<BR>
+<A HREF="#Local schema file">11.2.3. Local schema file</A>
+<BR>
+<A HREF="#Attribute Type Specification">11.2.4. Attribute Type Specification</A>
+<BR>
+<A HREF="#Object Class Specification">11.2.5. Object Class Specification</A>
+<BR>
+<A HREF="#OID Macros">11.2.6. OID Macros</A></UL></UL>
+<BR>
+<A HREF="#Security Considerations">12. Security Considerations</A><UL>
+<A HREF="#Network Security">12.1. Network Security</A><UL>
+<A HREF="#Selective Listening">12.1.1. Selective Listening</A>
+<BR>
+<A HREF="#IP Firewall">12.1.2. IP Firewall</A>
+<BR>
+<A HREF="#TCP Wrappers">12.1.3. TCP Wrappers</A></UL>
+<BR>
+<A HREF="#Data Integrity and Confidentiality Protection">12.2. Data Integrity and Confidentiality Protection</A><UL>
+<A HREF="#Security Strength Factors">12.2.1. Security Strength Factors</A></UL>
+<BR>
+<A HREF="#Authentication Methods">12.3. Authentication Methods</A><UL>
+<A HREF="#&quot;simple&quot; method">12.3.1. &quot;simple&quot; method</A>
+<BR>
+<A HREF="#SASL method">12.3.2. SASL method</A></UL></UL>
+<BR>
+<A HREF="#Using SASL">13. Using SASL</A><UL>
+<A HREF="#SASL Security Considerations">13.1. SASL Security Considerations</A>
+<BR>
+<A HREF="#SASL Authentication">13.2. SASL Authentication</A><UL>
+<A HREF="#GSSAPI">13.2.1. GSSAPI</A>
+<BR>
+<A HREF="#KERBEROS_V4">13.2.2. KERBEROS_V4</A>
+<BR>
+<A HREF="#DIGEST-MD5">13.2.3. DIGEST-MD5</A>
+<BR>
+<A HREF="#Mapping Authentication Identities">13.2.4. Mapping Authentication Identities</A>
+<BR>
+<A HREF="#Direct Mapping">13.2.5. Direct Mapping</A>
+<BR>
+<A HREF="#Search-based mappings">13.2.6. Search-based mappings</A></UL>
+<BR>
+<A HREF="#SASL Proxy Authorization">13.3. SASL Proxy Authorization</A><UL>
+<A HREF="#Uses of Proxy Authorization">13.3.1. Uses of Proxy Authorization</A>
+<BR>
+<A HREF="#SASL Authorization Identities">13.3.2. SASL Authorization Identities</A>
+<BR>
+<A HREF="#Proxy Authorization Rules">13.3.3. Proxy Authorization Rules</A></UL></UL>
+<BR>
+<A HREF="#Using TLS">14. Using TLS</A><UL>
+<A HREF="#TLS Certificates">14.1. TLS Certificates</A><UL>
+<A HREF="#Server Certificates">14.1.1. Server Certificates</A>
+<BR>
+<A HREF="#Client Certificates">14.1.2. Client Certificates</A></UL>
+<BR>
+<A HREF="#TLS Configuration">14.2. TLS Configuration</A><UL>
+<A HREF="#Server Configuration">14.2.1. Server Configuration</A>
+<BR>
+<A HREF="#Client Configuration">14.2.2. Client Configuration</A></UL></UL>
+<BR>
+<A HREF="#Constructing a Distributed Directory Service">15. Constructing a Distributed Directory Service</A><UL>
+<A HREF="#Subordinate Knowledge Information">15.1. Subordinate Knowledge Information</A>
+<BR>
+<A HREF="#Superior Knowledge Information">15.2. Superior Knowledge Information</A>
+<BR>
+<A HREF="#The ManageDsaIT Control">15.3. The ManageDsaIT Control</A></UL>
+<BR>
+<A HREF="#Replication">16. Replication</A><UL>
+<A HREF="#Replication Strategies">16.1. Replication Strategies</A><UL>
+<A HREF="#Push Based">16.1.1. Push Based</A>
+<BR>
+<A HREF="#Pull Based">16.1.2. Pull Based</A></UL>
+<BR>
+<A HREF="#Replication Types">16.2. Replication Types</A><UL>
+<A HREF="#syncrepl replication">16.2.1. syncrepl replication</A>
+<BR>
+<A HREF="#delta-syncrepl replication">16.2.2. delta-syncrepl replication</A>
+<BR>
+<A HREF="#N-Way Multi-Master replication">16.2.3. N-Way Multi-Master replication</A>
+<BR>
+<A HREF="#MirrorMode replication">16.2.4. MirrorMode replication</A></UL>
+<BR>
+<A HREF="#LDAP Sync Replication">16.3. LDAP Sync Replication</A><UL>
+<A HREF="#The LDAP Content Synchronization Protocol">16.3.1. The LDAP Content Synchronization Protocol</A>
+<BR>
+<A HREF="#Syncrepl Details">16.3.2. Syncrepl Details</A>
+<BR>
+<A HREF="#Configuring Syncrepl">16.3.3. Configuring Syncrepl</A></UL>
+<BR>
+<A HREF="#N-Way Multi-Master">16.4. N-Way Multi-Master</A>
+<BR>
+<A HREF="#MirrorMode">16.5. MirrorMode</A><UL>
+<A HREF="#Arguments for MirrorMode">16.5.1. Arguments for MirrorMode</A>
+<BR>
+<A HREF="#Arguments against MirrorMode">16.5.2. Arguments against MirrorMode</A>
+<BR>
+<A HREF="#MirrorMode Configuration">16.5.3. MirrorMode Configuration</A>
+<BR>
+<A HREF="#MirrorMode Summary">16.5.4. MirrorMode Summary</A></UL></UL>
+<BR>
+<A HREF="#Maintenance">17. Maintenance</A><UL>
+<A HREF="#Directory Backups">17.1. Directory Backups</A>
+<BR>
+<A HREF="#Berkeley DB Logs">17.2. Berkeley DB Logs</A>
+<BR>
+<A HREF="#Checkpointing">17.3. Checkpointing</A>
+<BR>
+<A HREF="#Migration">17.4. Migration</A></UL>
+<BR>
+<A HREF="#Monitoring">18. Monitoring</A><UL>
+<A HREF="#Monitor configuration via cn=config(5)">18.1. Monitor configuration via cn=config(5)</A>
+<BR>
+<A HREF="#Monitor configuration via slapd.conf(5)">18.2. Monitor configuration via slapd.conf(5)</A>
+<BR>
+<A HREF="#Accessing Monitoring Information">18.3. Accessing Monitoring Information</A>
+<BR>
+<A HREF="#Monitor Information">18.4. Monitor Information</A><UL>
+<A HREF="#Backends">18.4.1. Backends</A>
+<BR>
+<A HREF="#Connections">18.4.2. Connections</A>
+<BR>
+<A HREF="#Databases">18.4.3. Databases</A>
+<BR>
+<A HREF="#Listener">18.4.4. Listener</A>
+<BR>
+<A HREF="#Log">18.4.5. Log</A>
+<BR>
+<A HREF="#Operations">18.4.6. Operations</A>
+<BR>
+<A HREF="#Overlays">18.4.7. Overlays</A>
+<BR>
+<A HREF="#SASL">18.4.8. SASL</A>
+<BR>
+<A HREF="#Statistics">18.4.9. Statistics</A>
+<BR>
+<A HREF="#Threads">18.4.10. Threads</A>
+<BR>
+<A HREF="#Time">18.4.11. Time</A>
+<BR>
+<A HREF="#TLS">18.4.12. TLS</A>
+<BR>
+<A HREF="#Waiters">18.4.13. Waiters</A></UL></UL>
+<BR>
+<A HREF="#Tuning">19. Tuning</A><UL>
+<A HREF="#Performance Factors">19.1. Performance Factors</A><UL>
+<A HREF="#Memory">19.1.1. Memory</A>
+<BR>
+<A HREF="#Disks">19.1.2. Disks</A>
+<BR>
+<A HREF="#Network Topology">19.1.3. Network Topology</A>
+<BR>
+<A HREF="#Directory Layout Design">19.1.4. Directory Layout Design</A>
+<BR>
+<A HREF="#Expected Usage">19.1.5. Expected Usage</A></UL>
+<BR>
+<A HREF="#Indexes">19.2. Indexes</A><UL>
+<A HREF="#Understanding how a search works">19.2.1. Understanding how a search works</A>
+<BR>
+<A HREF="#What to index">19.2.2. What to index</A>
+<BR>
+<A HREF="#Presence indexing">19.2.3. Presence indexing</A></UL>
+<BR>
+<A HREF="#Logging">19.3. Logging</A><UL>
+<A HREF="#What log level to use">19.3.1. What log level to use</A>
+<BR>
+<A HREF="#What to watch out for">19.3.2. What to watch out for</A>
+<BR>
+<A HREF="#Improving throughput">19.3.3. Improving throughput</A></UL>
+<BR>
+<A HREF="#BDB/HDB Database Caching">19.4. BDB/HDB Database Caching</A><UL>
+<A HREF="#Berkeley DB Cache">19.4.1. Berkeley DB Cache</A>
+<BR>
+<A HREF="#{{slapd}}(8) Entry Cache">19.4.2. <EM>slapd</EM>(8) Entry Cache</A>
+<BR>
+<A HREF="#{{TERM:IDL}} Cache">19.4.3. <TERM>IDL</TERM> Cache</A></UL></UL>
+<BR>
+<A HREF="#Troubleshooting">20. Troubleshooting</A><UL>
+<A HREF="#User or Software errors">20.1. User or Software errors?</A>
+<BR>
+<A HREF="#Checklist">20.2. Checklist</A>
+<BR>
+<A HREF="#OpenLDAP Bugs">20.3. OpenLDAP Bugs</A>
+<BR>
+<A HREF="#3rd party software error">20.4. 3rd party software error</A>
+<BR>
+<A HREF="#How to contact the OpenLDAP Project">20.5. How to contact the OpenLDAP Project</A>
+<BR>
+<A HREF="#How to present your problem">20.6. How to present your problem</A>
+<BR>
+<A HREF="#Debugging {{slapd}}(8)">20.7. Debugging <EM>slapd</EM>(8)</A>
+<BR>
+<A HREF="#Commercial Support">20.8. Commercial Support</A></UL>
+<BR>
+<A HREF="#Changes Since Previous Release">A. Changes Since Previous Release</A><UL>
+<A HREF="#New Guide Sections">A.1. New Guide Sections</A>
+<BR>
+<A HREF="#New Features and Enhancements in 2.4">A.2. New Features and Enhancements in 2.4</A><UL>
+<A HREF="#Better {{B:cn=config}} functionality">A.2.1. Better <B>cn=config</B> functionality</A>
+<BR>
+<A HREF="#Better {{B:cn=schema}} functionality">A.2.2. Better <B>cn=schema</B> functionality</A>
+<BR>
+<A HREF="#More sophisticated Syncrepl configurations">A.2.3. More sophisticated Syncrepl configurations</A>
+<BR>
+<A HREF="#N-Way Multimaster Replication">A.2.4. N-Way Multimaster Replication</A>
+<BR>
+<A HREF="#Replicating {{slapd}} Configuration (syncrepl and {{B:cn=config}})">A.2.5. Replicating <EM>slapd</EM> Configuration (syncrepl and <B>cn=config</B>)</A>
+<BR>
+<A HREF="#Push-Mode Replication">A.2.6. Push-Mode Replication</A>
+<BR>
+<A HREF="#More extensive TLS configuration control">A.2.7. More extensive TLS configuration control</A>
+<BR>
+<A HREF="#Performance enhancements">A.2.8. Performance enhancements</A>
+<BR>
+<A HREF="#New overlays">A.2.9. New overlays</A>
+<BR>
+<A HREF="#New features in existing Overlays">A.2.10. New features in existing Overlays</A>
+<BR>
+<A HREF="#New features in slapd">A.2.11. New features in slapd</A>
+<BR>
+<A HREF="#New features in libldap">A.2.12. New features in libldap</A>
+<BR>
+<A HREF="#New clients, tools and tool enhancements">A.2.13. New clients, tools and tool enhancements</A>
+<BR>
+<A HREF="#New build options">A.2.14. New build options</A></UL>
+<BR>
+<A HREF="#Obsolete Features Removed From 2.4">A.3. Obsolete Features Removed From 2.4</A><UL>
+<A HREF="#Slurpd">A.3.1. Slurpd</A>
+<BR>
+<A HREF="#back-ldbm">A.3.2. back-ldbm</A></UL></UL>
+<BR>
+<A HREF="#Upgrading from 2.3.x">B. Upgrading from 2.3.x</A><UL>
+<A HREF="#Monitor Backend">B.1. Monitor Backend</A>
+<BR>
+<A HREF="#{{B:cn=config}} olc* attributes">B.2. <B>cn=config</B> olc* attributes</A></UL>
+<BR>
+<A HREF="#Common errors encountered when using OpenLDAP Software">C. Common errors encountered when using OpenLDAP Software</A><UL>
+<A HREF="#Common causes of LDAP errors">C.1. Common causes of LDAP errors</A><UL>
+<A HREF="#ldap_*: Can\'t contact LDAP server">C.1.1. ldap_*: Can't contact LDAP server</A>
+<BR>
+<A HREF="#ldap_*: No such object">C.1.2. ldap_*: No such object</A>
+<BR>
+<A HREF="#ldap_*: Can\'t chase referral">C.1.3. ldap_*: Can't chase referral</A>
+<BR>
+<A HREF="#ldap_*: server is unwilling to perform">C.1.4. ldap_*: server is unwilling to perform</A>
+<BR>
+<A HREF="#ldap_*: Insufficient access">C.1.5. ldap_*: Insufficient access</A>
+<BR>
+<A HREF="#ldap_*: Invalid DN syntax">C.1.6. ldap_*: Invalid DN syntax</A>
+<BR>
+<A HREF="#ldap_*: Referral hop limit exceeded">C.1.7. ldap_*: Referral hop limit exceeded</A>
+<BR>
+<A HREF="#ldap_*: operations error">C.1.8. ldap_*: operations error</A>
+<BR>
+<A HREF="#ldap_*: other error">C.1.9. ldap_*: other error</A>
+<BR>
+<A HREF="#ldap_add/modify: Invalid syntax">C.1.10. ldap_add/modify: Invalid syntax</A>
+<BR>
+<A HREF="#ldap_add/modify: Object class violation">C.1.11. ldap_add/modify: Object class violation</A>
+<BR>
+<A HREF="#ldap_add: No such object">C.1.12. ldap_add: No such object</A>
+<BR>
+<A HREF="#ldap add: invalid structural object class chain">C.1.13. ldap add: invalid structural object class chain</A>
+<BR>
+<A HREF="#ldap_add: no structuralObjectClass operational attribute">C.1.14. ldap_add: no structuralObjectClass operational attribute</A>
+<BR>
+<A HREF="#ldap_add/modify/rename: Naming violation">C.1.15. ldap_add/modify/rename: Naming violation</A>
+<BR>
+<A HREF="#ldap_add/delete/modify/rename: no global superior knowledge">C.1.16. ldap_add/delete/modify/rename: no global superior knowledge</A>
+<BR>
+<A HREF="#ldap_bind: Insufficient access">C.1.17. ldap_bind: Insufficient access</A>
+<BR>
+<A HREF="#ldap_bind: Invalid credentials">C.1.18. ldap_bind: Invalid credentials</A>
+<BR>
+<A HREF="#ldap_bind: Protocol error">C.1.19. ldap_bind: Protocol error</A>
+<BR>
+<A HREF="#ldap_modify: cannot modify object class">C.1.20. ldap_modify: cannot modify object class</A>
+<BR>
+<A HREF="#ldap_sasl_interactive_bind_s: ..">C.1.21. ldap_sasl_interactive_bind_s: ...</A>
+<BR>
+<A HREF="#ldap_sasl_interactive_bind_s: No such Object">C.1.22. ldap_sasl_interactive_bind_s: No such Object</A>
+<BR>
+<A HREF="#ldap_sasl_interactive_bind_s: No such attribute">C.1.23. ldap_sasl_interactive_bind_s: No such attribute</A>
+<BR>
+<A HREF="#ldap_sasl_interactive_bind_s: Unknown authentication method">C.1.24. ldap_sasl_interactive_bind_s: Unknown authentication method</A>
+<BR>
+<A HREF="#ldap_sasl_interactive_bind_s: Local error (82)">C.1.25. ldap_sasl_interactive_bind_s: Local error (82)</A>
+<BR>
+<A HREF="#ldap_search: Partial results and referral received">C.1.26. ldap_search: Partial results and referral received</A>
+<BR>
+<A HREF="#ldap_start_tls: Operations error">C.1.27. ldap_start_tls: Operations error</A></UL>
+<BR>
+<A HREF="#Other Errors">C.2. Other Errors</A><UL>
+<A HREF="#ber_get_next on fd X failed errno=34 (Numerical result out of range)">C.2.1. ber_get_next on fd X failed errno=34 (Numerical result out of range)</A>
+<BR>
+<A HREF="#ber_get_next on fd X failed errno=11 (Resource temporarily unavailable)">C.2.2. ber_get_next on fd X failed errno=11 (Resource temporarily unavailable)</A>
+<BR>
+<A HREF="#daemon: socket() failed errno=97 (Address family not supported)">C.2.3. daemon: socket() failed errno=97 (Address family not supported)</A>
+<BR>
+<A HREF="#GSSAPI: gss_acquire_cred: Miscellaneous failure; Permission denied;">C.2.4. GSSAPI: gss_acquire_cred: Miscellaneous failure; Permission denied;</A>
+<BR>
+<A HREF="#access from unknown denied">C.2.5. access from unknown denied</A>
+<BR>
+<A HREF="#ldap_read: want=# error=Resource temporarily unavailable">C.2.6. ldap_read: want=# error=Resource temporarily unavailable</A>
+<BR>
+<A HREF="#`make test\' fails">C.2.7. `make test' fails</A>
+<BR>
+<A HREF="#ldap_*: Internal (implementation specific) error (80) - additional info: entry index delete failed">C.2.8. ldap_*: Internal (implementation specific) error (80) - additional info: entry index delete failed</A>
+<BR>
+<A HREF="#ldap_sasl_interactive_bind_s: Can\'t contact LDAP server (-1)">C.2.9. ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1)</A></UL></UL>
+<BR>
+<A HREF="#Recommended OpenLDAP Software Dependency Versions">D. Recommended OpenLDAP Software Dependency Versions</A><UL>
+<A HREF="#Dependency Versions">D.1. Dependency Versions</A></UL>
+<BR>
+<A HREF="#Real World OpenLDAP Deployments and Examples">E. Real World OpenLDAP Deployments and Examples</A>
+<BR>
+<A HREF="#OpenLDAP Software Contributions">F. OpenLDAP Software Contributions</A><UL>
+<A HREF="#Client APIs">F.1. Client APIs</A><UL>
+<A HREF="#ldapc++">F.1.1. ldapc++</A>
+<BR>
+<A HREF="#ldaptcl">F.1.2. ldaptcl</A></UL>
+<BR>
+<A HREF="#Overlays">F.2. Overlays</A><UL>
+<A HREF="#acl">F.2.1. acl</A>
+<BR>
+<A HREF="#addpartial">F.2.2. addpartial</A>
+<BR>
+<A HREF="#allop">F.2.3. allop</A>
+<BR>
+<A HREF="#comp_match">F.2.4. comp_match</A>
+<BR>
+<A HREF="#denyop">F.2.5. denyop</A>
+<BR>
+<A HREF="#dsaschema">F.2.6. dsaschema</A>
+<BR>
+<A HREF="#lastmod">F.2.7. lastmod</A>
+<BR>
+<A HREF="#passwd">F.2.8. passwd</A>
+<BR>
+<A HREF="#proxyOld">F.2.9. proxyOld</A>
+<BR>
+<A HREF="#smbk5pwd">F.2.10. smbk5pwd</A>
+<BR>
+<A HREF="#trace">F.2.11. trace</A></UL>
+<BR>
+<A HREF="#Tools">F.3. Tools</A><UL>
+<A HREF="#Statistic Logging">F.3.1. Statistic Logging</A></UL>
+<BR>
+<A HREF="#SLAPI Plugins">F.4. SLAPI Plugins</A><UL>
+<A HREF="#addrdnvalues">F.4.1. addrdnvalues</A></UL></UL>
+<BR>
+<A HREF="#Configuration File Examples">G. Configuration File Examples</A><UL>
+<A HREF="#slapd.conf">G.1. slapd.conf</A>
+<BR>
+<A HREF="#ldap.conf">G.2. ldap.conf</A>
+<BR>
+<A HREF="#a-n-other.conf">G.3. a-n-other.conf</A></UL>
+<BR>
+<A HREF="#LDAP Result Codes">H. LDAP Result Codes</A><UL>
+<A HREF="#Non-Error Result Codes">H.1. Non-Error Result Codes</A>
+<BR>
+<A HREF="#Result Codes">H.2. Result Codes</A>
+<BR>
+<A HREF="#{{success (0)}}">H.3. <EM>success (0)</EM></A>
+<BR>
+<A HREF="#{{operationsError (1)}}">H.4. <EM>operationsError (1)</EM></A>
+<BR>
+<A HREF="#{{protocolError (2)}}">H.5. <EM>protocolError (2)</EM></A>
+<BR>
+<A HREF="#{{timeLimitExceeded (3)}}">H.6. <EM>timeLimitExceeded (3)</EM></A>
+<BR>
+<A HREF="#{{sizeLimitExceeded (4)}}">H.7. <EM>sizeLimitExceeded (4)</EM></A>
+<BR>
+<A HREF="#{{compareFalse (5)}}">H.8. <EM>compareFalse (5)</EM></A>
+<BR>
+<A HREF="#{{compareTrue (6)}}">H.9. <EM>compareTrue (6)</EM></A>
+<BR>
+<A HREF="#{{authMethodNotSupported (7)}}">H.10. <EM>authMethodNotSupported (7)</EM></A>
+<BR>
+<A HREF="#{{strongerAuthRequired (8)}}">H.11. <EM>strongerAuthRequired (8)</EM></A>
+<BR>
+<A HREF="#{{referral (10)}}">H.12. <EM>referral (10)</EM></A>
+<BR>
+<A HREF="#{{adminLimitExceeded (11)}}">H.13. <EM>adminLimitExceeded (11)</EM></A>
+<BR>
+<A HREF="#{{unavailableCriticalExtension (12)}}">H.14. <EM>unavailableCriticalExtension (12)</EM></A>
+<BR>
+<A HREF="#{{confidentialityRequired (13)}}">H.15. <EM>confidentialityRequired (13)</EM></A>
+<BR>
+<A HREF="#{{saslBindInProgress (14)}}">H.16. <EM>saslBindInProgress (14)</EM></A>
+<BR>
+<A HREF="#{{noSuchAttribute (16)}}">H.17. <EM>noSuchAttribute (16)</EM></A>
+<BR>
+<A HREF="#{{undefinedAttributeType (17)}}">H.18. <EM>undefinedAttributeType (17)</EM></A>
+<BR>
+<A HREF="#{{inappropriateMatching (18)}}">H.19. <EM>inappropriateMatching (18)</EM></A>
+<BR>
+<A HREF="#{{constraintViolation (19)}}">H.20. <EM>constraintViolation (19)</EM></A>
+<BR>
+<A HREF="#{{attributeOrValueExists (20)}}">H.21. <EM>attributeOrValueExists (20)</EM></A>
+<BR>
+<A HREF="#{{invalidAttributeSyntax (21)}}">H.22. <EM>invalidAttributeSyntax (21)</EM></A>
+<BR>
+<A HREF="#{{noSuchObject (32)}}">H.23. <EM>noSuchObject (32)</EM></A>
+<BR>
+<A HREF="#{{aliasProblem (33)}}">H.24. <EM>aliasProblem (33)</EM></A>
+<BR>
+<A HREF="#{{invalidDNSyntax (34)}}">H.25. <EM>invalidDNSyntax (34)</EM></A>
+<BR>
+<A HREF="#{{aliasDereferencingProblem (36)}}">H.26. <EM>aliasDereferencingProblem (36)</EM></A>
+<BR>
+<A HREF="#{{inappropriateAuthentication (48)}}">H.27. <EM>inappropriateAuthentication (48)</EM></A>
+<BR>
+<A HREF="#{{invalidCredentials (49)}}">H.28. <EM>invalidCredentials (49)</EM></A>
+<BR>
+<A HREF="#{{insufficientAccessRights (50)}}">H.29. <EM>insufficientAccessRights (50)</EM></A>
+<BR>
+<A HREF="#{{busy (51)}}">H.30. <EM>busy (51)</EM></A>
+<BR>
+<A HREF="#{{unavailable (52)}}">H.31. <EM>unavailable (52)</EM></A>
+<BR>
+<A HREF="#{{unwillingToPerform (53)}}">H.32. <EM>unwillingToPerform (53)</EM></A>
+<BR>
+<A HREF="#{{loopDetect (54)}}">H.33. <EM>loopDetect (54)</EM></A>
+<BR>
+<A HREF="#{{namingViolation (64)}}">H.34. <EM>namingViolation (64)</EM></A>
+<BR>
+<A HREF="#{{objectClassViolation (65)}}">H.35. <EM>objectClassViolation (65)</EM></A>
+<BR>
+<A HREF="#{{notAllowedOnNonLeaf (66)}}">H.36. <EM>notAllowedOnNonLeaf (66)</EM></A>
+<BR>
+<A HREF="#{{notAllowedOnRDN (67)}}">H.37. <EM>notAllowedOnRDN (67)</EM></A>
+<BR>
+<A HREF="#{{entryAlreadyExists (68)}}">H.38. <EM>entryAlreadyExists (68)</EM></A>
+<BR>
+<A HREF="#{{objectClassModsProhibited (69)}}">H.39. <EM>objectClassModsProhibited (69)</EM></A>
+<BR>
+<A HREF="#{{affectsMultipleDSAs (71)}}">H.40. <EM>affectsMultipleDSAs (71)</EM></A>
+<BR>
+<A HREF="#{{other (80)}}">H.41. <EM>other (80)</EM></A></UL>
+<BR>
+<A HREF="#Glossary">I. Glossary</A><UL>
+<A HREF="#Terms">I.1. Terms</A>
+<BR>
+<A HREF="#Related Organizations">I.2. Related Organizations</A>
+<BR>
+<A HREF="#Related Products">I.3. Related Products</A>
+<BR>
+<A HREF="#References">I.4. References</A></UL>
+<BR>
+<A HREF="#Generic configure Instructions">J. Generic configure Instructions</A>
+<BR>
+<A HREF="#OpenLDAP Software Copyright Notices">K. OpenLDAP Software Copyright Notices</A><UL>
+<A HREF="#OpenLDAP Copyright Notice">K.1. OpenLDAP Copyright Notice</A>
+<BR>
+<A HREF="#Additional Copyright Notice">K.2. Additional Copyright Notice</A>
+<BR>
+<A HREF="#University of Michigan Copyright Notice">K.3. University of Michigan Copyright Notice</A></UL>
+<BR>
+<A HREF="#OpenLDAP Public License">L. OpenLDAP Public License</A></UL>
 </DIV>
 <DIV CLASS="main">
 <P></P>
 <HR>
 <H1><A NAME="Preface">Preface</A></H1>
 <H2>Copyright</H2>
-<P>Copyright 1998-2005, The <A HREF="http://www.openldap.org/foundation/">OpenLDAP Foundation</A>, <EM>All Rights Reserved</EM>.</P>
+<P>Copyright 1998-2007, The <A HREF="http://www.openldap.org/foundation/">OpenLDAP Foundation</A>, <EM>All Rights Reserved</EM>.</P>
 <P>Copyright 1992-1996, Regents of the <A HREF="http://www.umich.edu/">University of Michigan</A>, <EM>All Rights Reserved</EM>.</P>
-<P>This document is considered a part of OpenLDAP Software.  This document is subject to terms of conditions set forth in <A HREF="#OpenLDAP Software Copyright Notices">OpenLDAP Software Copyright Notices</A> and the <A HREF="#OpenLDAP Public License">OpenLDAP Public License</A>. Complete copies of the notices and associated license can be found in Appendix B and C, respectively.</P>
+<P>This document is considered a part of OpenLDAP Software.  This document is subject to terms of conditions set forth in <A HREF="#OpenLDAP Software Copyright Notices">OpenLDAP Software Copyright Notices</A> and the <A HREF="#OpenLDAP Public License">OpenLDAP Public License</A>. Complete copies of the notices and associated license can be found in Appendix K and L, respectively.</P>
 <H2>Scope of this Document</H2>
-<P>This document provides a guide for installing OpenLDAP Software 2.3 (<A HREF="http://www.openldap.org/software/">http://www.openldap.org/software/</A>) on <TERM>UNIX</TERM> (and UNIX-like) systems.  The document is aimed at experienced system administrators but who may not have prior experience operating <TERM>LDAP</TERM>-based directory software.</P>
-<P>This document is meant to be used in conjunction with other OpenLDAP information resources provided with the software package and on the project's extensive site (<A HREF="http://www.OpenLDAP.org/">http://www.OpenLDAP.org/</A>) on the World Wide Web.  The site makes available a number of resources.</P>
+<P>This document provides a guide for installing OpenLDAP Software 2.4 (<A HREF="http://www.openldap.org/software/">http://www.openldap.org/software/</A>) on <TERM>UNIX</TERM> (and UNIX-like) systems.  The document is aimed at experienced system administrators with basic understanding of <TERM>LDAP</TERM>-based directory services.</P>
+<P>This document is meant to be used in conjunction with other OpenLDAP information resources provided with the software package and on the project's site (<A HREF="http://www.OpenLDAP.org/">http://www.OpenLDAP.org/</A>) on the <TERM>World Wide Web</TERM>.  The site makes available a number of resources.</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
 <CAPTION ALIGN=top>OpenLDAP Resources</CAPTION>
 <TR CLASS="heading">
@@ -223,6 +848,14 @@
 </TR>
 <TR>
 <TD>
+Manual Pages
+</TD>
+<TD>
+<A HREF="http://www.OpenLDAP.org/software/man.cgi">http://www.OpenLDAP.org/software/man.cgi</A>
+</TD>
+</TR>
+<TR>
+<TD>
 Software Pages
 </TD>
 <TD>
@@ -241,74 +874,117 @@
 
 <H2>Acknowledgments</H2>
 <P>The <A HREF="http://www.openldap.org/project/">OpenLDAP Project</A> is comprised of a team of volunteers.  This document would not be possible without their contribution of time and energy.</P>
-<P>The OpenLDAP Project would also like to thank the <A HREF="http://www.umich.edu/~dirsvcs/ldap/ldap.html">University of Michigan LDAP</A> for building the foundation of LDAP software and information to which OpenLDAP Software is built upon.  This document is based upon U-Mich LDAP document: <EM>The SLAPD and SLURPD Administrators Guide</EM>.</P>
+<P>The OpenLDAP Project would also like to thank the <A HREF="http://www.umich.edu/~dirsvcs/ldap/ldap.html">University of Michigan LDAP Team</A> for building the foundation of LDAP software and information to which OpenLDAP Software is built upon.  This document is based upon University of Michigan document: <A HREF="http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/guide.pdf">The SLAPD and SLURPD Administrators Guide</A>.</P>
 <H2>Amendments</H2>
-<P>Suggested enhancements and corrections to this document should be submitted using the <A HREF="http://www.openldap.org/">OpenLDAP</A> <EM><TERM>Issue Tracking System</TERM></EM> (<A HREF="http://www.openldap.org/its/">http://www.openldap.org/its/</A>).</P>
+<P>Suggested enhancements and corrections to this document should be submitted using the <A HREF="http://www.openldap.org/">OpenLDAP</A> <TERM>Issue Tracking System</TERM> (<A HREF="http://www.openldap.org/its/">http://www.openldap.org/its/</A>).</P>
 <H2>About this document</H2>
-<P>This document was produced using the <EM>Simple Document Format</EM> (<A HREF="http://search.cpan.org/src/IANC/sdf-2.001/doc/">http://search.cpan.org/src/IANC/sdf-2.001/doc/</A>) documentation system developed by <EM>Ian Clatworthy</EM>.  Tools for <EM>SDF</EM> are available from CPAN (<A HREF="http://search.cpan.org/search?query=SDF">http://search.cpan.org/search?query=SDF</A>).</P>
+<P>This document was produced using the <TERM>Simple Document Format</TERM> (<TERM>SDF</TERM>) documentation system (<A HREF="http://search.cpan.org/src/IANC/sdf-2.001/doc/catalog.html">http://search.cpan.org/src/IANC/sdf-2.001/doc/catalog.html</A>) developed by <EM>Ian Clatworthy</EM>.  Tools for SDF are available from <A HREF="http://cpan.org/">CPAN</A> (<A HREF="http://search.cpan.org/search?query=SDF&amp;mode=dist">http://search.cpan.org/search?query=SDF&amp;mode=dist</A>).</P>
 <P></P>
 <HR>
 <H1><A NAME="Introduction to OpenLDAP Directory Services">1. Introduction to OpenLDAP Directory Services</A></H1>
-<P>This document describes how to build, configure, and operate OpenLDAP software to provide directory services.  This includes details on how to configure and run the stand-alone <TERM>LDAP</TERM> daemon, <EM>slapd</EM>(8) and the stand-alone LDAP update replication daemon, <EM>slurpd</EM>(8). It is intended for newcomers and experienced administrators alike.  This section provides a basic introduction to directory services and, in particular, the directory services provided by <EM>slapd</EM>(8).</P>
+<P>This document describes how to build, configure, and operate <A HREF="http://www.openldap.org/">OpenLDAP</A> Software to provide directory services.  This includes details on how to configure and run the Standalone <TERM>LDAP</TERM> Daemon, <EM>slapd</EM>(8).  It is intended for new and experienced administrators alike.  This section provides a basic introduction to directory services and, in particular, the directory services provided by <EM>slapd</EM>(8).  This introduction is only intended to provide enough information so one might get started learning about <TERM>LDAP</TERM>, <TERM>X.500</TERM>, and directory services.</P>
 <H2><A NAME="What is a directory service">1.1. What is a directory service?</A></H2>
-<P>A directory is a specialized database optimized for reading, browsing and searching.  Directories tend to contain descriptive, attribute-based information and support sophisticated filtering capabilities. Directories generally do not support complicated transaction or roll-back schemes found in database management systems designed for handling high-volume complex updates.  Directory updates are typically simple all-or-nothing changes, if they are allowed at all.  Directories are tuned to give quick response to high-volume lookup or search operations. They may have the ability to replicate information widely in order to increase availability and reliability, while reducing response time.  When directory information is replicated, temporary inconsistencies between the replicas may be okay, as long as they get in sync eventually.</P>
-<P>There are many different ways to provide a directory service. Different methods allow different kinds of information to be stored in the directory, place different requirements on how that information can be referenced, queried and updated, how it is protected from unauthorized access, etc.  Some directory services are <EM>local</EM>, providing service to a restricted context (e.g., the finger service on a single machine). Other services are global, providing service to a much broader context (e.g., the entire Internet).  Global services are usually <EM>distributed</EM>, meaning that the data they contain is spread across many machines, all of which cooperate to provide the directory service. Typically a global service defines a uniform <EM>namespace</EM> which gives the same view of the data no matter where you are in relation to the data itself.  The Internet <TERM>Domain Name System</TERM> (DNS) is an example of a globally distributed directory service.</P>
+<P>A directory is a specialized database specifically designed for searching and browsing, in additional to supporting basic lookup and update functions.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>A directory is defined by some as merely a database optimized for read access.  This definition, at best, is overly simplistic.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<P>Directories tend to contain descriptive, attribute-based information and support sophisticated filtering capabilities.  Directories generally do not support complicated transaction or roll-back schemes found in database management systems designed for handling high-volume complex updates.  Directory updates are typically simple all-or-nothing changes, if they are allowed at all.  Directories are generally tuned to give quick response to high-volume lookup or search operations. They may have the ability to replicate information widely in order to increase availability and reliability, while reducing response time.  When directory information is replicated, temporary inconsistencies between the replicas may be okay, as long as inconsistencies are resolved in a timely manner.</P>
+<P>There are many different ways to provide a directory service. Different methods allow different kinds of information to be stored in the directory, place different requirements on how that information can be referenced, queried and updated, how it is protected from unauthorized access, etc.  Some directory services are <EM>local</EM>, providing service to a restricted context (e.g., the finger service on a single machine). Other services are global, providing service to a much broader context (e.g., the entire Internet).  Global services are usually <EM>distributed</EM>, meaning that the data they contain is spread across many machines, all of which cooperate to provide the directory service. Typically a global service defines a uniform <EM>namespace</EM> which gives the same view of the data no matter where you are in relation to the data itself.</P>
+<P>A web directory, such as provided by the <EM>Open Directory Project</EM> &lt;<A HREF="http://dmoz.org">http://dmoz.org</A>&gt;, is a good example of a directory service. These services catalog web pages and are specifically designed to support browsing and searching.</P>
+<P>While some consider the Internet <TERM>Domain Name System</TERM> (DNS) is an example of a globally distributed directory service, DNS is not browseable nor searchable.  It is more properly described as a globally distributed <EM>lookup</EM> service.</P>
 <H2><A NAME="What is LDAP">1.2. What is LDAP?</A></H2>
-<P><TERM>LDAP</TERM> stands for <TERM>Lightweight Directory Access Protocol</TERM>.  As the name suggests, it is a lightweight protocol for accessing directory services, specifically <TERM>X.500</TERM>-based directory services.  LDAP runs over <TERM>TCP</TERM>/<TERM>IP</TERM> or other connection oriented transfer services.  The nitty-gritty details of LDAP are defined in <A HREF="http://www.rfc-editor.org/rfc/rfc2251.txt">RFC2251</A> &quot;The Lightweight Directory Access Protocol (v3)&quot; and other documents comprising the technical specification <A HREF="http://www.rfc-editor.org/rfc/rfc3377.txt">RFC3377</A>.  This section gives an overview of LDAP from a user's perspective.</P>
-<P><EM>What kind of information can be stored in the directory?</EM> The LDAP information model is based on <EM>entries</EM>. An entry is a collection of attributes that has a globally-unique <TERM>Distinguished Name</TERM> (DN).  The DN is used to refer to the entry unambiguously. Each of the entry's attributes has a <EM>type</EM> and one or more <EM>values</EM>. The types are typically mnemonic strings, like &quot;<TT>cn</TT>&quot; for common name, or &quot;<TT>mail</TT>&quot; for email address. The syntax of values depend on the attribute type.  For example, a <TT>cn</TT> attribute might contain the value <TT>Babs Jensen</TT>.  A <TT>mail</TT> attribute might contain the value &quot;<TT>babs at example.com</TT>&quot;. A <TT>jpegPhoto</TT> attribute would contain a photograph in the JPEG (binary) format.</P>
+<P><TERM>LDAP</TERM> stands for <TERM>Lightweight Directory Access Protocol</TERM>.  As the name suggests, it is a lightweight protocol for accessing directory services, specifically <TERM>X.500</TERM>-based directory services.  LDAP runs over <TERM>TCP</TERM>/<TERM>IP</TERM> or other connection oriented transfer services.  LDAP is an <A HREF="http://www.ietf.org/">IETF</A> Standard Track protocol and is specified in &quot;Lightweight Directory Access Protocol (LDAP) Technical Specification Road Map&quot; <A HREF="http://www.rfc-editor.org/rfc/rfc4510.txt">RFC4510</A>.</P>
+<P>This section gives an overview of LDAP from a user's perspective.</P>
+<P><EM>What kind of information can be stored in the directory?</EM> The LDAP information model is based on <EM>entries</EM>. An entry is a collection of attributes that has a globally-unique <TERM>Distinguished Name</TERM> (DN).  The DN is used to refer to the entry unambiguously. Each of the entry's attributes has a <EM>type</EM> and one or more <EM>values</EM>. The types are typically mnemonic strings, like &quot;<TT>cn</TT>&quot; for common name, or &quot;<TT>mail</TT>&quot; for email address. The syntax of values depend on the attribute type.  For example, a <TT>cn</TT> attribute might contain the value <TT>Babs Jensen</TT>.  A <TT>mail</TT> attribute might contain the value &quot;<TT>babs at example.com</TT>&quot;. A <TT>jpegPhoto</TT> attribute would contain a photograph in the <TERM>JPEG</TERM> (binary) format.</P>
 <P><EM>How is the information arranged?</EM> In LDAP, directory entries are arranged in a hierarchical tree-like structure.  Traditionally, this structure reflected the geographic and/or organizational boundaries.  Entries representing countries appear at the top of the tree. Below them are entries representing states and national organizations. Below them might be entries representing organizational units, people, printers, documents, or just about anything else you can think of.  Figure 1.1 shows an example LDAP directory tree using traditional naming.</P>
-<P><CENTER><IMG SRC="intro_tree.gif" ALIGN="center"></CENTER></P>
+<P><CENTER><IMG SRC="intro_tree.png" ALIGN="center"></CENTER></P>
 <P ALIGN="Center">Figure 1.1: LDAP directory tree (traditional naming)</P>
 <P>The tree may also be arranged based upon Internet domain names. This naming approach is becoming increasing popular as it allows for directory services to be located using the <EM>DNS</EM>. Figure 1.2 shows an example LDAP directory tree using domain-based naming.</P>
-<P><CENTER><IMG SRC="intro_dctree.gif" ALIGN="center"></CENTER></P>
+<P><CENTER><IMG SRC="intro_dctree.png" ALIGN="center"></CENTER></P>
 <P ALIGN="Center">Figure 1.2: LDAP directory tree (Internet naming)</P>
 <P>In addition, LDAP allows you to control which attributes are required and allowed in an entry through the use of a special attribute called <TT>objectClass</TT>.  The values of the <TT>objectClass</TT> attribute determine the <EM>schema</EM> rules the entry must obey.</P>
-<P><EM>How is the information referenced?</EM> An entry is referenced by its distinguished name, which is constructed by taking the name of the entry itself (called the <TERM>Relative Distinguished Name</TERM> or RDN) and concatenating the names of its ancestor entries. For example, the entry for Barbara Jensen in the Internet naming example above has an RDN of <TT>uid=babs</TT> and a DN of <TT>uid=babs,ou=People,dc=example,dc=com</TT>. The full DN format is described in <A HREF="http://www.rfc-editor.org/rfc/rfc2253.txt">RFC2253</A>, &quot;Lightweight Directory Access Protocol (v3):  UTF-8 String Representation of Distinguished Names.&quot;</P>
+<P><EM>How is the information referenced?</EM> An entry is referenced by its distinguished name, which is constructed by taking the name of the entry itself (called the <TERM>Relative Distinguished Name</TERM> or RDN) and concatenating the names of its ancestor entries. For example, the entry for Barbara Jensen in the Internet naming example above has an RDN of <TT>uid=babs</TT> and a DN of <TT>uid=babs,ou=People,dc=example,dc=com</TT>. The full DN format is described in <A HREF="http://www.rfc-editor.org/rfc/rfc4514.txt">RFC4514</A>, &quot;LDAP: String Representation of Distinguished Names.&quot;</P>
 <P><EM>How is the information accessed?</EM> LDAP defines operations for interrogating and updating the directory.  Operations are provided for adding and deleting an entry from the directory, changing an existing entry, and changing the name of an entry. Most of the time, though, LDAP is used to search for information in the directory. The LDAP search operation allows some portion of the directory to be searched for entries that match some criteria specified by a search filter. Information can be requested from each entry that matches the criteria.</P>
 <P>For example, you might want to search the entire directory subtree at and below <TT>dc=example,dc=com</TT> for people with the name <TT>Barbara Jensen</TT>, retrieving the email address of each entry found. LDAP lets you do this easily.  Or you might want to search the entries directly below the <TT>st=California,c=US</TT> entry for organizations with the string <TT>Acme</TT> in their name, and that have a fax number. LDAP lets you do this too. The next section describes in more detail what you can do with LDAP and how it might be useful to you.</P>
 <P><EM>How is the information protected from unauthorized access?</EM> Some directory services provide no protection, allowing anyone to see the information. LDAP provides a mechanism for a client to authenticate, or prove its identity to a directory server, paving the way for rich access control to protect the information the server contains. LDAP also supports data security (integrity and confidentiality) services.</P>
-<H2><A NAME="How does LDAP work">1.3. How does LDAP work?</A></H2>
-<P>LDAP directory service is based on a <EM>client-server</EM> model. One or more LDAP servers contain the data making up the directory information tree (DIT).  The client connects to servers and asks it a question.  The server responds with an answer and/or with a pointer to where the client can get additional information (typically, another LDAP server).  No matter which LDAP server a client connects to, it sees the same view of the directory; a name presented to one LDAP server references the same entry it would at another LDAP server. This is an important feature of a global directory service, like LDAP.</P>
-<H2><A NAME="What about X.500">1.4. What about X.500?</A></H2>
+<H2><A NAME="When should I use LDAP">1.3. When should I use LDAP?</A></H2>
+<P>This is a very good question. In general, you should use a Directory server when you require data to be centrally managed, stored and accessible via standards based methods.</P>
+<P>Some common examples found throughout the industry are, but not limited to:</P>
+<UL>
+<LI>Machine Authentication
+<LI>User Authentication
+<LI>User/System Groups
+<LI>Address book
+<LI>Organization Representation
+<LI>Asset Tracking
+<LI>Telephony Information Store
+<LI>User resource management
+<LI>E-mail address lookups
+<LI>Application Configuration store
+<LI>PBX Configuration store
+<LI>etc.....</UL>
+<P>There are various <A HREF="#Distributed Schema Files">Distributed Schema Files</A> that are standards based, but you can always create your own <A HREF="#Schema Specification">Schema Specification</A>.</P>
+<P>There are always new ways to use a Directory and apply LDAP principles to address certain problems, therefore there is no simple answer to this question.</P>
+<P>If in doubt, join the general LDAP forum for non-commercial discussions and information relating to LDAP at: <A HREF="http://www.umich.edu/~dirsvcs/ldap/mailinglist.html">http://www.umich.edu/~dirsvcs/ldap/mailinglist.html</A> and ask</P>
+<H2><A NAME="When should I not use LDAP">1.4. When should I not use LDAP?</A></H2>
+<P>When you start finding yourself bending the directory to do what you require, maybe a redesign is needed. Or if you only require one application to use and manipulate your data (for discussion of LDAP vs RDBMS, please read the <A HREF="#LDAP vs RDBMS">LDAP vs RDBMS</A> section).</P>
+<P>It will become obvious when LDAP is the right tool for the job.</P>
+<H2><A NAME="How does LDAP work">1.5. How does LDAP work?</A></H2>
+<P>LDAP utilizes a <EM>client-server model</EM>. One or more LDAP servers contain the data making up the directory information tree (<TERM>DIT</TERM>). The client connects to servers and asks it a question.  The server responds with an answer and/or with a pointer to where the client can get additional information (typically, another LDAP server). No matter which LDAP server a client connects to, it sees the same view of the directory; a name presented to one LDAP server references the same entry it would at another LDAP server.  This is an important feature of a global directory service.</P>
+<H2><A NAME="What about X.500">1.6. What about X.500?</A></H2>
 <P>Technically, <TERM>LDAP</TERM> is a directory access protocol to an <TERM>X.500</TERM> directory service, the <TERM>OSI</TERM> directory service. Initially, LDAP clients accessed gateways to the X.500 directory service. This gateway ran LDAP between the client and gateway and X.500's <TERM>Directory Access Protocol</TERM> (<TERM>DAP</TERM>) between the gateway and the X.500 server.  DAP is a heavyweight protocol that operates over a full OSI protocol stack and requires a significant amount of computing resources.  LDAP is designed to operate over <TERM>TCP</TERM>/<TERM>IP</TERM> and provides most of the functionality of DAP at a much lower cost.</P>
 <P>While LDAP is still used to access X.500 directory service via gateways, LDAP is now more commonly directly implemented in X.500 servers.</P>
-<P>The stand-alone LDAP daemon, or <EM>slapd</EM>(8), can be viewed as a <EM>lightweight</EM> X.500 directory server.  That is, it does not implement the X.500's DAP nor does it support the complete X.500 models.</P>
+<P>The Standalone LDAP Daemon, or <EM>slapd</EM>(8), can be viewed as a <EM>lightweight</EM> X.500 directory server.  That is, it does not implement the X.500's DAP nor does it support the complete X.500 models.</P>
 <P>If you are already running a X.500 DAP service and you want to continue to do so, you can probably stop reading this guide.  This guide is all about running LDAP via <EM>slapd</EM>(8), without running X.500 DAP.  If you are not running X.500 DAP, want to stop running X.500 DAP, or have no immediate plans to run X.500 DAP, read on.</P>
-<P>It is possible to replicate data from an LDAP directory server to a X.500 DAP <TERM>DSA</TERM>.  This requires an LDAP/DAP gateway. OpenLDAP does not provide such a gateway, but our replication daemon can be used to replicate to such a gateway.  See the <A HREF="#Replication with slurpd">Replication with slurpd</A> chapter of this document for information regarding replication.</P>
-<H2><A NAME="What is the difference between LDAPv2 and LDAPv3">1.5. What is the difference between LDAPv2 and LDAPv3?</A></H2>
+<P>It is possible to replicate data from an LDAP directory server to a X.500 DAP <TERM>DSA</TERM>.  This requires an LDAP/DAP gateway. OpenLDAP Software does not include such a gateway.</P>
+<H2><A NAME="What is the difference between LDAPv2 and LDAPv3">1.7. What is the difference between LDAPv2 and LDAPv3?</A></H2>
 <P>LDAPv3 was developed in the late 1990's to replace LDAPv2. LDAPv3 adds the following features to LDAP:</P>
-<UL><UL>
+<UL>
 <LI>Strong authentication and data security services via <TERM>SASL</TERM>
 <LI>Certificate authentication and data security services via <TERM>TLS</TERM> (SSL)
 <LI>Internationalization through the use of Unicode
 <LI>Referrals and Continuations
 <LI>Schema Discovery
-<LI>Extensibility (controls, extended operations, and more)</UL></UL>
-<P>LDAPv2 is historic (<A HREF="http://www.rfc-editor.org/rfc/rfc3494.txt">RFC3494</A>).  As most <EM>so-called</EM> LDAPv2 implementations (including <EM>slapd</EM>(8)) do not conform to the LDAPv2 technical specification, interoperatibility amongst implementations claiming LDAPv2 support is limited.  As LDAPv2 differs significantly from LDAPv3, deploying both LDAPv2 and LDAPv3 simultaneously is quite problematic.  LDAPv2 should be avoided. LDAPv2 is disabled by default.</P>
-<H2><A NAME="What is slapd and what can it do">1.6. What is slapd and what can it do?</A></H2>
+<LI>Extensibility (controls, extended operations, and more)</UL>
+<P>LDAPv2 is historic (<A HREF="http://www.rfc-editor.org/rfc/rfc3494.txt">RFC3494</A>).  As most <EM>so-called</EM> LDAPv2 implementations (including <EM>slapd</EM>(8)) do not conform to the LDAPv2 technical specification, interoperability amongst implementations claiming LDAPv2 support is limited.  As LDAPv2 differs significantly from LDAPv3, deploying both LDAPv2 and LDAPv3 simultaneously is quite problematic.  LDAPv2 should be avoided. LDAPv2 is disabled by default.</P>
+<H2><A NAME="LDAP vs RDBMS">1.8. LDAP vs RDBMS</A></H2>
+<P>This question is raised many times, in different forms. The most common, however, is: <EM>Why doesn't OpenLDAP drop Berkeley DB and use a relational database management system (RDBMS) instead?</EM> In general, expecting that the sophisticated algorithms implemented by commercial-grade RDBMS would make <EM>OpenLDAP</EM> be faster or somehow better and, at the same time, permitting sharing of data with other applications.</P>
+<P>The short answer is that use of an embedded database and custom indexing system allows OpenLDAP to provide greater performance and scalability without loss of reliability. OpenLDAP uses Berkeley DB concurrent / transactional database software. This is the same software used by leading commercial directory software.</P>
+<P>Now for the long answer. We are all confronted all the time with the choice RDBMSes vs. directories. It is a hard choice and no simple answer exists.</P>
+<P>It is tempting to think that having a RDBMS backend to the directory solves all problems. However, it is a pig. This is because the data models are very different. Representing directory data with a relational database is going to require splitting data into multiple tables.</P>
+<P>Think for a moment about the person objectclass. Its definition requires attribute types objectclass, sn and cn and allows attribute types userPassword, telephoneNumber, seeAlso and description. All of these attributes are multivalued, so a normalization requires putting each attribute type in a separate table.</P>
+<P>Now you have to decide on appropriate keys for those tables. The primary key might be a combination of the DN, but this becomes rather inefficient on most database implementations.</P>
+<P>The big problem now is that accessing data from one entry requires seeking on different disk areas. On some applications this may be OK but in many applications performance suffers.</P>
+<P>The only attribute types that can be put in the main table entry are those that are mandatory and single-value. You may add also the optional single-valued attributes and set them to NULL or something if not present.</P>
+<P>But wait, the entry can have multiple objectclasses and they are organized in an inheritance hierarchy. An entry of objectclass organizationalPerson now has the attributes from person plus a few others and some formerly optional attribute types are now mandatory.</P>
+<P>What to do? Should we have different tables for the different objectclasses? This way the person would have an entry on the person table, another on organizationalPerson, etc. Or should we get rid of person and put everything on the second table?</P>
+<P>But what do we do with a filter like (cn=*) where cn is an attribute type that appears in many, many objectclasses. Should we search all possible tables for matching entries? Not very attractive.</P>
+<P>Once this point is reached, three approaches come to mind. One is to do full normalization so that each attribute type, no matter what, has its own separate table. The simplistic approach where the DN is part of the primary key is extremely wasteful, and calls for an approach where the entry has a unique numeric id that is used instead for the keys and a main table that maps DNs to ids. The approach, anyway, is very inefficient when several attribute types from one or more entries are requested. Such a database, though cumbersomely, can be managed from SQL applications.</P>
+<P>The second approach is to put the whole entry as a blob in a table shared by all entries regardless of the objectclass and have additional tables that act as indices for the first table. Index tables are not database indices, but are fully managed by the LDAP server-side implementation. However, the database becomes unusable from SQL. And, thus, a fully fledged database system provides little or no advantage. The full generality of the database is unneeded. Much better to use something light and fast, like Berkeley DB.</P>
+<P>A completely different way to see this is to give up any hopes of implementing the directory data model. In this case, LDAP is used as an access protocol to data that provides only superficially the directory data model. For instance, it may be read only or, where updates are allowed, restrictions are applied, such as making single-value attribute types that would allow for multiple values. Or the impossibility to add new objectclasses to an existing entry or remove one of those present. The restrictions span the range from allowed restrictions (that might be elsewhere the result of access control) to outright violations of the data model. It can be, however, a method to provide LDAP access to preexisting data that is used by other applications. But in the understanding that we don't really have a &quot;directory&quot;.</P>
+<P>Existing commercial LDAP server implementations that use a relational database are either from the first kind or the third. I don't know of any implementation that uses a relational database to do inefficiently what BDB does efficiently. For those who are interested in &quot;third way&quot; (exposing EXISTING data from RDBMS as LDAP tree, having some limitations compared to classic LDAP model, but making it possible to interoperate between LDAP and SQL applications):</P>
+<P>OpenLDAP includes back-sql - the backend that makes it possible. It uses ODBC + additional metainformation about translating LDAP queries to SQL queries in your RDBMS schema, providing different levels of access - from read-only to full access depending on RDBMS you use, and your schema.</P>
+<P>For more information on concept and limitations, see <EM>slapd-sql</EM>(5) man page, or the <A HREF="#Backends">Backends</A> section. There are also several examples for several RDBMSes in <TT>back-sql/rdbms_depend/*</TT> subdirectories.</P>
+<H2><A NAME="What is slapd and what can it do">1.9. What is slapd and what can it do?</A></H2>
 <P><EM>slapd</EM>(8) is an LDAP directory server that runs on many different platforms. You can use it to provide a directory service of your very own.  Your directory can contain pretty much anything you want to put in it. You can connect it to the global LDAP directory service, or run a service all by yourself. Some of slapd's more interesting features and capabilities include:</P>
-<P><B>LDAPv3</B>: <EM>slapd</EM> implements version 3 of <TERM>Lightweight Directory Access Protocol</TERM>. <EM>slapd</EM> supports LDAP over both IPv4 and IPv6 and Unix IPC.</P>
-<P><B><TERM>Simple Authentication and Security Layer</TERM></B>: <EM>slapd</EM> supports strong authentication and data security (integrity and confidentiality) services through the use of SASL.  <EM>slapd</EM>'s SASL implementation utilizes <A HREF="http://asg.web.cmu.edu/cyrus/">Cyrus</A> <A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">SASL</A> software which supports a number of mechanisms including DIGEST-MD5, EXTERNAL, and GSSAPI.</P>
-<P><B><TERM>Transport Layer Security</TERM></B>: <EM>slapd</EM> supports certificate-based authentication and data security (integrity and confidentiality) services through the use of TLS (or SSL).  <EM>slapd</EM>'s TLS implementation utilizes <A HREF="http://www.openssl.org/">OpenSSL</A> software.</P>
+<P><B>LDAPv3</B>: <EM>slapd</EM> implements version 3 of <TERM>Lightweight Directory Access Protocol</TERM>. <EM>slapd</EM> supports LDAP over both <TERM>IPv4</TERM> and <TERM>IPv6</TERM> and Unix <TERM>IPC</TERM>.</P>
+<P><B><TERM>Simple Authentication and Security Layer</TERM></B>: <EM>slapd</EM> supports strong authentication and data security (integrity and confidentiality) services through the use of SASL.  <EM>slapd</EM>'s SASL implementation utilizes <A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">Cyrus SASL</A> software which supports a number of mechanisms including <TERM>DIGEST-MD5</TERM>, <TERM>EXTERNAL</TERM>, and <TERM>GSSAPI</TERM>.</P>
+<P><B><TERM>Transport Layer Security</TERM></B>: <EM>slapd</EM> supports certificate-based authentication and data security (integrity and confidentiality) services through the use of TLS (or SSL).  <EM>slapd</EM>'s TLS implementation can utilize either <A HREF="http://www.openssl.org/">OpenSSL</A> or <A HREF="http://www.gnu.org/software/gnutls/">GnuTLS</A> software.</P>
 <P><B>Topology control</B>: <EM>slapd</EM> can be configured to restrict access at the socket layer based upon network topology information. This feature utilizes <EM>TCP wrappers</EM>.</P>
 <P><B>Access control</B>: <EM>slapd</EM> provides a rich and powerful access control facility, allowing you to control access to the information in your database(s). You can control access to entries based on LDAP authorization information, <TERM>IP</TERM> address, domain name and other criteria.  <EM>slapd</EM> supports both <EM>static</EM> and <EM>dynamic</EM> access control information.</P>
 <P><B>Internationalization</B>: <EM>slapd</EM> supports Unicode and language tags.</P>
-<P><B>Choice of database backends</B>: <EM>slapd</EM> comes with a variety of different database backends you can choose from. They include <TERM>BDB</TERM>, a high-performance transactional database backend; <TERM>HDB</TERM>, a hierarchical high-performance transactional backend; <TERM>LDBM</TERM>, a lightweight DBM based backend; <EM>SHELL</EM>, a backend interface to arbitrary shell scripts; and PASSWD, a simple backend interface to the <EM>passwd</EM>(5) file.  The BDB and HDB backends utilize <A HREF="http://www.sleepycat.com/">Sleepycat</A> <A HREF="http://www.sleepycat.com/products/transactional.shtml">Berkeley DB</A>.  The LDBM utilizes either <A HREF="http://www.sleepycat.com/products/transactional.shtml">Berkeley DB</A> or <A HREF="http://www.gnu.org/software/gdbm/">GDBM</A>.</P>
+<P><B>Choice of database backends</B>: <EM>slapd</EM> comes with a variety of different database backends you can choose from. They include <TERM>BDB</TERM>, a high-performance transactional database backend; <TERM>HDB</TERM>, a hierarchical high-performance transactional backend; <EM>SHELL</EM>, a backend interface to arbitrary shell scripts; and PASSWD, a simple backend interface to the <EM>passwd</EM>(5) file. The BDB and HDB backends utilize <A HREF="http://www.oracle.com/">Oracle</A> <A HREF="http://www.oracle.com/database/berkeley-db/db/index.html">Berkeley DB</A>.</P>
 <P><B>Multiple database instances</B>: <EM>slapd</EM> can be configured to serve multiple databases at the same time. This means that a single <EM>slapd</EM> server can respond to requests for many logically different portions of the LDAP tree, using the same or different database backends.</P>
-<P><B>Generic modules API</B>:  If you require even more customization, <EM>slapd</EM> lets you write your own modules easily. <EM>slapd</EM> consists of two distinct parts: a front end that handles protocol communication with LDAP clients; and modules which handle specific tasks such as database operations.  Because these two pieces communicate via a well-defined <TERM>C</TERM> <TERM>API</TERM>, you can write your own customized modules which extend <EM>slapd</EM> in numerous ways.  Also, a number of <EM>programmable database</EM> modules are provided.  These allow you to expose external data sources to <EM>slapd</EM> using popular programming languages (<A HREF="http://www.perl.org/">Perl</A>, <EM>shell</EM>, <A HREF="http://www.jcc.com/SQLPages/jccs_sql.htm">SQL</A>, and <A HREF="http://www.tcl.tk/">TCL</A>).</P>
+<P><B>Generic modules API</B>:  If you require even more customization, <EM>slapd</EM> lets you write your own modules easily. <EM>slapd</EM> consists of two distinct parts: a front end that handles protocol communication with LDAP clients; and modules which handle specific tasks such as database operations.  Because these two pieces communicate via a well-defined <TERM>C</TERM> <TERM>API</TERM>, you can write your own customized modules which extend <EM>slapd</EM> in numerous ways.  Also, a number of <EM>programmable database</EM> modules are provided.  These allow you to expose external data sources to <EM>slapd</EM> using popular programming languages (<A HREF="http://www.perl.org/">Perl</A>, <EM>shell</EM>, and <TERM>SQL</TERM>.</P>
 <P><B>Threads</B>: <EM>slapd</EM> is threaded for high performance.  A single multi-threaded <EM>slapd</EM> process handles all incoming requests using a pool of threads.  This reduces the amount of system overhead required while providing high performance.</P>
-<P><B>Replication</B>: <EM>slapd</EM> can be configured to maintain shadow copies of directory information.  This <EM>single-master/multiple-slave</EM> replication scheme is vital in high-volume environments where a single <EM>slapd</EM> just doesn't provide the necessary availability or reliability. <EM>slapd</EM> supports two replication methods: <EM>LDAP Sync</EM>-based and <EM>slurpd</EM>(8)-based replication.</P>
+<P><B>Replication</B>: <EM>slapd</EM> can be configured to maintain shadow copies of directory information.  This <EM>single-master/multiple-slave</EM> replication scheme is vital in high-volume environments where a single <EM>slapd</EM> installation just doesn't provide the necessary availability or reliability.  For extremely demanding environments where a single point of failure is not acceptable, <EM>multi-master</EM> replication is also available.  <EM>slapd</EM> includes support for <EM>LDAP Sync</EM>-based replication.</P>
 <P><B>Proxy Cache</B>: <EM>slapd</EM> can be configured as a caching LDAP proxy service.</P>
-<P><B>Configuration</B>: <EM>slapd</EM> is highly configurable through a single configuration file which allows you to change just about everything you'd ever want to change.  Configuration options have reasonable defaults, making your job much easier.</P>
-<H2><A NAME="What is slurpd and what can it do">1.7. What is slurpd and what can it do?</A></H2>
-<P><EM>slurpd</EM>(8) is a daemon that, with <EM>slapd</EM> help, provides replicated service.  It is responsible for distributing changes made to the master <EM>slapd</EM> database out to the various <EM>slapd</EM> replicas.  It frees <EM>slapd</EM> from having to worry that some replicas might be down or unreachable when a change comes through; <EM>slurpd</EM> handles retrying failed requests automatically.  <EM>slapd</EM> and <EM>slurpd</EM> communicate through a simple text file that is used to log changes.</P>
-<P>See the <A HREF="#Replication with slurpd">Replication with slurpd</A> chapter for information about how to configure and run <EM>slurpd</EM>(8).</P>
-<P>Alternatively, <EM>LDAP-Sync</EM>-based replication may be used to provide a replicated service.  See the <A HREF="#LDAP Sync Replication">LDAP Sync Replication</A> chapter for details.</P>
+<P><B>Configuration</B>: <EM>slapd</EM> is highly configurable through a single configuration file which allows you to change just about everything you'd ever want to change.  Configuration options have reasonable defaults, making your job much easier. Configuration can also be performed dynamically using LDAP itself, which greatly improves manageability.</P>
 <P></P>
 <HR>
 <H1><A NAME="A Quick-Start Guide">2. A Quick-Start Guide</A></H1>
-<P>The following is a quick start guide to OpenLDAP Software 2.3, including the stand-alone LDAP daemon, <EM>slapd</EM>(8).</P>
-<P>It is meant to walk you through the basic steps needed to install and configure OpenLDAP Software. It should be used in conjunction with the other chapters of this document, manual pages, and other materials provided with the distribution (e.g. the <TT>INSTALL</TT> document) or on the OpenLDAP web site (in particular, the OpenLDAP Software <TERM>FAQ</TERM>).</P>
+<P>The following is a quick start guide to OpenLDAP Software 2.4, including the Standalone <TERM>LDAP</TERM> Daemon, <EM>slapd</EM>(8).</P>
+<P>It is meant to walk you through the basic steps needed to install and configure <A HREF="http://www.openldap.org/software/">OpenLDAP Software</A>.  It should be used in conjunction with the other chapters of this document, manual pages, and other materials provided with the distribution (e.g. the <TT>INSTALL</TT> document) or on the <A HREF="http://www.openldap.org/">OpenLDAP</A> web site (<A HREF="http://www.OpenLDAP.org">http://www.OpenLDAP.org</A>), in particular the OpenLDAP Software <TERM>FAQ</TERM> (<A HREF="http://www.OpenLDAP.org/faq/?file=2">http://www.OpenLDAP.org/faq/?file=2</A>).</P>
 <P>If you intend to run OpenLDAP Software seriously, you should review all of this document before attempting to install the software.</P>
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>This quick start guide does not use strong authentication nor any integrity or confidential protection services.  These services are described in other chapters of the OpenLDAP Administrator's Guide.
@@ -317,7 +993,7 @@
 &nbsp;</UL><OL>
 <LI><B>Get the software</B>
 <BR>
-You can obtain a copy of the software by following the instructions on the OpenLDAP download page (<A HREF="http://www.openldap.org/software/download/">http://www.openldap.org/software/download/</A>).  It is recommended that new users start with the latest <EM>release</EM>.
+You can obtain a copy of the software by following the instructions on the OpenLDAP Software download page (<A HREF="http://www.openldap.org/software/download/">http://www.openldap.org/software/download/</A>).  It is recommended that new users start with the latest <EM>release</EM>.
 <BR>
 &nbsp;
 <LI><B>Unpack the distribution</B>
@@ -333,7 +1009,7 @@
 &nbsp;
 <LI><B>Review documentation</B>
 <BR>
-You should now review the <TT>COPYRIGHT</TT>, <TT>LICENSE</TT>, <TT>README</TT> and <TT>INSTALL</TT> documents provided with the distribution. The <TT>COPYRIGHT</TT> and <TT>LICENSE</TT> provide information on acceptable use, copying, and limitation of warranty of OpenLDAP software.
+You should now review the <TT>COPYRIGHT</TT>, <TT>LICENSE</TT>, <TT>README</TT> and <TT>INSTALL</TT> documents provided with the distribution. The <TT>COPYRIGHT</TT> and <TT>LICENSE</TT> provide information on acceptable use, copying, and limitation of warranty of OpenLDAP Software.
 <BR>
 &nbsp;
 <BR>
@@ -348,7 +1024,7 @@
 However, given that you are using this guide, we'll assume you are brave enough to just let <TT>configure</TT> determine what's best:<UL>
 <TT>./configure</TT></UL>
 <BR>
-Assuming <TT>configure</TT> doesn't dislike your system, you can proceed with building the software.  If <TT>configure</TT> did complain, well, you'll likely need to go to the FAQ Installation Section (<A HREF="http://www.openldap.org/faq/">http://www.openldap.org/faq/</A> and/or actually read the <A HREF="#Building and Installing OpenLDAP Software">Building and Installing OpenLDAP Software</A> chapter of this document.
+Assuming <TT>configure</TT> doesn't dislike your system, you can proceed with building the software.  If <TT>configure</TT> did complain, well, you'll likely need to go to the Software FAQ <EM>Installation</EM> section (<A HREF="http://www.openldap.org/faq/?file=8">http://www.openldap.org/faq/?file=8</A>) and/or actually read the <A HREF="#Building and Installing OpenLDAP Software">Building and Installing OpenLDAP Software</A> chapter of this document.
 <BR>
 &nbsp;
 <LI><B>Build the software</B>.
@@ -417,10 +1093,10 @@
 &nbsp;
 <LI><B>Start SLAPD</B>.
 <BR>
-You are now ready to start the stand-alone LDAP server, <EM>slapd</EM>(8), by running the command:<UL>
+You are now ready to start the Standalone LDAP Daemon, <EM>slapd</EM>(8), by running the command:<UL>
 <TT>su root -c /usr/local/libexec/slapd</TT></UL>
 <BR>
-To check to see if the server is running and configured correctly, you can run a search against it with <EM>ldapsearch</EM>(1).  By default, ldapsearch is installed as <TT>/usr/local/bin/ldapsearch</TT>:<UL>
+To check to see if the server is running and configured correctly, you can run a search against it with <EM>ldapsearch</EM>(1).  By default, <EM>ldapsearch</EM> is installed as <TT>/usr/local/bin/ldapsearch</TT>:<UL>
 <TT>ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts</TT></UL>
 <BR>
 Note the use of single quotes around command parameters to prevent special characters from being interpreted by the shell.  This should return:<UL>
@@ -433,7 +1109,7 @@
 &nbsp;
 <LI><B>Add initial entries to your directory</B>.
 <BR>
-You can use <EM>ldapadd</EM>(1) to add entries to your LDAP directory. <EM>ldapadd</EM> expects input in LDIF form. We'll do it in two steps:<OL>
+You can use <EM>ldapadd</EM>(1) to add entries to your LDAP directory. <EM>ldapadd</EM> expects input in <TERM>LDIF</TERM> form.  We'll do it in two steps:<OL>
 <LI>create an LDIF file
 <LI>run ldapadd</OL>
 <BR>
@@ -494,36 +1170,36 @@
 <BR>
 This command will search for and retrieve every entry in the database.</OL>
 <P>You are now ready to add more entries using <EM>ldapadd</EM>(1) or another LDAP client, experiment with various configuration options, backend arrangements, etc..</P>
-<P>Note that by default, the <EM>slapd</EM>(8) database grants <EM>read access to everybody</EM> excepting the <EM>super-user</EM> (as specified by the <TT>rootdn</TT> configuration directive).  It is highly recommended that you establish controls to restrict access to authorized users. Access controls are discussed in the <A HREF="#Access Control">Access Control</A> section of <A HREF="#The slapd Configuration File">The slapd Configuration File</A> chapter.  You are also encouraged to read the <A HREF="#Security Considerations">Security Considerations</A>, <A HREF="#Using SASL">Using SASL</A> and <A HREF="#Using TLS">Using TLS</A> sections.</P>
+<P>Note that by default, the <EM>slapd</EM>(8) database grants <EM>read access to everybody</EM> excepting the <EM>super-user</EM> (as specified by the <TT>rootdn</TT> configuration directive).  It is highly recommended that you establish controls to restrict access to authorized users. Access controls are discussed in the <A HREF="#The access Configuration Directive">The access Configuration Directive</A> section of <A HREF="#The slapd Configuration File">The slapd Configuration File</A> chapter. You are also encouraged to read the <A HREF="#Security Considerations">Security Considerations</A>, <A HREF="#Using SASL">Using SASL</A> and <A HREF="#Using TLS">Using TLS</A> sections.</P>
 <P>The following chapters provide more detailed information on making, installing, and running <EM>slapd</EM>(8).</P>
 <P></P>
 <HR>
 <H1><A NAME="The Big Picture - Configuration Choices">3. The Big Picture - Configuration Choices</A></H1>
-<P>This section gives a brief overview of various <TERM>LDAP</TERM> directory configurations, and how your stand-alone LDAP server <EM>slapd</EM>(8) fits in with the rest of the world.</P>
+<P>This section gives a brief overview of various <TERM>LDAP</TERM> directory configurations, and how your Standalone LDAP Daemon <EM>slapd</EM>(8) fits in with the rest of the world.</P>
 <H2><A NAME="Local Directory Service">3.1. Local Directory Service</A></H2>
-<P>In this configuration, you run a <EM>slapd</EM> which provides directory service for your local domain only. It does not interact with other directory servers in any way. This configuration is shown in Figure 3.1.</P>
-<P><CENTER><IMG SRC="config_local.gif" ALIGN="center"></CENTER></P>
+<P>In this configuration, you run a <EM>slapd</EM>(8) instance which provides directory service for your local domain only. It does not interact with other directory servers in any way. This configuration is shown in Figure 3.1.</P>
+<P><CENTER><IMG SRC="config_local.png" ALIGN="center"></CENTER></P>
 <P ALIGN="Center">Figure 3.1: Local service configuration.</P>
 <P>Use this configuration if you are just starting out (it's the one the quick-start guide makes for you) or if you want to provide a local service and are not interested in connecting to the rest of the world. It's easy to upgrade to another configuration later if you want.</P>
 <H2><A NAME="Local Directory Service with Referrals">3.2. Local Directory Service with Referrals</A></H2>
-<P>In this configuration, you run a slapd which provides directory service for your local domain and configure it to return referrals to a <EM>superior</EM> service capable of handling requests outside your local domain. You may run this service yourself or use one provided to you. This configuration is shown in Figure 3.2.</P>
-<P><CENTER><IMG SRC="config_ref.gif" ALIGN="center"></CENTER></P>
+<P>In this configuration, you run a <EM>slapd</EM>(8) instance which provides directory service for your local domain and configure it to return referrals to other servers capable of handling requests.  You may run this service (or services) yourself or use one provided to you. This configuration is shown in Figure 3.2.</P>
+<P><CENTER><IMG SRC="config_ref.png" ALIGN="center"></CENTER></P>
 <P ALIGN="Center">Figure 3.2: Local service with referrals</P>
-<P>Use this configuration if you want to provide local service and participate in the Global Directory.</P>
+<P>Use this configuration if you want to provide local service and participate in the Global Directory,  or you want to delegate responsibility for <EM>subordinate</EM> entries to another server.</P>
 <H2><A NAME="Replicated Directory Service">3.3. Replicated Directory Service</A></H2>
-<P>The slurpd daemon is used to propagate changes from a master slapd to one or more slave slapds. An example master-slave configuration is shown in figure 3.3.</P>
+<P>slapd(8) includes support for <EM>LDAP Sync</EM>-based replication, called <EM>syncrepl</EM>, which may be used to maintain shadow copies of directory information on multiple directory servers.   In its most basic configuration, the <EM>master</EM> is a syncrepl provider and one or more <EM>slave</EM> (or <EM>shadow</EM>) are syncrepl consumers.  An example master-slave configuration is shown in figure 3.3.</P>
 <P><CENTER><IMG SRC="config_repl.gif" ALIGN="center"></CENTER></P>
 <P ALIGN="Center">Figure 3.3: Replicated Directory Services</P>
-<P>This configuration can be used in conjunction with either of the first two configurations in situations where a single slapd does not provide the required reliability or availability.</P>
+<P>This configuration can be used in conjunction with either of the first two configurations in situations where a single <EM>slapd</EM>(8) instance does not provide the required reliability or availability.</P>
 <H2><A NAME="Distributed Local Directory Service">3.4. Distributed Local Directory Service</A></H2>
 <P>In this configuration, the local service is partitioned into smaller services, each of which may be replicated, and <EM>glued</EM> together with <EM>superior</EM> and <EM>subordinate</EM> referrals.</P>
 <P></P>
 <HR>
 <H1><A NAME="Building and Installing OpenLDAP Software">4. Building and Installing OpenLDAP Software</A></H1>
-<P>This chapter details how to build and install the <A HREF="http://www.openldap.org/">OpenLDAP</A> Software package including <EM>slapd</EM>(8), the stand-alone LDAP daemon and <EM>slurpd</EM>(8), the stand-alone update replication daemon. Building and installing OpenLDAP Software requires several steps: installing prerequisite software, configuring OpenLDAP Software itself, making, and finally installing.  The following sections describe this process in detail.</P>
+<P>This chapter details how to build and install the <A HREF="http://www.openldap.org/">OpenLDAP</A> Software package including <EM>slapd</EM>(8), the Standalone <TERM>LDAP</TERM> Daemon.  Building and installing OpenLDAP Software requires several steps: installing prerequisite software, configuring OpenLDAP Software itself, making, and finally installing.  The following sections describe this process in detail.</P>
 <H2><A NAME="Obtaining and Extracting the Software">4.1. Obtaining and Extracting the Software</A></H2>
 <P>You can obtain OpenLDAP Software from the project's download page at <A HREF="http://www.openldap.org/software/download/">http://www.openldap.org/software/download/</A> or directly from the project's <TERM>FTP</TERM> service at <A HREF="ftp://ftp.openldap.org/pub/OpenLDAP/">ftp://ftp.openldap.org/pub/OpenLDAP/</A>.</P>
-<P>The project makes available two series of packages for <EM>general use</EM>.  The project makes <EM>releases</EM> as new features and bug fixes come available.  Though the project takes steps to improve stablity of these releases, it is common for problems to arise only after <EM>release</EM>.  The <EM>stable</EM> release is the latest <EM>release</EM> which has demonstrated stability through general use.</P>
+<P>The project makes available two series of packages for <EM>general use</EM>.  The project makes <EM>releases</EM> as new features and bug fixes come available.  Though the project takes steps to improve stability of these releases, it is common for problems to arise only after <EM>release</EM>.  The <EM>stable</EM> release is the latest <EM>release</EM> which has demonstrated stability through general use.</P>
 <P>Users of OpenLDAP Software can choose, depending on their desire for the <EM>latest features</EM> versus <EM>demonstrated stability</EM>, the most appropriate series to install.</P>
 <P>After downloading OpenLDAP Software, you need to extract the distribution from the compressed archive file and change your working directory to the top directory of the distribution:</P>
 <UL>
@@ -535,22 +1211,25 @@
 <H2><A NAME="Prerequisite software">4.2. Prerequisite software</A></H2>
 <P>OpenLDAP Software relies upon a number of software packages distributed by third parties.  Depending on the features you intend to use, you may have to download and install a number of additional software packages.  This section details commonly needed third party software packages you might have to install.  However, for an up-to-date prerequisite information, the <TT>README</TT> document should be consulted.  Note that some of these third party packages may depend on additional software packages.  Install each package per the installation instructions provided with it.</P>
 <H3><A NAME="{{TERM[expand]TLS}}">4.2.1. <TERM>Transport Layer Security</TERM></A></H3>
-<P>OpenLDAP clients and servers require installation of <A HREF="http://www.openssl.org/">OpenSSL</A> <TERM>TLS</TERM> libraries to provide <TERM>Transport Layer Security</TERM> services.  Though some operating systems may provide these libraries as part of the base system or as an optional software component, OpenSSL often requires separate installation.</P>
-<P>OpenSSL is available from <A HREF="http://www.openssl.org/">http://www.openssl.org/</A>.</P>
-<P>OpenLDAP Software will not be fully LDAPv3 compliant unless OpenLDAP's <TT>configure</TT> detects a usable OpenSSL installation.</P>
-<H3><A NAME="Kerberos Authentication Services">4.2.2. Kerberos Authentication Services</A></H3>
-<P>OpenLDAP clients and servers support Kerberos-based authentication services. In particular, OpenLDAP supports the <TERM>SASL</TERM>/<TERM>GSSAPI</TERM> authentication mechanism using either <A HREF="http://www.pdc.kth.se/heimdal/">Heimdal</A> or <A HREF="http://web.mit.edu/kerberos/www/">MIT Kerberos</A> V packages. If you desire to use Kerberos-based SASL/GSSAPI authentication, you should install either Heimdal or MIT Kerberos V.</P>
+<P>OpenLDAP clients and servers require installation of either <A HREF="http://www.openssl.org/">OpenSSL</A> or <A HREF="http://www.gnu.org/software/gnutls/">GnuTLS</A> <TERM>TLS</TERM> libraries to provide <TERM>Transport Layer Security</TERM> services.  Though some operating systems may provide these libraries as part of the base system or as an optional software component, OpenSSL and GnuTLS often require separate installation.</P>
+<P>OpenSSL is available from <A HREF="http://www.openssl.org/">http://www.openssl.org/</A>. GnuTLS is available from <A HREF="http://www.gnu.org/software/gnutls/">http://www.gnu.org/software/gnutls/</A>.</P>
+<P>OpenLDAP Software will not be fully LDAPv3 compliant unless OpenLDAP's <TT>configure</TT> detects a usable TLS library.</P>
+<H3><A NAME="{{TERM[expand]SASL}}">4.2.2. <TERM>Simple Authentication and Security Layer</TERM></A></H3>
+<P>OpenLDAP clients and servers require installation of <A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">Cyrus SASL</A> libraries to provide <TERM>Simple Authentication and Security Layer</TERM> services.  Though some operating systems may provide this library as part of the base system or as an optional software component, Cyrus SASL often requires separate installation.</P>
+<P>Cyrus SASL is available from <A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">http://asg.web.cmu.edu/sasl/sasl-library.html</A>. Cyrus SASL will make use of OpenSSL and Kerberos/GSSAPI libraries if preinstalled.</P>
+<P>OpenLDAP Software will not be fully LDAPv3 compliant unless OpenLDAP's configure detects a usable Cyrus SASL installation.</P>
+<H3><A NAME="{{TERM[expand]Kerberos}}">4.2.3. <TERM>Kerberos Authentication Service</TERM></A></H3>
+<P>OpenLDAP clients and servers support <TERM>Kerberos</TERM> authentication services.  In particular, OpenLDAP supports the Kerberos V <TERM>GSS-API</TERM> <TERM>SASL</TERM> authentication mechanism known as the <TERM>GSSAPI</TERM> mechanism.  This feature requires, in addition to Cyrus SASL libraries, either <A HREF="http://www.pdc.kth.se/heimdal/">Heimdal</A> or <A HREF="http://web.mit.edu/kerberos/www/">MIT Kerberos</A> V libraries.</P>
 <P>Heimdal Kerberos is available from <A HREF="http://www.pdc.kth.se/heimdal/">http://www.pdc.kth.se/heimdal/</A>. MIT Kerberos is available from <A HREF="http://web.mit.edu/kerberos/www/">http://web.mit.edu/kerberos/www/</A>.</P>
 <P>Use of strong authentication services, such as those provided by Kerberos, is highly recommended.</P>
-<H3><A NAME="{{TERM[expand]SASL}}">4.2.3. <TERM>Simple Authentication and Security Layer</TERM></A></H3>
-<P>OpenLDAP clients and servers require installation of <A HREF="http://asg.web.cmu.edu/cyrus/">Cyrus</A>'s <A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">SASL</A> libraries to provide <TERM>Simple Authentication and Security Layer</TERM> services.  Though some operating systems may provide this library as part of the base system or as an optional software component, Cyrus SASL often requires separate installation.</P>
-<P>Cyrus SASL is available from <A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">http://asg.web.cmu.edu/sasl/sasl-library.html</A>. Cyrus SASL will make use of OpenSSL and Kerberos/GSSAPI libraries if preinstalled.</P>
-<P>OpenLDAP Software will not be fully LDAPv3 compliant unless OpenLDAP's configure detects a usable Cyrus SASL installation.</P>
 <H3><A NAME="Database Software">4.2.4. Database Software</A></H3>
-<P>OpenLDAP's <EM>slapd</EM>(8) <TERM>BDB</TERM> and <TERM>HDB</TERM> primary database backends require <A HREF="http://www.sleepycat.com/">Sleepycat Software</A> <A HREF="http://www.sleepycat.com/products/transactional.shtml">Berkeley DB</A>. If not available at configure time, you will not be able build <EM>slapd</EM>(8) with these primary database backends.</P>
-<P>Your operating system may provide a supported version of <A HREF="http://www.sleepycat.com/products/transactional.shtml">Berkeley DB</A> in the base system or as an optional software component.  If not, you'll have to obtain and install it yourself.</P>
-<P><A HREF="http://www.sleepycat.com/products/transactional.shtml">Berkeley DB</A> is available from <A HREF="http://www.sleepycat.com/">Sleepycat Software</A>'s download page <A HREF="http://www.sleepycat.com/download/">http://www.sleepycat.com/download/</A>.  There are several versions available.  Generally, the most recent release (with published patches) is recommended.  This package is required if you wish to use the <TERM>BDB</TERM> or <TERM>HDB</TERM> database backends.</P>
-<P>OpenLDAP's <EM>slapd</EM>(8) LDBM backend supports a variety of data base managers including <A HREF="http://www.sleepycat.com/products/transactional.shtml">Berkeley DB</A> and <A HREF="http://www.gnu.org/software/gdbm/">GDBM</A>. <A HREF="http://www.gnu.org/software/gdbm/">GDBM</A> is available from <A HREF="http://www.fsf.org/">FSF</A>'s download site <A HREF="ftp://ftp.gnu.org/pub/gnu/gdbm/">ftp://ftp.gnu.org/pub/gnu/gdbm/</A>.</P>
+<P>OpenLDAP's <EM>slapd</EM>(8) <TERM>BDB</TERM> and <TERM>HDB</TERM> primary database backends require <A HREF="http://www.oracle.com/">Oracle Corporation</A> <A HREF="http://www.oracle.com/database/berkeley-db/db/index.html">Berkeley DB</A>. If not available at configure time, you will not be able build <EM>slapd</EM>(8) with these primary database backends.</P>
+<P>Your operating system may provide a supported version of <A HREF="http://www.oracle.com/database/berkeley-db/db/index.html">Berkeley DB</A> in the base system or as an optional software component.  If not, you'll have to obtain and install it yourself.</P>
+<P><A HREF="http://www.oracle.com/database/berkeley-db/db/index.html">Berkeley DB</A> is available from <A HREF="http://www.oracle.com/">Oracle Corporation</A>'s Berkeley DB download page <A HREF="http://www.oracle.com/technology/software/products/berkeley-db/index.html">http://www.oracle.com/technology/software/products/berkeley-db/index.html</A>.</P>
+<P>There are several versions available. Generally, the most recent release (with published patches) is recommended. This package is required if you wish to use the <TERM>BDB</TERM> or <TERM>HDB</TERM> database backends.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>Please see <A HREF="#Recommended OpenLDAP Software Dependency Versions">Recommended OpenLDAP Software Dependency Versions</A> for more information.
+<HR WIDTH="80%" ALIGN="Left"></P>
 <H3><A NAME="Threads">4.2.5. Threads</A></H3>
 <P>OpenLDAP is designed to take advantage of threads.  OpenLDAP supports POSIX <EM>pthreads</EM>, Mach <EM>CThreads</EM>, and a number of other varieties.  <TT>configure</TT> will complain if it cannot find a suitable thread subsystem.   If this occurs, please consult the <TT>Software|Installation|Platform Hints</TT> section of the OpenLDAP FAQ <A HREF="http://www.openldap.org/faq/">http://www.openldap.org/faq/</A>.</P>
 <H3><A NAME="TCP Wrappers">4.2.6. TCP Wrappers</A></H3>
@@ -644,7 +1323,7 @@
 <PRE>
         make
 </PRE>
-<P>You should examine the output of this command carefully to make sure everything is built correctly. Note that this command builds the LDAP libraries and associated clients as well as <EM>slapd</EM>(8) and <EM>slurpd</EM>(8).</P>
+<P>You should examine the output of this command carefully to make sure everything is built correctly.  Note that this command builds the LDAP libraries and associated clients as well as <EM>slapd</EM>(8).</P>
 <H2><A NAME="Testing the Software">4.5. Testing the Software</A></H2>
 <P>Once the software has been properly configured and successfully made, you should run the test suite to verify the build.</P>
 <PRE>
@@ -662,25 +1341,18 @@
 <P></P>
 <HR>
 <H1><A NAME="Configuring slapd">5. Configuring slapd</A></H1>
-<P>Once the software has been built and installed, you are ready to configure <EM>slapd</EM>(8) for use at your site. Unlike previous OpenLDAP releases, the slapd runtime configuration in 2.3 is fully LDAP-enabled and can be managed using the standard LDAP operations with data in <TERM>LDIF</TERM>. The LDAP configuration engine allows all of slapd's configuration options to be changed on the fly, generally without requiring a server restart for the changes to take effect. The old style <EM>slapd.conf</EM>(5) file is still supported, but must be converted to the new <EM>slapd.d</EM>(5) format to allow runtime changes to be saved. While the old style configuration uses a single file, normally installed as <TT>/usr/local/etc/openldap/slapd.conf</TT>, the new style uses a slapd backend database to store the configuration. The configuration database normally resides in the <TT>/usr/local/etc/openldap/slapd.d</TT> directory.</P>
-<P>An alternate configuration directory (or file) can be specified via a command-line option to <EM>slapd</EM>(8) or <EM>slurpd</EM>(8). This chapter describes the general format of the configuration system, followed by a detailed description of commonly used config settings.</P>
+<P>Once the software has been built and installed, you are ready to configure <EM>slapd</EM>(8) for use at your site. Unlike previous OpenLDAP releases, the slapd(8) runtime configuration in 2.3 (and later) is fully LDAP-enabled and can be managed using the standard LDAP operations with data in <TERM>LDIF</TERM>. The LDAP configuration engine allows all of slapd's configuration options to be changed on the fly, generally without requiring a server restart for the changes to take effect. The old style <EM>slapd.conf</EM>(5) file is still supported, but must be converted to the new <EM>slapd-config</EM>(5) format to allow runtime changes to be saved. While the old style configuration uses a single file, normally installed as <TT>/usr/local/etc/openldap/slapd.conf</TT>, the new style uses a slapd backend database to store the configuration. The configuration database normally resides in the <TT>/usr/local/etc/openldap/slapd.d</TT> directory. When converting from the slapd.conf format to slapd.d format, any include files will also be integrated into the resulting configuration database.</P>
+<P>An alternate configuration directory (or file) can be specified via a command-line option to <EM>slapd</EM>(8). This chapter describes the general format of the configuration system, followed by a detailed description of commonly used config settings.</P>
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>some of the backends and of the distributed overlays do not support runtime configuration yet.  In those cases, the old style <EM>slapd.conf</EM>(5) file must be used.
 <HR WIDTH="80%" ALIGN="Left"></P>
-<P><HR WIDTH="80%" ALIGN="Left">
-<STRONG>Note: </STRONG>the current version of <EM>slurpd</EM> has not been updated for compatibility with this new configuration engine. If you must use slurpd for replication at your site, you will have to maintain an old-style <EM>slapd.conf</EM> file for slurpd to use.
-<HR WIDTH="80%" ALIGN="Left"></P>
 <H2><A NAME="Configuration Layout">5.1. Configuration Layout</A></H2>
 <P>The slapd configuration is stored as a special LDAP directory with a predefined schema and DIT. There are specific objectClasses used to carry global configuration options, schema definitions, backend and database definitions, and assorted other items. A sample config tree is shown in Figure 5.1.</P>
-<P><CENTER><IMG SRC="config_dit.gif" ALIGN="center"></CENTER></P>
+<P><CENTER><IMG SRC="config_dit.png" ALIGN="center"></CENTER></P>
 <P ALIGN="Center">Figure 5.1: Sample configuration tree.</P>
 <P>Other objects may be part of the configuration but were omitted from the illustration for clarity.</P>
-<P>The <EM>slapd.d</EM> configuration tree has a very specific structure. The root of the tree is named <TT>cn=config</TT> and contains global configuration settings. Additional settings are contained in separate child entries:</P>
+<P>The <EM>slapd-config</EM> configuration tree has a very specific structure. The root of the tree is named <TT>cn=config</TT> and contains global configuration settings. Additional settings are contained in separate child entries:</P>
 <UL>
-<LI>Include files<UL>
-Usually these are just pathnames left over from a converted <TT>slapd.conf</TT> file.
-<BR>
-Otherwise use of Include files is deprecated.</UL>
 <LI>Dynamically loaded modules<UL>
 These may only be used if the <TT>--enable-modules</TT> option was used to configure the software.</UL>
 <LI>Schema definitions<UL>
@@ -735,7 +1407,7 @@
 <P>A configuration directive may take arguments.  If so, the arguments are separated by white space.  If an argument contains white space, the argument should be enclosed in double quotes <TT>&quot;like this&quot;</TT>. In the descriptions that follow, arguments that should be replaced by actual text are shown in brackets <TT>&lt;&gt;</TT>.</P>
 <P>The distribution contains an example configuration file that will be installed in the <TT>/usr/local/etc/openldap</TT> directory. A number of files containing schema definitions (attribute types and object classes) are also provided in the <TT>/usr/local/etc/openldap/schema</TT> directory.</P>
 <H2><A NAME="Configuration Directives">5.2. Configuration Directives</A></H2>
-<P>This section details commonly used configuration directives.  For a complete list, see the <EM>slapd.d</EM>(5) manual page.  This section will treat the configuration directives in a top-down order, starting with the global directives in the <TT>cn=config</TT> entry. Each directive will be described along with its default value (if any) and an example of its use.</P>
+<P>This section details commonly used configuration directives.  For a complete list, see the <EM>slapd-config</EM>(5) manual page.  This section will treat the configuration directives in a top-down order, starting with the global directives in the <TT>cn=config</TT> entry. Each directive will be described along with its default value (if any) and an example of its use.</P>
 <H3><A NAME="cn=config">5.2.1. cn=config</A></H3>
 <P>Directives contained in this entry generally apply to the server as a whole. Most of them are system or connection oriented, not database related. This entry must have the <TT>olcGlobal</TT> objectClass.</P>
 <H4><A NAME="olcIdleTimeout: &lt;integer&gt;">5.2.1.1. olcIdleTimeout: &lt;integer&gt;</A></H4>
@@ -973,32 +1645,13 @@
 olcLogLevel: Stats
 olcReferral: ldap://root.openldap.org
 </PRE>
-<H3><A NAME="cn=include">5.2.2. cn=include</A></H3>
-<P>An include entry holds the pathname of one include file. Include files are part of the old style slapd.conf configuration system and must be in slapd.conf format. Include files were commonly used to load schema specifications. While they are still supported, their use is deprecated. Include entries must have the <TT>olcIncludeFile</TT> objectClass.</P>
-<H4><A NAME="olcInclude: &lt;filename&gt;">5.2.2.1. olcInclude: &lt;filename&gt;</A></H4>
-<P>This directive specifies that slapd should read additional configuration information from the given file.</P>
-<P><HR WIDTH="80%" ALIGN="Left">
-<STRONG>Note: </STRONG>You should be careful when using this directive - there is no small limit on the number of nested include directives, and no loop detection is done.
-<HR WIDTH="80%" ALIGN="Left"></P>
-<H4><A NAME="Sample Entries">5.2.2.2. Sample Entries</A></H4>
-<PRE>
-dn: cn=include{0},cn=config
-objectClass: olcIncludeFile
-cn: include{0}
-olcInclude: ./schema/core.schema
-
-dn: cn=include{1},cn=config
-objectClass: olcIncludeFile
-cn: include{1}
-olcInclude: ./schema/cosine.schema
-</PRE>
-<H3><A NAME="cn=module">5.2.3. cn=module</A></H3>
+<H3><A NAME="cn=module">5.2.2. cn=module</A></H3>
 <P>If support for dynamically loaded modules was enabled when configuring slapd, <TT>cn=module</TT> entries may be used to specify sets of modules to load. Module entries must have the <TT>olcModuleList</TT> objectClass.</P>
-<H4><A NAME="olcModuleLoad: &lt;filename&gt;">5.2.3.1. olcModuleLoad: &lt;filename&gt;</A></H4>
+<H4><A NAME="olcModuleLoad: &lt;filename&gt;">5.2.2.1. olcModuleLoad: &lt;filename&gt;</A></H4>
 <P>Specify the name of a dynamically loadable module to load. The filename may be an absolute path name or a simple filename. Non-absolute names are searched for in the directories specified by the <TT>olcModulePath</TT> directive.</P>
-<H4><A NAME="olcModulePath: &lt;pathspec&gt;">5.2.3.2. olcModulePath: &lt;pathspec&gt;</A></H4>
+<H4><A NAME="olcModulePath: &lt;pathspec&gt;">5.2.2.2. olcModulePath: &lt;pathspec&gt;</A></H4>
 <P>Specify a list of directories to search for loadable modules. Typically the path is colon-separated but this depends on the operating system.</P>
-<H4><A NAME="Sample Entries">5.2.3.3. Sample Entries</A></H4>
+<H4><A NAME="Sample Entries">5.2.2.3. Sample Entries</A></H4>
 <PRE>
 dn: cn=module{0},cn=config
 objectClass: olcModuleList
@@ -1012,13 +1665,13 @@
 olcModuleLoad: accesslog.la
 olcModuleLoad: pcache.la
 </PRE>
-<H3><A NAME="cn=schema">5.2.4. cn=schema</A></H3>
+<H3><A NAME="cn=schema">5.2.3. cn=schema</A></H3>
 <P>The cn=schema entry holds all of the schema definitions that are hard-coded in slapd. As such, the values in this entry are generated by slapd so no schema values need to be provided in the config file. The entry must still be defined though, to serve as a base for the user-defined schema to add in underneath. Schema entries must have the <TT>olcSchemaConfig</TT> objectClass.</P>
-<H4><A NAME="olcAttributeTypes: &lt;{{REF:RFC2252}} Attribute Type Description&gt;"> </A>5.2.4.1. olcAttributeTypes: &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc2252.txt">RFC2252</A> Attribute Type Description&gt;</H4>
+<H4><A NAME="olcAttributeTypes: &lt;{{REF:RFC4512}} Attribute Type Description&gt;"> </A>5.2.3.1. olcAttributeTypes: &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4512</A> Attribute Type Description&gt;</H4>
 <P>This directive defines an attribute type. Please see the <A HREF="#Schema Specification">Schema Specification</A> chapter for information regarding how to use this directive.</P>
-<H4><A NAME="olcObjectClasses: &lt;{{REF:RFC2252}} Object Class Description&gt;"> </A>5.2.4.2. olcObjectClasses: &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc2252.txt">RFC2252</A> Object Class Description&gt;</H4>
+<H4><A NAME="olcObjectClasses: &lt;{{REF:RFC4512}} Object Class Description&gt;"> </A>5.2.3.2. olcObjectClasses: &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4512</A> Object Class Description&gt;</H4>
 <P>This directive defines an object class. Please see the <A HREF="#Schema Specification">Schema Specification</A> chapter for information regarding how to use this directive.</P>
-<H4><A NAME="Sample Entries">5.2.4.3. Sample Entries</A></H4>
+<H4><A NAME="Sample Entries">5.2.3.3. Sample Entries</A></H4>
 <PRE>
 dn: cn=schema,cn=config
 objectClass: olcSchemaConfig
@@ -1036,9 +1689,9 @@
 olcObjectClasses: ( 1.1.3 NAME 'testObject'
   MAY ( testAttr $ testTwo ) AUXILIARY )
 </PRE>
-<H3><A NAME="Backend-specific Directives">5.2.5. Backend-specific Directives</A></H3>
+<H3><A NAME="Backend-specific Directives">5.2.4. Backend-specific Directives</A></H3>
 <P>Backend directives apply to all database instances of the same type and, depending on the directive, may be overridden by database directives. Backend entries must have the <TT>olcBackendConfig</TT> objectClass.</P>
-<H4><A NAME="olcBackend: &lt;type&gt;">5.2.5.1. olcBackend: &lt;type&gt;</A></H4>
+<H4><A NAME="olcBackend: &lt;type&gt;">5.2.4.1. olcBackend: &lt;type&gt;</A></H4>
 <P>This directive names a backend-specific configuration entry. <TT>&lt;type&gt;</TT> should be one of the supported backend types listed in Table 5.2.</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
 <CAPTION ALIGN=top>Table 5.2: Database Backends</CAPTION>
@@ -1092,14 +1745,6 @@
 </TR>
 <TR>
 <TD>
-<TT>ldbm</TT>
-</TD>
-<TD>
-Lightweight DBM backend
-</TD>
-</TR>
-<TR>
-<TD>
 <TT>ldif</TT>
 </TD>
 <TD>
@@ -1161,15 +1806,15 @@
         olcBackend: bdb
 </PRE>
 <P>There are no other directives defined for this entry.  Specific backend types may define additional attributes for their particular use but so far none have ever been defined.  As such, these directives usually do not appear in any actual configurations.</P>
-<H4><A NAME="Sample Entry">5.2.5.2. Sample Entry</A></H4>
+<H4><A NAME="Sample Entry">5.2.4.2. Sample Entry</A></H4>
 <PRE>
  dn: olcBackend=bdb,cn=config
  objectClass: olcBackendConfig
  olcBackend: bdb
 </PRE>
-<H3><A NAME="Database-specific Directives">5.2.6. Database-specific Directives</A></H3>
+<H3><A NAME="Database-specific Directives">5.2.5. Database-specific Directives</A></H3>
 <P>Directives in this section are supported by every type of database. Database entries must have the <TT>olcDatabaseConfig</TT> objectClass.</P>
-<H4><A NAME="olcDatabase: [{&lt;index&gt;}]&lt;type&gt;">5.2.6.1. olcDatabase: [{&lt;index&gt;}]&lt;type&gt;</A></H4>
+<H4><A NAME="olcDatabase: [{&lt;index&gt;}]&lt;type&gt;">5.2.5.1. olcDatabase: [{&lt;index&gt;}]&lt;type&gt;</A></H4>
 <P>This directive names a specific database instance. The numeric {&lt;index&gt;} may be provided to distinguish multiple databases of the same type. Usually the index can be omitted, and slapd will generate it automatically. <TT>&lt;type&gt;</TT> should be one of the supported backend types listed in Table 5.2 or the <TT>frontend</TT> type.</P>
 <P>The <TT>frontend</TT> is a special database that is used to hold database-level options that should be applied to all the other databases. Subsequent database definitions may also override some frontend settings.</P>
 <P>The <TT>config</TT> database is also special; both the <TT>config</TT> and the <TT>frontend</TT> databases are always created implicitly even if they are not explicitly configured, and they are created before any other databases.</P>
@@ -1178,42 +1823,21 @@
         olcDatabase: bdb
 </PRE>
 <P>This marks the beginning of a new <TERM>BDB</TERM> database instance.</P>
-<H4><A NAME="olcAccess: to &lt;what&gt; [ by &lt;who&gt; &lt;accesslevel&gt; &lt;control&gt; ]+">5.2.6.2. olcAccess: to &lt;what&gt; [ by &lt;who&gt; &lt;accesslevel&gt; &lt;control&gt; ]+</A></H4>
-<P>This directive grants access (specified by &lt;accesslevel&gt;) to a set of entries and/or attributes (specified by &lt;what&gt;) by one or more requesters (specified by &lt;who&gt;). See the <A HREF="#Access Control">Access Control</A> section of this chapter for a summary of basic usage.</P>
+<H4><A NAME="olcAccess: to &lt;what&gt; [ by &lt;who&gt; [&lt;accesslevel&gt;] [&lt;control&gt;] ]+">5.2.5.2. olcAccess: to &lt;what&gt; [ by &lt;who&gt; [&lt;accesslevel&gt;] [&lt;control&gt;] ]+</A></H4>
+<P>This directive grants access (specified by &lt;accesslevel&gt;) to a set of entries and/or attributes (specified by &lt;what&gt;) by one or more requestors (specified by &lt;who&gt;). See the <A HREF="#Access Control">Access Control</A> section of this chapter for a summary of basic usage.</P>
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>If no <TT>olcAccess</TT> directives are specified, the default access control policy, <TT>to * by * read</TT>, allows all users (both authenticated and anonymous) read access.
 <HR WIDTH="80%" ALIGN="Left"></P>
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>Access controls defined in the frontend are appended to all other databases' controls.
 <HR WIDTH="80%" ALIGN="Left"></P>
-<H4><A NAME="olcReadonly { TRUE | FALSE }">5.2.6.3. olcReadonly { TRUE | FALSE }</A></H4>
+<H4><A NAME="olcReadonly { TRUE | FALSE }">5.2.5.3. olcReadonly { TRUE | FALSE }</A></H4>
 <P>This directive puts the database into &quot;read-only&quot; mode. Any attempts to modify the database will return an &quot;unwilling to perform&quot; error.</P>
 <P>Default:</P>
 <PRE>
         olcReadonly: FALSE
 </PRE>
-<H4><A NAME="olcReplica">5.2.6.4. olcReplica</A></H4>
-<PRE>
-        olcReplica: uri=ldap[s]://&lt;hostname&gt;[:&lt;port&gt;] | host=&lt;hostname&gt;[:&lt;port&gt;]
-                [bindmethod={simple|sasl}]
-                [&quot;binddn=&lt;DN&gt;&quot;]
-                [saslmech=&lt;mech&gt;]
-                [authcid=&lt;identity&gt;]
-                [authzid=&lt;identity&gt;]
-                [credentials=&lt;password&gt;]
-</PRE>
-<P>This directive specifies a replication site for this database for use with slurpd. The <TT>uri=</TT> parameter specifies a scheme, a host and optionally a port where the slave slapd instance can be found. Either a domain name or IP address may be used for &lt;hostname&gt;. If &lt;port&gt; is not given, the standard LDAP port number (389 or 636) is used.</P>
-<P><TT>host</TT> is deprecated in favor of the <TT>uri</TT> parameter.</P>
-<P><TT>uri</TT> allows the replica LDAP server to be specified as an LDAP URI such as <TT>ldap://slave.example.com:389</TT> or <TT>ldaps://slave.example.com:636</TT>.</P>
-<P>The <TT>binddn=</TT> parameter gives the DN to bind as for updates to the slave slapd. It should be a DN which has read/write access to the slave slapd's database.  It must also match the <TT>updatedn</TT> directive in the slave slapd's config file.  Generally, this DN <EM>should not</EM> be the same as the <TT>rootdn</TT> of the master database.  Since DNs are likely to contain embedded spaces, the entire <TT>&quot;binddn=&lt;DN&gt;&quot;</TT> string should be enclosed in double quotes.</P>
-<P>The <TT>bindmethod</TT> is <TT>simple</TT> or <TT>sasl</TT>, depending on whether simple password-based authentication or <TERM>SASL</TERM> authentication is to be used when connecting to the slave slapd.</P>
-<P>Simple authentication should not be used unless adequate data integrity and confidentiality protections are in place (e.g. TLS or IPSEC).  Simple authentication requires specification of <TT>binddn</TT> and <TT>credentials</TT> parameters.</P>
-<P>SASL authentication is generally recommended.  SASL authentication requires specification of a mechanism using the <TT>saslmech</TT> parameter. Depending on the mechanism, an authentication identity and/or credentials can be specified using <TT>authcid</TT> and <TT>credentials</TT> respectively.  The <TT>authzid</TT> parameter may be used to specify an authorization identity.</P>
-<P>See the chapter entitled <A HREF="#Replication with slurpd">Replication with slurpd</A> for more information on how to use this directive.</P>
-<H4><A NAME="olcReplogfile: &lt;filename&gt;">5.2.6.5. olcReplogfile: &lt;filename&gt;</A></H4>
-<P>This directive specifies the name of the replication log file to which slapd will log changes. The replication log is typically written by slapd and read by slurpd. Normally, this directive is only used if slurpd is being used to replicate the database. However, you can also use it to generate a transaction log, if slurpd is not running. In this case, you will need to periodically truncate the file, since it will grow indefinitely otherwise.</P>
-<P>See the chapter entitled <A HREF="#Replication with slurpd">Replication with slurpd</A> for more information on how to use this directive.</P>
-<H4><A NAME="olcRootDN: &lt;DN&gt;">5.2.6.6. olcRootDN: &lt;DN&gt;</A></H4>
+<H4><A NAME="olcRootDN: &lt;DN&gt;">5.2.5.4. olcRootDN: &lt;DN&gt;</A></H4>
 <P>This directive specifies the DN that is not subject to access control or administrative limit restrictions for operations on this database.  The DN need not refer to an entry in this database or even in the directory. The DN may refer to a SASL identity.</P>
 <P>Entry-based Example:</P>
 <PRE>
@@ -1224,25 +1848,25 @@
         olcRootDN: &quot;uid=root,cn=example.com,cn=digest-md5,cn=auth&quot;
 </PRE>
 <P>See the <A HREF="#SASL Authentication">SASL Authentication</A> section for information on SASL authentication identities.</P>
-<H4><A NAME="olcRootPW: &lt;password&gt;">5.2.6.7. olcRootPW: &lt;password&gt;</A></H4>
+<H4><A NAME="olcRootPW: &lt;password&gt;">5.2.5.5. olcRootPW: &lt;password&gt;</A></H4>
 <P>This directive can be used to specify a password for the DN for the rootdn (when the rootdn is set to a DN within the database).</P>
 <P>Example:</P>
 <PRE>
         olcRootPW: secret
 </PRE>
-<P>It is also permissible to provide a hash of the password in RFC 2307 form.  <EM>slappasswd</EM>(8) may be used to generate the password hash.</P>
+<P>It is also permissible to provide a hash of the password in <A HREF="http://www.rfc-editor.org/rfc/rfc2307.txt">RFC2307</A> form.  <EM>slappasswd</EM>(8) may be used to generate the password hash.</P>
 <P>Example:</P>
 <PRE>
         olcRootPW: {SSHA}ZKKuqbEKJfKSXhUbHG3fG8MDn9j1v4QN
 </PRE>
 <P>The hash was generated using the command <TT>slappasswd -s secret</TT>.</P>
-<H4><A NAME="olcSizeLimit: &lt;integer&gt;">5.2.6.8. olcSizeLimit: &lt;integer&gt;</A></H4>
+<H4><A NAME="olcSizeLimit: &lt;integer&gt;">5.2.5.6. olcSizeLimit: &lt;integer&gt;</A></H4>
 <P>This directive specifies the maximum number of entries to return from a search operation.</P>
 <P>Default:</P>
 <PRE>
         olcSizeLimit: 500
 </PRE>
-<H4><A NAME="olcSuffix: &lt;dn suffix&gt;">5.2.6.9. olcSuffix: &lt;dn suffix&gt;</A></H4>
+<H4><A NAME="olcSuffix: &lt;dn suffix&gt;">5.2.5.7. olcSuffix: &lt;dn suffix&gt;</A></H4>
 <P>This directive specifies the DN suffix of queries that will be passed to this backend database. Multiple suffix lines can be given, and usually at least one is required for each database definition. (Some backend types, such as <TT>frontend</TT> and <TT>monitor</TT> use a hard-coded suffix which may not be overridden in the configuration.)</P>
 <P>Example:</P>
 <PRE>
@@ -1252,11 +1876,10 @@
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>When the backend to pass a query to is selected, slapd looks at the suffix value(s) in each database definition in the order in which they were configured. Thus, if one database suffix is a prefix of another, it must appear after it in the configuration.
 <HR WIDTH="80%" ALIGN="Left"></P>
-<H4><A NAME="olcSyncrepl">5.2.6.10. olcSyncrepl</A></H4>
+<H4><A NAME="olcSyncrepl">5.2.5.8. olcSyncrepl</A></H4>
 <PRE>
         olcSyncrepl: rid=&lt;replica ID&gt;
                 provider=ldap[s]://&lt;hostname&gt;[:port]
-                [starttls=yes|critical]
                 [type=refreshOnly|refreshAndPersist]
                 [interval=dd:hh:mm:ss]
                 [retry=[&lt;retry interval&gt; &lt;# of retries&gt;]+]
@@ -1276,46 +1899,47 @@
                 [credentials=&lt;passwd&gt;]
                 [realm=&lt;realm&gt;]
                 [secprops=&lt;properties&gt;]
+                [starttls=yes|critical]
+                [tls_cert=&lt;file&gt;]
+                [tls_key=&lt;file&gt;]
+                [tls_cacert=&lt;file&gt;]
+                [tls_cacertdir=&lt;path&gt;]
+                [tls_reqcert=never|allow|try|demand]
+                [tls_ciphersuite=&lt;ciphers&gt;]
+                [tls_crlcheck=none|peer|all]
+                [logbase=&lt;base DN&gt;]
+                [logfilter=&lt;filter str&gt;]
+                [syncdata=default|accesslog|changelog]
 </PRE>
-<P>This directive specifies the current database as a replica of the master content by establishing the current <EM>slapd</EM>(8) as a replication consumer site running a syncrepl replication engine. The master database is located at the replication provider site specified by the <TT>provider</TT> parameter. The replica database is kept up-to-date with the master content using the LDAP Content Synchronization protocol. See <TT>draft-zeilenga-ldup-sync-xx.txt</TT> (<EM>a work in progress</EM>) for more information on the protocol.</P>
+<P>This directive specifies the current database as a replica of the master content by establishing the current <EM>slapd</EM>(8) as a replication consumer site running a syncrepl replication engine. The master database is located at the replication provider site specified by the <TT>provider</TT> parameter. The replica database is kept up-to-date with the master content using the LDAP Content Synchronization protocol. See <A HREF="http://www.rfc-editor.org/rfc/rfc4533.txt">RFC4533</A> for more information on the protocol.</P>
 <P>The <TT>rid</TT> parameter is used for identification of the current <TT>syncrepl</TT> directive within the replication consumer server, where <TT>&lt;replica ID&gt;</TT> uniquely identifies the syncrepl specification described by the current <TT>syncrepl</TT> directive. <TT>&lt;replica ID&gt;</TT> is non-negative and is no more than three decimal digits in length.</P>
 <P>The <TT>provider</TT> parameter specifies the replication provider site containing the master content as an LDAP URI. The <TT>provider</TT> parameter specifies a scheme, a host and optionally a port where the provider slapd instance can be found. Either a domain name or IP address may be used for &lt;hostname&gt;. Examples are <TT>ldap://provider.example.com:389</TT> or <TT>ldaps://192.168.1.1:636</TT>. If &lt;port&gt; is not given, the standard LDAP port number (389 or 636) is used. Note that the syncrepl uses a consumer-initiated protocol, and hence its specification is located at the consumer site, whereas the <TT>replica</TT> specification is located at the provider site. <TT>syncrepl</TT> and <TT>replica</TT> directives define two independent replication mechanisms. They do not represent the replication peers of each other.</P>
-<P>The <TT>starttls</TT> parameter specifies use of the StartTLS extended operation to establish a TLS session before Binding to the provider. If the StartTLS request fails and the <TT>critical</TT> argument was used, the session will be aborted. Otherwise the syncrepl session continues without TLS.</P>
 <P>The content of the syncrepl replica is defined using a search specification as its result set. The consumer slapd will send search requests to the provider slapd according to the search specification. The search specification includes <TT>searchbase</TT>, <TT>scope</TT>, <TT>filter</TT>, <TT>attrs</TT>, <TT>attrsonly</TT>, <TT>sizelimit</TT>, and <TT>timelimit</TT> parameters as in the normal search specification. The <TT>searchbase</TT> parameter has no default value and must always be specified. The <TT>scope</TT> defaults to <TT>sub</TT>, the <TT>filter</TT> defaults to <TT>(objectclass=*)</TT>, <TT>attrs</TT> defaults to <TT>&quot;*,+&quot;</TT> to replicate all user and operational attributes, and <TT>attrsonly</TT> is unset by default. Both <TT>sizelimit</TT> and <TT>timelimit</TT> default to &quot;unlimited&quot;, and only positive integers or &quot;unlimited&quot; may be specified.</P>
-<P>The LDAP Content Synchronization protocol has two operation types: <TT>refreshOnly</TT> and <TT>refreshAndPersist</TT>. The operation type is specified by the <TT>type</TT> parameter. In the <TT>refreshOnly</TT> operation, the next synchronization search operation is periodically rescheduled at an interval time after each synchronization operation finishes. The interval is specified by the <TT>interval</TT> parameter. It is set to one day by default. In the <TT>refreshAndPersist</TT> operation, a synchronization search remains persistent in the provider slapd. Further updates to the master replica will generate <TT>searchResultEntry</TT> to the consumer slapd as the search responses to the persistent synchronization search.</P>
+<P>The <TERM>LDAP Content Sychronization</TERM> protocol has two operation types: <TT>refreshOnly</TT> and <TT>refreshAndPersist</TT>. The operation type is specified by the <TT>type</TT> parameter. In the <TT>refreshOnly</TT> operation, the next synchronization search operation is periodically rescheduled at an interval time after each synchronization operation finishes. The interval is specified by the <TT>interval</TT> parameter. It is set to one day by default. In the <TT>refreshAndPersist</TT> operation, a synchronization search remains persistent in the provider <EM>slapd</EM> instance. Further updates to the master replica will generate <TT>searchResultEntry</TT> to the consumer slapd as the search responses to the persistent synchronization search.</P>
 <P>If an error occurs during replication, the consumer will attempt to reconnect according to the retry parameter which is a list of the &lt;retry interval&gt; and &lt;# of retries&gt; pairs. For example, retry=&quot;60 10 300 3&quot; lets the consumer retry every 60 seconds for the first 10 times and then retry every 300 seconds for the next three times before stop retrying. + in &lt;#  of retries&gt; means indefinite number of retries until success.</P>
 <P>The schema checking can be enforced at the LDAP Sync consumer site by turning on the <TT>schemachecking</TT> parameter. If it is turned on, every replicated entry will be checked for its schema as the entry is stored into the replica content. Every entry in the replica should contain those attributes required by the schema definition. If it is turned off, entries will be stored without checking schema conformance. The default is off.</P>
 <P>The <TT>binddn</TT> parameter gives the DN to bind as for the syncrepl searches to the provider slapd. It should be a DN which has read access to the replication content in the master database.</P>
-<P>The <TT>bindmethod</TT> is <TT>simple</TT> or <TT>sasl</TT>, depending on whether simple password-based authentication or <TERM>SASL</TERM> authentication is to be used when connecting to the provider slapd.</P>
-<P>Simple authentication should not be used unless adequate data integrity and confidentiality protections are in place (e.g. TLS or IPSEC). Simple authentication requires specification of <TT>binddn</TT> and <TT>credentials</TT> parameters.</P>
+<P>The <TT>bindmethod</TT> is <TT>simple</TT> or <TT>sasl</TT>, depending on whether simple password-based authentication or <TERM>SASL</TERM> authentication is to be used when connecting to the provider <EM>slapd</EM> instance.</P>
+<P>Simple authentication should not be used unless adequate data integrity and confidentiality protections are in place (e.g. TLS or IPsec). Simple authentication requires specification of <TT>binddn</TT> and <TT>credentials</TT> parameters.</P>
 <P>SASL authentication is generally recommended.  SASL authentication requires specification of a mechanism using the <TT>saslmech</TT> parameter. Depending on the mechanism, an authentication identity and/or credentials can be specified using <TT>authcid</TT> and <TT>credentials</TT>, respectively.  The <TT>authzid</TT> parameter may be used to specify an authorization identity.</P>
 <P>The <TT>realm</TT> parameter specifies a realm which a certain mechanisms authenticate the identity within. The <TT>secprops</TT> parameter specifies Cyrus SASL security properties.</P>
-<P>The syncrepl replication mechanism is supported by the three native backends: back-bdb, back-hdb, and back-ldbm.</P>
-<P>See the <A HREF="#LDAP Sync Replication">LDAP Sync Replication</A> chapter of the admin guide for more information on how to use this directive.</P>
-<H4><A NAME="olcTimeLimit: &lt;integer&gt;">5.2.6.11. olcTimeLimit: &lt;integer&gt;</A></H4>
+<P>The <TT>starttls</TT> parameter specifies use of the StartTLS extended operation to establish a TLS session before authenticating to the provider. If the <TT>critical</TT> argument is supplied, the session will be aborted if the StartTLS request fails.  Otherwise the syncrepl session continues without TLS.  Note that the main slapd TLS settings are not used by the syncrepl engine; by default the TLS parameters from a <EM>ldap.conf</EM>(5) configuration file will be used.  TLS settings may be specified here, in which case any <EM>ldap.conf</EM>(5) settings will be completely ignored.</P>
+<P>Rather than replicating whole entries, the consumer can query logs of data modifications.  This mode of operation is referred to as <EM>delta syncrepl</EM>.  In addition to the above parameters, the <TT>logbase</TT> and <TT>logfilter</TT> parameters must be set appropriately for the log that will be used. The <TT>syncdata</TT> parameter must be set to either <TT>&quot;accesslog&quot;</TT> if the log conforms to the <EM>slapo-accesslog</EM>(5) log format, or <TT>&quot;changelog&quot;</TT> if the log conforms to the obsolete <EM>changelog</EM> format. If the <TT>syncdata</TT> parameter is omitted or set to <TT>&quot;default&quot;</TT> then the log parameters are ignored.</P>
+<P>The <EM>syncrepl</EM> replication mechanism is supported by the <EM>bdb</EM> and <EM>hdb</EM> backends.</P>
+<P>See the <A HREF="#LDAP Sync Replication">LDAP Sync Replication</A> chapter of this guide for more information on how to use this directive.</P>
+<H4><A NAME="olcTimeLimit: &lt;integer&gt;">5.2.5.9. olcTimeLimit: &lt;integer&gt;</A></H4>
 <P>This directive specifies the maximum number of seconds (in real time) slapd will spend answering a search request. If a request is not finished in this time, a result indicating an exceeded timelimit will be returned.</P>
 <P>Default:</P>
 <PRE>
         olcTimeLimit: 3600
 </PRE>
-<H4><A NAME="olcUpdateDN: &lt;DN&gt;">5.2.6.12. olcUpdateDN: &lt;DN&gt;</A></H4>
-<P>This directive is only applicable in a slave slapd. It specifies the DN allowed to make changes to the replica.  This may be the DN <EM>slurpd</EM>(8) binds as when making changes to the replica or the DN associated with a SASL identity.</P>
-<P>Entry-based Example:</P>
-<PRE>
-        olcUpdateDN: &quot;cn=Update Daemon,dc=example,dc=com&quot;
-</PRE>
-<P>SASL-based Example:</P>
-<PRE>
-        olcUpdateDN: &quot;uid=slurpd,cn=example.com,cn=digest-md5,cn=auth&quot;
-</PRE>
-<P>See the <A HREF="#Replication with slurpd">Replication with slurpd</A> chapter for more information on how to use this directive.</P>
-<H4><A NAME="olcUpdateref: &lt;URL&gt;">5.2.6.13. olcUpdateref: &lt;URL&gt;</A></H4>
+<H4><A NAME="olcUpdateref: &lt;URL&gt;">5.2.5.10. olcUpdateref: &lt;URL&gt;</A></H4>
 <P>This directive is only applicable in a slave slapd. It specifies the URL to return to clients which submit update requests upon the replica. If specified multiple times, each <TERM>URL</TERM> is provided.</P>
 <P>Example:</P>
 <PRE>
         olcUpdateref:   ldap://master.example.net
 </PRE>
-<H4><A NAME="Sample Entries">5.2.6.14. Sample Entries</A></H4>
+<H4><A NAME="Sample Entries">5.2.5.11. Sample Entries</A></H4>
 <PRE>
 dn: olcDatabase=frontend,cn=config
 objectClass: olcDatabaseConfig
@@ -1328,28 +1952,29 @@
 olcDatabase: config
 olcRootDN: cn=Manager,dc=example,dc=com
 </PRE>
-<H3><A NAME="BDB and HDB Database Directives">5.2.7. BDB and HDB Database Directives</A></H3>
+<H3><A NAME="BDB and HDB Database Directives">5.2.6. BDB and HDB Database Directives</A></H3>
 <P>Directives in this category apply to both the <TERM>BDB</TERM> and the <TERM>HDB</TERM> database. They are used in an olcDatabase entry in addition to the generic database directives defined above.  For a complete reference of BDB/HDB configuration directives, see <EM>slapd-bdb</EM>(5). In addition to the <TT>olcDatabaseConfig</TT> objectClass, BDB and HDB database entries must have the <TT>olcBdbConfig</TT> and <TT>olcHdbConfig</TT> objectClass, respectively.</P>
-<H4><A NAME="olcDbDirectory: &lt;directory&gt;">5.2.7.1. olcDbDirectory: &lt;directory&gt;</A></H4>
+<H4><A NAME="olcDbDirectory: &lt;directory&gt;">5.2.6.1. olcDbDirectory: &lt;directory&gt;</A></H4>
 <P>This directive specifies the directory where the BDB files containing the database and associated indices live.</P>
 <P>Default:</P>
 <PRE>
         olcDbDirectory: /usr/local/var/openldap-data
 </PRE>
-<H4><A NAME="olcDbCachesize: &lt;integer&gt;">5.2.7.2. olcDbCachesize: &lt;integer&gt;</A></H4>
+<H4><A NAME="olcDbCachesize: &lt;integer&gt;">5.2.6.2. olcDbCachesize: &lt;integer&gt;</A></H4>
 <P>This directive specifies the size in entries of the in-memory cache maintained by the BDB backend database instance.</P>
 <P>Default:</P>
 <PRE>
         olcDbCachesize: 1000
 </PRE>
-<H4><A NAME="olcDbCheckpoint: &lt;kbyte&gt; &lt;min&gt;">5.2.7.3. olcDbCheckpoint: &lt;kbyte&gt; &lt;min&gt;</A></H4>
-<P>This directive specifies how often to checkpoint the BDB transaction log. A checkpoint operation flushes the database buffers to disk and writes a checkpoint record in the log. The checkpoint will occur if either &lt;kbyte&gt; data has been written or &lt;min&gt; minutes have passed since the last checkpont. Both arguments default to zero, in which case they are ignored. When the &lt;min&gt; argument is non-zero, an internal task will run every &lt;min&gt; minutes to perform the checkpoint. See the Berkeley DB reference guide for more details.</P>
+<H4><A NAME="olcDbCheckpoint: &lt;kbyte&gt; &lt;min&gt;">5.2.6.3. olcDbCheckpoint: &lt;kbyte&gt; &lt;min&gt;</A></H4>
+<P>This directive specifies how often to checkpoint the BDB transaction log. A checkpoint operation flushes the database buffers to disk and writes a checkpoint record in the log. The checkpoint will occur if either &lt;kbyte&gt; data has been written or &lt;min&gt; minutes have passed since the last checkpoint. Both arguments default to zero, in which case they are ignored. When the &lt;min&gt; argument is non-zero, an internal task will run every &lt;min&gt; minutes to perform the checkpoint. See the Berkeley DB reference guide for more details.</P>
 <P>Example:</P>
 <PRE>
         olcDbCheckpoint: 1024 10
 </PRE>
-<H4><A NAME="olcDbConfig: &lt;DB_CONFIG setting&gt;">5.2.7.4. olcDbConfig: &lt;DB_CONFIG setting&gt;</A></H4>
-<P>This attribute specifies a configuration directive to be placed in the <TT>DB_CONFIG</TT> file of the database directory. At server startup time, if no such file exists yet, the <TT>DB_CONFIG</TT> file will be created and the settings in this attribute will be written to it. If the file exists, its contents will be read and displayed in this attribute. The attribute is multi-valued, to accomodate multiple configuration directives. No default is provided, but it is essential to use proper settings here to get the best server performance.</P>
+<H4><A NAME="olcDbConfig: &lt;DB_CONFIG setting&gt;">5.2.6.4. olcDbConfig: &lt;DB_CONFIG setting&gt;</A></H4>
+<P>This attribute specifies a configuration directive to be placed in the <TT>DB_CONFIG</TT> file of the database directory. At server startup time, if no such file exists yet, the <TT>DB_CONFIG</TT> file will be created and the settings in this attribute will be written to it. If the file exists, its contents will be read and displayed in this attribute. The attribute is multi-valued, to accommodate multiple configuration directives. No default is provided, but it is essential to use proper settings here to get the best server performance.</P>
+<P>Any changes made to this attribute will be written to the <TT>DB_CONFIG</TT> file and will cause the database environment to be reset so the changes can take immediate effect. If the environment cache is large and has not been recently checkpointed, this reset operation may take a long time. It may be advisable to manually perform a single checkpoint using the Berkeley DB <EM>db_checkpoint</EM> utility before using LDAP Modify to change this attribute.</P>
 <P>Example:</P>
 <PRE>
         olcDbConfig: set_cachesize 0 10485760 0
@@ -1357,21 +1982,21 @@
         olcDbConfig: set_lg_dir /var/tmp/bdb-log
         olcDbConfig: set_flags DB_LOG_AUTOREMOVE
 </PRE>
-<P>In this example, the BDB cache is set to 10MB, the BDB transaction log buffer size is set to 2MB, and the transaction log files are to be stored in the /var/tmp/bdb-log directory. Also a flag is set to tell BDB to delete transaction log files as soon as their contents have been checkpointed and they are no longer needed. Without this setting the transaction log files will continue to accumulate until some other cleanup procedure removes them. See the SleepyCat documentation for the <TT>db_archive</TT> command for details.</P>
-<P>Ideally the BDB cache must be at least as large as the working set of the database, the log buffer size should be large enough to accomodate most transactions without overflowing, and the log directory must be on a separate physical disk from the main database files. And both the database directory and the log directory should be separate from disks used for regular system activities such as the root, boot, or swap filesystems. See the FAQ-o-Matic and the SleepyCat documentation for more details.</P>
-<H4><A NAME="olcDbNosync: { TRUE | FALSE }">5.2.7.5. olcDbNosync: { TRUE | FALSE }</A></H4>
+<P>In this example, the BDB cache is set to 10MB, the BDB transaction log buffer size is set to 2MB, and the transaction log files are to be stored in the /var/tmp/bdb-log directory. Also a flag is set to tell BDB to delete transaction log files as soon as their contents have been checkpointed and they are no longer needed. Without this setting the transaction log files will continue to accumulate until some other cleanup procedure removes them. See the Berkeley DB documentation for the <TT>db_archive</TT> command for details.</P>
+<P>Ideally the BDB cache must be at least as large as the working set of the database, the log buffer size should be large enough to accommodate most transactions without overflowing, and the log directory must be on a separate physical disk from the main database files. And both the database directory and the log directory should be separate from disks used for regular system activities such as the root, boot, or swap filesystems. See the FAQ-o-Matic and the Berkeley DB documentation for more details.</P>
+<H4><A NAME="olcDbNosync: { TRUE | FALSE }">5.2.6.5. olcDbNosync: { TRUE | FALSE }</A></H4>
 <P>This option causes on-disk database contents to not be immediately synchronized with in memory changes upon change.  Setting this option to <TT>TRUE</TT> may improve performance at the expense of data integrity. This directive has the same effect as using</P>
 <PRE>
         olcDbConfig: set_flags DB_TXN_NOSYNC
 </PRE>
-<H4><A NAME="olcDbIDLcacheSize: &lt;integer&gt;">5.2.7.6. olcDbIDLcacheSize: &lt;integer&gt;</A></H4>
+<H4><A NAME="olcDbIDLcacheSize: &lt;integer&gt;">5.2.6.6. olcDbIDLcacheSize: &lt;integer&gt;</A></H4>
 <P>Specify the size of the in-memory index cache, in index slots. The default is zero. A larger value will speed up frequent searches of indexed entries. The optimal size will depend on the data and search characteristics of the database, but using a number three times the entry cache size is a good starting point.</P>
 <P>Example:</P>
 <PRE>
         olcDbIDLcacheSize: 3000
 </PRE>
-<H4><A NAME="olcDbIndex: {&lt;attrlist&gt; | default} [pres,eq,approx,sub,none]">5.2.7.7. olcDbIndex: {&lt;attrlist&gt; | default} [pres,eq,approx,sub,none]</A></H4>
-<P>This directive specifies the indices to maintain for the given attribute. If only an <TT>&lt;attrlist&gt;</TT> is given, the default indices are maintained.</P>
+<H4><A NAME="olcDbIndex: {&lt;attrlist&gt; | default} [pres,eq,approx,sub,none]">5.2.6.7. olcDbIndex: {&lt;attrlist&gt; | default} [pres,eq,approx,sub,none]</A></H4>
+<P>This directive specifies the indices to maintain for the given attribute. If only an <TT>&lt;attrlist&gt;</TT> is given, the default indices are maintained. The index keywords correspond to the common types of matches that may be used in an LDAP search filter.</P>
 <P>Example:</P>
 <PRE>
         olcDbIndex: default pres,eq
@@ -1380,32 +2005,36 @@
         olcDbIndex: objectClass eq
 </PRE>
 <P>The first line sets the default set of indices to maintain to present and equality.  The second line causes the default (pres,eq) set of indices to be maintained for the <TT>uid</TT> attribute type. The third line causes present, equality, and substring indices to be maintained for <TT>cn</TT> and <TT>sn</TT> attribute types.  The fourth line causes an equality index for the <TT>objectClass</TT> attribute type.</P>
+<P>There is no index keyword for inequality matches. Generally these matches do not use an index. However, some attributes do support indexing for inequality matches, based on the equality index.</P>
+<P>A substring index can be more explicitly specified as <TT>subinitial</TT>, <TT>subany</TT>, or <TT>subfinal</TT>, corresponding to the three possible components of a substring match filter. A subinitial index only indexes substrings that appear at the beginning of an attribute value. A subfinal index only indexes substrings that appear at the end of an attribute value, while subany indexes substrings that occur anywhere in a value.</P>
+<P>Note that by default, setting an index for an attribute also affects every subtype of that attribute. E.g., setting an equality index on the <TT>name</TT> attribute causes <TT>cn</TT>, <TT>sn</TT>, and every other attribute that inherits from <TT>name</TT> to be indexed.</P>
 <P>By default, no indices are maintained.  It is generally advised that minimally an equality index upon objectClass be maintained.</P>
 <PRE>
         olcDbindex: objectClass eq
 </PRE>
+<P>Additional indices should be configured corresponding to the most common searches that are used on the database. Presence indexing should not be configured for an attribute unless the attribute occurs very rarely in the database, and presence searches on the attribute occur very frequently during normal use of the directory. Most applications don't use presence searches, so usually presence indexing is not very useful.</P>
 <P>If this setting is changed while slapd is running, an internal task will be run to generate the changed index data. All server operations can continue as normal while the indexer does its work.  If slapd is stopped before the index task completes, indexing will have to be manually completed using the slapindex tool.</P>
-<H4><A NAME="olcDbLinearIndex: { TRUE | FALSE }">5.2.7.8. olcDbLinearIndex: { TRUE | FALSE }</A></H4>
+<H4><A NAME="olcDbLinearIndex: { TRUE | FALSE }">5.2.6.8. olcDbLinearIndex: { TRUE | FALSE }</A></H4>
 <P>If this setting is <TT>TRUE</TT> slapindex will index one attribute at a time. The default settings is <TT>FALSE</TT> in which case all indexed attributes of an entry are processed at the same time. When enabled, each indexed attribute is processed individually, using multiple passes through the entire database. This option improves slapindex performance when the database size exceeds the BDB cache size. When the BDB cache is large enough, this option is not needed and will decrease performance. Also by default, slapadd performs full indexing and so a separate slapindex run is not needed. With this option, slapadd does no indexing and slapindex must be used.</P>
-<H4><A NAME="olcDbMode: &lt;integer&gt;">5.2.7.9. olcDbMode: &lt;integer&gt;</A></H4>
+<H4><A NAME="olcDbMode: &lt;integer&gt;">5.2.6.9. olcDbMode: &lt;integer&gt;</A></H4>
 <P>This directive specifies the file protection mode that newly created database index files should have.</P>
 <P>Default:</P>
 <PRE>
         olcDbMode: 0600
 </PRE>
-<H4><A NAME="olcDbSearchStack: &lt;integer&gt;">5.2.7.10. olcDbSearchStack: &lt;integer&gt;</A></H4>
-<P>Specify the depth of the stack used for search filter evaluation. Search filters are evaluated on a stack to accomodate nested <TT>AND</TT> / <TT>OR</TT> clauses. An individual stack is allocated for each server thread. The depth of the stack determines how complex a filter can be evaluated without requiring any additional memory allocation. Filters that are nested deeper than the search stack depth will cause a separate stack to be allocated for that particular search operation. These separate allocations can have a major negative impact on server performance, but specifying too much stack will also consume a great deal of memory. Each search uses 512K bytes per level on a 32-bit machine, or 1024K bytes per level on a 64-bit machine. The default stack depth is 16, thus 8MB or 16MB per thread is used on 32 and 64 bit machines, respectively. Also the 512KB size of a single stack slot is set by a compile-time constant which may be changed if needed; the code must be recompiled for the change to take effect.</P>
+<H4><A NAME="olcDbSearchStack: &lt;integer&gt;">5.2.6.10. olcDbSearchStack: &lt;integer&gt;</A></H4>
+<P>Specify the depth of the stack used for search filter evaluation. Search filters are evaluated on a stack to accommodate nested <TT>AND</TT> / <TT>OR</TT> clauses. An individual stack is allocated for each server thread. The depth of the stack determines how complex a filter can be evaluated without requiring any additional memory allocation. Filters that are nested deeper than the search stack depth will cause a separate stack to be allocated for that particular search operation. These separate allocations can have a major negative impact on server performance, but specifying too much stack will also consume a great deal of memory. Each search uses 512K bytes per level on a 32-bit machine, or 1024K bytes per level on a 64-bit machine. The default stack depth is 16, thus 8MB or 16MB per thread is used on 32 and 64 bit machines, respectively. Also the 512KB size of a single stack slot is set by a compile-time constant which may be changed if needed; the code must be recompiled for the change to take effect.</P>
 <P>Default:</P>
 <PRE>
         olcDbSearchStack: 16
 </PRE>
-<H4><A NAME="olcDbShmKey: &lt;integer&gt;">5.2.7.11. olcDbShmKey: &lt;integer&gt;</A></H4>
+<H4><A NAME="olcDbShmKey: &lt;integer&gt;">5.2.6.11. olcDbShmKey: &lt;integer&gt;</A></H4>
 <P>Specify a key for a shared memory BDB environment. By default the BDB environment uses memory mapped files. If a non-zero value is specified, it will be used as the key to identify a shared memory region that will house the environment.</P>
 <P>Example:</P>
 <PRE>
         olcDbShmKey: 42
 </PRE>
-<H4><A NAME="Sample Entry">5.2.7.12. Sample Entry</A></H4>
+<H4><A NAME="Sample Entry">5.2.6.12. Sample Entry</A></H4>
 <PRE>
 dn: olcDatabase=hdb,cn=config
 objectClass: olcDatabaseConfig
@@ -1427,7 +2056,7 @@
 <PRE>
         olcAccess: &lt;access directive&gt;
         &lt;access directive&gt; ::= to &lt;what&gt;
-                [by &lt;who&gt; &lt;access&gt; &lt;control&gt;]+
+                [by &lt;who&gt; [&lt;access&gt;] [&lt;control&gt;] ]+
         &lt;what&gt; ::= * |
                 [dn[.&lt;basic-style&gt;]=&lt;regex&gt; | dn.&lt;scope-style&gt;=&lt;DN&gt;]
                 [filter=&lt;ldapfilter&gt;] [attrs=&lt;attrlist&gt;]
@@ -1446,8 +2075,8 @@
                 [set=&lt;setspec&gt;]
                 [aci=&lt;attrname&gt;]
         &lt;access&gt; ::= [self]{&lt;level&gt;|&lt;priv&gt;}
-        &lt;level&gt; ::= none | auth | compare | search | read | write
-        &lt;priv&gt; ::= {=|+|-}{w|r|s|c|x|0}+
+        &lt;level&gt; ::= none | disclose | auth | compare | search | read | write | manage
+        &lt;priv&gt; ::= {=|+|-}{m|w|r|s|c|x|d|0}+
         &lt;control&gt; ::= [stop | continue | break]
 </PRE>
 <P>where the &lt;what&gt; part selects the entries and/or attributes to which the access applies, the <TT>&lt;who&gt;</TT> part specifies which entities are granted access, and the <TT>&lt;access&gt;</TT> part specifies the access granted. Multiple <TT>&lt;who&gt; &lt;access&gt; &lt;control&gt;</TT> triplets are supported, allowing many entities to be granted different access to the same set of entries and attributes. Not all of these access control options are described here; for more details see the <EM>slapd.access</EM>(5) man page.</P>
@@ -1458,7 +2087,7 @@
         to dn[.&lt;basic-style&gt;]=&lt;regex&gt;
         to dn.&lt;scope-style&gt;=&lt;DN&gt;
 </PRE>
-<P>The first form is used to select all entries.  The second form may be used to select entries by matching a regular expression against the target entry's <EM>normalized DN</EM>.   (The second form is not discussed further in this document.)  The third form is used to select entries which are within the requested scope of DN.  The &lt;DN&gt; is a string representation of the Distinguished Name, as described in <A HREF="http://www.rfc-editor.org/rfc/rfc2253.txt">RFC2253</A>.</P>
+<P>The first form is used to select all entries.  The second form may be used to select entries by matching a regular expression against the target entry's <EM>normalized DN</EM>.   (The second form is not discussed further in this document.)  The third form is used to select entries which are within the requested scope of DN.  The &lt;DN&gt; is a string representation of the Distinguished Name, as described in <A HREF="http://www.rfc-editor.org/rfc/rfc4514.txt">RFC4514</A>.</P>
 <P>The scope can be either <TT>base</TT>, <TT>one</TT>, <TT>subtree</TT>, or <TT>children</TT>.  Where <TT>base</TT> matches only the entry with provided DN, <TT>one</TT> matches the entries whose parent is the provided DN, <TT>subtree</TT> matches all entries in the subtree whose root is the provided DN, and <TT>children</TT> matches all entries under the DN (but not the entry named by the DN).</P>
 <P>For example, if the directory contained entries named:</P>
 <PRE>
@@ -1482,7 +2111,7 @@
 <PRE>
         to filter=&lt;ldap filter&gt;
 </PRE>
-<P>where &lt;ldap filter&gt; is a string representation of an LDAP search filter, as described in <A HREF="http://www.rfc-editor.org/rfc/rfc2254.txt">RFC2254</A>.  For example:</P>
+<P>where &lt;ldap filter&gt; is a string representation of an LDAP search filter, as described in <A HREF="http://www.rfc-editor.org/rfc/rfc4515.txt">RFC4515</A>.  For example:</P>
 <PRE>
         to filter=(objectClass=person)
 </PRE>
@@ -1568,7 +2197,7 @@
         dnattr=&lt;dn-valued attribute name&gt;
 </PRE>
 <P>The dnattr specification is used to give access to an entry whose DN is listed in an attribute of the entry (e.g., give access to a group entry to whoever is listed as the owner of the group entry).</P>
-<P>Some factors may not be appropriate in all environments (or any). For example, the domain factor relies on IP to domain name lookups. As these can easily spoofed, the domain factor should not be avoided.</P>
+<P>Some factors may not be appropriate in all environments (or any). For example, the domain factor relies on IP to domain name lookups. As these can easily be spoofed, the domain factor should be avoided.</P>
 <H3><A NAME="The access to grant">5.3.3. The access to grant</A></H3>
 <P>The kind of &lt;access&gt; granted can be one of the following:</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
@@ -1597,13 +2226,24 @@
 </TR>
 <TR>
 <TD ALIGN='Left'>
+<TT>disclose</TT>
+</TD>
+<TD ALIGN='Right'>
+<TT>=d</TT>
+</TD>
+<TD ALIGN='Left'>
+needed for information disclosure on error
+</TD>
+</TR>
+<TR>
+<TD ALIGN='Left'>
 <TT>auth</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=x</TT>
+<TT>=dx</TT>
 </TD>
 <TD ALIGN='Left'>
-needed to bind
+needed to authenticate (bind)
 </TD>
 </TR>
 <TR>
@@ -1611,7 +2251,7 @@
 <TT>compare</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=cx</TT>
+<TT>=cdx</TT>
 </TD>
 <TD ALIGN='Left'>
 needed to compare
@@ -1622,7 +2262,7 @@
 <TT>search</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=scx</TT>
+<TT>=scdx</TT>
 </TD>
 <TD ALIGN='Left'>
 needed to apply search filters
@@ -1633,7 +2273,7 @@
 <TT>read</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=rscx</TT>
+<TT>=rscdx</TT>
 </TD>
 <TD ALIGN='Left'>
 needed to read search results
@@ -1644,17 +2284,28 @@
 <TT>write</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=wrscx</TT>
+<TT>=wrscdx</TT>
 </TD>
 <TD ALIGN='Left'>
 needed to modify/rename
 </TD>
 </TR>
+<TR>
+<TD ALIGN='Left'>
+<TT>manage</TT>
+</TD>
+<TD ALIGN='Right'>
+<TT>=mwrscdx</TT>
+</TD>
+<TD ALIGN='Left'>
+needed to manage
+</TD>
+</TR>
 </TABLE>
 
-<P>Each level implies all lower levels of access. So, for example, granting someone <TT>write</TT> access to an entry also grants them <TT>read</TT>, <TT>search</TT>, <TT>compare</TT>, and <TT>auth</TT> access.  However, one may use the privileges specifier to grant specific permissions.</P>
+<P>Each level implies all lower levels of access. So, for example, granting someone <TT>write</TT> access to an entry also grants them <TT>read</TT>, <TT>search</TT>, <TT>compare</TT>, <TT>auth</TT> and <TT>disclose</TT> access.  However, one may use the privileges specifier to grant specific permissions.</P>
 <H3><A NAME="Access Control Evaluation">5.3.4. Access Control Evaluation</A></H3>
-<P>When evaluating whether some requester should be given access to an entry and/or attribute, slapd compares the entry and/or attribute to the <TT>&lt;what&gt;</TT> selectors given in the configuration. For each entry, access controls provided in the database which holds the entry (or the first database if not held in any database) apply first, followed by the global access directives (which are held in the <TT>frontend</TT> database definition).  Within this priority, access directives are examined in the order in which they appear in the configuration attribute.  Slapd stops with the first <TT>&lt;what&gt;</TT> selector that matches the entry and/or attribute. The corresponding access directive is the one slapd will use to evaluate access.</P>
+<P>When evaluating whether some requester should be given access to an entry and/or attribute, slapd compares the entry and/or attribute to the <TT>&lt;what&gt;</TT> selectors given in the configuration.  For each entry, access controls provided in the database which holds the entry (or the first database if not held in any database) apply first, followed by the global access directives (which are held in the <TT>frontend</TT> database definition).  Within this priority, access directives are examined in the order in which they appear in the configuration attribute.  Slapd stops with the first <TT>&lt;what&gt;</TT> selector that matches the entry and/or attribute. The corresponding access directive is the one slapd will use to evaluate access.</P>
 <P>Next, slapd compares the entity requesting access to the <TT>&lt;who&gt;</TT> selectors within the access directive selected above in the order in which they appear. It stops with the first <TT>&lt;who&gt;</TT> selector that matches the requester. This determines the access the entity requesting access has to the entry and/or attribute.</P>
 <P>Finally, slapd compares the access granted in the selected <TT>&lt;access&gt;</TT> clause to the access requested by the client. If it allows greater or equal access, access is granted. Otherwise, access is denied.</P>
 <P>The order of evaluation of access directives makes their placement in the configuration file important. If one access directive is more specific than another in terms of the entries it selects, it should appear first in the configuration. Similarly, if one <TT>&lt;who&gt;</TT> selector is more specific than another it should come first in the access directive. The access control examples given below should help make this clear.</P>
@@ -1822,24 +2473,26 @@
 <P>Lines 30 through 32 indicate the indices to maintain for various attributes.</P>
 <P>Lines 33 through 41 specify access control for entries in this database.  As this is the first database, the controls also apply to entries not held in any database (such as the Root DSE).  For all applicable entries, the <TT>userPassword</TT> attribute is writable by the entry itself and by the &quot;admin&quot; entry.  It may be used for authentication/authorization purposes, but is otherwise not readable. All other attributes are writable by the entry and the &quot;admin&quot; entry, but may be read by all users (authenticated or not).</P>
 <P>Line 42 is a blank line, indicating the end of this entry.</P>
-<P>The next section of the example configuration file defines another BDB database. This one handles queries involving the <TT>dc=example,dc=net</TT> subtree but is managed by the same entity as the first database.  Note that without line 51, the read access would be allowed due to the global access rule at line 19.</P>
+<P>The next section of the example configuration file defines another BDB database. This one handles queries involving the <TT>dc=example,dc=net</TT> subtree but is managed by the same entity as the first database.  Note that without line 52, the read access would be allowed due to the global access rule at line 19.</P>
 <PRE>
- 42.    # BDB definition for example.net
- 43.    dn: olcDatabase=bdb,cn=config
- 44.    objectClass: olcDatabaseConfig
- 45.    objectClass: olcBdbConfig
- 46.    olcDatabase: bdb
- 47.    olcSuffix: &quot;dc=example,dc=net&quot;
- 48.    olcDbDirectory: /usr/local/var/openldap-data-net
- 49.    olcRootDN: &quot;cn=Manager,dc=example,dc=com&quot;
- 50.    olcDbIndex: objectClass eq
- 51.    olcAccess: to * by users read
+ 43.    # BDB definition for example.net
+ 44.    dn: olcDatabase=bdb,cn=config
+ 45.    objectClass: olcDatabaseConfig
+ 46.    objectClass: olcBdbConfig
+ 47.    olcDatabase: bdb
+ 48.    olcSuffix: &quot;dc=example,dc=net&quot;
+ 49.    olcDbDirectory: /usr/local/var/openldap-data-net
+ 50.    olcRootDN: &quot;cn=Manager,dc=example,dc=com&quot;
+ 51.    olcDbIndex: objectClass eq
+ 52.    olcAccess: to * by users read
 </PRE>
+<H2><A NAME="Converting from slapd.conf(8) to a {{B:cn=config}} directory format">5.5. Converting from slapd.conf(8) to a <B>cn=config</B> directory format</A></H2>
+<P>Discuss slap* -f slapd.conf -F slapd.d/  (man slapd-config)</P>
 <P></P>
 <HR>
 <H1><A NAME="The slapd Configuration File">6. The slapd Configuration File</A></H1>
 <P>Once the software has been built and installed, you are ready to configure <EM>slapd</EM>(8) for use at your site. The slapd runtime configuration is primarily accomplished through the <EM>slapd.conf</EM>(5) file, normally installed in the <TT>/usr/local/etc/openldap</TT> directory.</P>
-<P>An alternate configuration file can be specified via a command-line option to <EM>slapd</EM>(8) or <EM>slurpd</EM>(8). This chapter describes the general format of the config file, followed by a detailed description of commonly used config file directives.</P>
+<P>An alternate configuration file location can be specified via a command-line option to <EM>slapd</EM>(8). This chapter describes the general format of the <EM>slapd.conf</EM>(5) configuration file, followed by a detailed description of commonly used config file directives.</P>
 <H2><A NAME="Configuration File Format">6.1. Configuration File Format</A></H2>
 <P>The <EM>slapd.conf</EM>(5) file consists of three types of configuration information: global, backend specific, and database specific.  Global information is specified first, followed by information associated with a particular backend type, which is then followed by information associated with a particular database instance.  Global directives can be overridden in backend and/or database directives, and backend directives can be overridden by database directives.</P>
 <P>Blank lines and comment lines beginning with a '<TT>#</TT>' character are ignored.  If a line begins with white space, it is considered a continuation of the previous line (even if the previous line is a comment).</P>
@@ -1873,12 +2526,12 @@
 <P>This section details commonly used configuration directives.  For a complete list, see the <EM>slapd.conf</EM>(5) manual page.  This section separates the configuration file directives into global, backend-specific and data-specific categories, describing each directive and its default value (if any), and giving an example of its use.</P>
 <H3><A NAME="Global Directives">6.2.1. Global Directives</A></H3>
 <P>Directives described in this section apply to all backends and databases unless specifically overridden in a backend or database definition.  Arguments that should be replaced by actual text are shown in brackets <TT>&lt;&gt;</TT>.</P>
-<H4><A NAME="access to &lt;what&gt; [ by &lt;who&gt; &lt;accesslevel&gt; &lt;control&gt; ]+">6.2.1.1. access to &lt;what&gt; [ by &lt;who&gt; &lt;accesslevel&gt; &lt;control&gt; ]+</A></H4>
-<P>This directive grants access (specified by &lt;accesslevel&gt;) to a set of entries and/or attributes (specified by &lt;what&gt;) by one or more requesters (specified by &lt;who&gt;). See the <A HREF="#Access Control">Access Control</A> section of this chapter for a summary of basic usage.</P>
+<H4><A NAME="access to &lt;what&gt; [ by &lt;who&gt; [&lt;accesslevel&gt;] [&lt;control&gt;] ]+">6.2.1.1. access to &lt;what&gt; [ by &lt;who&gt; [&lt;accesslevel&gt;] [&lt;control&gt;] ]+</A></H4>
+<P>This directive grants access (specified by &lt;accesslevel&gt;) to a set of entries and/or attributes (specified by &lt;what&gt;) by one or more requestors (specified by &lt;who&gt;).  See the <A HREF="#The access Configuration Directive">The access Configuration Directive</A> section of this chapter for a summary of basic usage.</P>
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>If no <TT>access</TT> directives are specified, the default access control policy, <TT>access to * by * read</TT>, allows all both authenticated and anonymous users read access.
 <HR WIDTH="80%" ALIGN="Left"></P>
-<H4><A NAME="attributetype &lt;{{REF:RFC2252}} Attribute Type Description&gt;"> </A>6.2.1.2. attributetype &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc2252.txt">RFC2252</A> Attribute Type Description&gt;</H4>
+<H4><A NAME="attributetype &lt;{{REF:RFC4512}} Attribute Type Description&gt;"> </A>6.2.1.2. attributetype &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4512</A> Attribute Type Description&gt;</H4>
 <P>This directive defines an attribute type. Please see the <A HREF="#Schema Specification">Schema Specification</A> chapter for information regarding how to use this directive.</P>
 <H4><A NAME="idletimeout &lt;integer&gt;">6.2.1.3. idletimeout &lt;integer&gt;</A></H4>
 <P>Specify the number of seconds to wait before forcibly closing an idle client connection.  An idletimeout of 0, the default, disables this feature.</P>
@@ -1890,7 +2543,7 @@
 <H4><A NAME="loglevel &lt;integer&gt;">6.2.1.5. loglevel &lt;integer&gt;</A></H4>
 <P>This directive specifies the level at which debugging statements and operation statistics should be syslogged (currently logged to the <EM>syslogd</EM>(8) <TT>LOG_LOCAL4</TT> facility). You must have configured OpenLDAP <TT>--enable-debug</TT> (the default) for this to work (except for the two statistics levels, which are always enabled).  Log levels are additive. To display what numbers correspond to what kind of debugging, invoke slapd with <TT>-?</TT> or consult the table below. The possible values for &lt;integer&gt; are:</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
-<CAPTION ALIGN=top>Table 5.1: Debugging Levels</CAPTION>
+<CAPTION ALIGN=top>Table 6.1: Debugging Levels</CAPTION>
 <TR CLASS="heading">
 <TD ALIGN='Right'>
 <STRONG>Level</STRONG>
@@ -2022,7 +2675,7 @@
 <PRE>
  loglevel 256
 </PRE>
-<H4><A NAME="objectclass &lt;{{REF:RFC2252}} Object Class Description&gt;"> </A>6.2.1.6. objectclass &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc2252.txt">RFC2252</A> Object Class Description&gt;</H4>
+<H4><A NAME="objectclass &lt;{{REF:RFC4512}} Object Class Description&gt;"> </A>6.2.1.6. objectclass &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4512</A> Object Class Description&gt;</H4>
 <P>This directive defines an object class. Please see the <A HREF="#Schema Specification">Schema Specification</A> chapter for information regarding how to use this directive.</P>
 <H4><A NAME="referral &lt;URI&gt;">6.2.1.7. referral &lt;URI&gt;</A></H4>
 <P>This directive specifies the referral to pass back when slapd cannot find a local database to handle a request.</P>
@@ -2046,7 +2699,7 @@
 <H3><A NAME="General Backend Directives">6.2.2. General Backend Directives</A></H3>
 <P>Directives in this section apply only to the backend in which they are defined. They are supported by every type of backend. Backend directives apply to all databases instances of the same type and, depending on the directive, may be overridden by database directives.</P>
 <H4><A NAME="backend &lt;type&gt;">6.2.2.1. backend &lt;type&gt;</A></H4>
-<P>This directive marks the beginning of a backend declaration. <TT>&lt;type&gt;</TT> should be one of the supported backend types listed in Table 5.2.</P>
+<P>This directive marks the beginning of a backend declaration. <TT>&lt;type&gt;</TT> should be one of the supported backend types listed in Table 6.2.</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
 <CAPTION ALIGN=top>Table 5.2: Database Backends</CAPTION>
 <TR CLASS="heading">
@@ -2091,14 +2744,6 @@
 </TR>
 <TR>
 <TD>
-<TT>ldbm</TT>
-</TD>
-<TD>
-Lightweight DBM backend
-</TD>
-</TR>
-<TR>
-<TD>
 <TT>meta</TT>
 </TD>
 <TD>
@@ -2155,7 +2800,7 @@
 <H3><A NAME="General Database Directives">6.2.3. General Database Directives</A></H3>
 <P>Directives in this section apply only to the database in which they are defined. They are supported by every type of database.</P>
 <H4><A NAME="database &lt;type&gt;">6.2.3.1. database &lt;type&gt;</A></H4>
-<P>This directive marks the beginning of a database instance declaration. <TT>&lt;type&gt;</TT> should be one of the supported backend types listed in Table 5.2.</P>
+<P>This directive marks the beginning of a database instance declaration. <TT>&lt;type&gt;</TT> should be one of the supported backend types listed in Table 6.2.</P>
 <P>Example:</P>
 <PRE>
         database bdb
@@ -2167,28 +2812,7 @@
 <PRE>
         readonly off
 </PRE>
-<H4><A NAME="replica">6.2.3.3. replica</A></H4>
-<PRE>
-        replica uri=ldap[s]://&lt;hostname&gt;[:&lt;port&gt;] | host=&lt;hostname&gt;[:&lt;port&gt;]
-                [bindmethod={simple|sasl}]
-                [&quot;binddn=&lt;DN&gt;&quot;]
-                [saslmech=&lt;mech&gt;]
-                [authcid=&lt;identity&gt;]
-                [authzid=&lt;identity&gt;]
-                [credentials=&lt;password&gt;]
-</PRE>
-<P>This directive specifies a replication site for this database. The <TT>uri=</TT> parameter specifies a scheme, a host and optionally a port where the slave slapd instance can be found. Either a domain name or IP address may be used for &lt;hostname&gt;. If &lt;port&gt; is not given, the standard LDAP port number (389 or 636) is used.</P>
-<P><TT>host</TT> is deprecated in favor of the <TT>uri</TT> parameter.</P>
-<P><TT>uri</TT> allows the replica LDAP server to be specified as an LDAP URI such as <TT>ldap://slave.example.com:389</TT> or <TT>ldaps://slave.example.com:636</TT>.</P>
-<P>The <TT>binddn=</TT> parameter gives the DN to bind as for updates to the slave slapd. It should be a DN which has read/write access to the slave slapd's database.  It must also match the <TT>updatedn</TT> directive in the slave slapd's config file.  Generally, this DN <EM>should not</EM> be the same as the <TT>rootdn</TT> of the master database.  Since DNs are likely to contain embedded spaces, the entire <TT>&quot;binddn=&lt;DN&gt;&quot;</TT> string should be enclosed in double quotes.</P>
-<P>The <TT>bindmethod</TT> is <TT>simple</TT> or <TT>sasl</TT>, depending on whether simple password-based authentication or <TERM>SASL</TERM> authentication is to be used when connecting to the slave slapd.</P>
-<P>Simple authentication should not be used unless adequate data integrity and confidentiality protections are in place (e.g. TLS or IPSEC).  Simple authentication requires specification of <TT>binddn</TT> and <TT>credentials</TT> parameters.</P>
-<P>SASL authentication is generally recommended.  SASL authentication requires specification of a mechanism using the <TT>saslmech</TT> parameter. Depending on the mechanism, an authentication identity and/or credentials can be specified using <TT>authcid</TT> and <TT>credentials</TT> respectively.  The <TT>authzid</TT> parameter may be used to specify an authorization identity.</P>
-<P>See the chapter entitled <A HREF="#Replication with slurpd">Replication with slurpd</A> for more information on how to use this directive.</P>
-<H4><A NAME="replogfile &lt;filename&gt;">6.2.3.4. replogfile &lt;filename&gt;</A></H4>
-<P>This directive specifies the name of the replication log file to which slapd will log changes. The replication log is typically written by slapd and read by slurpd. Normally, this directive is only used if slurpd is being used to replicate the database. However, you can also use it to generate a transaction log, if slurpd is not running. In this case, you will need to periodically truncate the file, since it will grow indefinitely otherwise.</P>
-<P>See the chapter entitled <A HREF="#Replication with slurpd">Replication with slurpd</A> for more information on how to use this directive.</P>
-<H4><A NAME="rootdn &lt;DN&gt;">6.2.3.5. rootdn &lt;DN&gt;</A></H4>
+<H4><A NAME="rootdn &lt;DN&gt;">6.2.3.3. rootdn &lt;DN&gt;</A></H4>
 <P>This directive specifies the DN that is not subject to access control or administrative limit restrictions for operations on this database.  The DN need not refer to an entry in this database or even in the directory. The DN may refer to a SASL identity.</P>
 <P>Entry-based Example:</P>
 <PRE>
@@ -2199,19 +2823,19 @@
         rootdn &quot;uid=root,cn=example.com,cn=digest-md5,cn=auth&quot;
 </PRE>
 <P>See the <A HREF="#SASL Authentication">SASL Authentication</A> section for information on SASL authentication identities.</P>
-<H4><A NAME="rootpw &lt;password&gt;">6.2.3.6. rootpw &lt;password&gt;</A></H4>
+<H4><A NAME="rootpw &lt;password&gt;">6.2.3.4. rootpw &lt;password&gt;</A></H4>
 <P>This directive can be used to specifies a password for the DN for the rootdn (when the rootdn is set to a DN within the database).</P>
 <P>Example:</P>
 <PRE>
         rootpw secret
 </PRE>
-<P>It is also permissible to provide hash of the password in RFC 2307 form.  <EM>slappasswd</EM>(8) may be used to generate the password hash.</P>
+<P>It is also permissible to provide hash of the password in <A HREF="http://www.rfc-editor.org/rfc/rfc2307.txt">RFC2307</A> form.  <EM>slappasswd</EM>(8) may be used to generate the password hash.</P>
 <P>Example:</P>
 <PRE>
         rootpw {SSHA}ZKKuqbEKJfKSXhUbHG3fG8MDn9j1v4QN
 </PRE>
 <P>The hash was generated using the command <TT>slappasswd -s secret</TT>.</P>
-<H4><A NAME="suffix &lt;dn suffix&gt;">6.2.3.7. suffix &lt;dn suffix&gt;</A></H4>
+<H4><A NAME="suffix &lt;dn suffix&gt;">6.2.3.5. suffix &lt;dn suffix&gt;</A></H4>
 <P>This directive specifies the DN suffix of queries that will be passed to this backend database. Multiple suffix lines can be given, and at least one is required for each database definition.</P>
 <P>Example:</P>
 <PRE>
@@ -2221,14 +2845,14 @@
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>When the backend to pass a query to is selected, slapd looks at the suffix line(s) in each database definition in the order they appear in the file. Thus, if one database suffix is a prefix of another, it must appear after it in the config file.
 <HR WIDTH="80%" ALIGN="Left"></P>
-<H4><A NAME="syncrepl">6.2.3.8. syncrepl</A></H4>
+<H4><A NAME="syncrepl">6.2.3.6. syncrepl</A></H4>
 <PRE>
         syncrepl rid=&lt;replica ID&gt;
                 provider=ldap[s]://&lt;hostname&gt;[:port]
                 [type=refreshOnly|refreshAndPersist]
                 [interval=dd:hh:mm:ss]
                 [retry=[&lt;retry interval&gt; &lt;# of retries&gt;]+]
-                [searchbase=&lt;base DN&gt;]
+                searchbase=&lt;base DN&gt;
                 [filter=&lt;filter str&gt;]
                 [scope=sub|one|base]
                 [attrs=&lt;attr list&gt;]
@@ -2245,7 +2869,7 @@
                 [realm=&lt;realm&gt;]
                 [secprops=&lt;properties&gt;]
 </PRE>
-<P>This directive specifies the current database as a replica of the master content by establishing the current <EM>slapd</EM>(8) as a replication consumer site running a syncrepl replication engine. The master database is located at the replication provider site specified by the <TT>provider</TT> parameter. The replica database is kept up-to-date with the master content using the LDAP Content Synchronization protocol. See <TT>draft-zeilenga-ldup-sync-xx.txt</TT> (<EM>a work in progress</EM>) for more information on the protocol.</P>
+<P>This directive specifies the current database as a replica of the master content by establishing the current <EM>slapd</EM>(8) as a replication consumer site running a syncrepl replication engine. The master database is located at the replication provider site specified by the <TT>provider</TT> parameter. The replica database is kept up-to-date with the master content using the LDAP Content Synchronization protocol. See <A HREF="http://www.rfc-editor.org/rfc/rfc4533.txt">RFC4533</A> for more information on the protocol.</P>
 <P>The <TT>rid</TT> parameter is used for identification of the current <TT>syncrepl</TT> directive within the replication consumer server, where <TT>&lt;replica ID&gt;</TT> uniquely identifies the syncrepl specification described by the current <TT>syncrepl</TT> directive. <TT>&lt;replica ID&gt;</TT> is non-negative and is no more than three decimal digits in length.</P>
 <P>The <TT>provider</TT> parameter specifies the replication provider site containing the master content as an LDAP URI. The <TT>provider</TT> parameter specifies a scheme, a host and optionally a port where the provider slapd instance can be found. Either a domain name or IP address may be used for &lt;hostname&gt;. Examples are <TT>ldap://provider.example.com:389</TT> or <TT>ldaps://192.168.1.1:636</TT>. If &lt;port&gt; is not given, the standard LDAP port number (389 or 636) is used. Note that the syncrepl uses a consumer-initiated protocol, and hence its specification is located at the consumer site, whereas the <TT>replica</TT> specification is located at the provider site. <TT>syncrepl</TT> and <TT>replica</TT> directives define two independent replication mechanisms. They do not represent the replication peers of each other.</P>
 <P>The content of the syncrepl replica is defined using a search specification as its result set. The consumer slapd will send search requests to the provider slapd according to the search specification. The search specification includes <TT>searchbase</TT>, <TT>scope</TT>, <TT>filter</TT>, <TT>attrs</TT>, <TT>attrsonly</TT>, <TT>sizelimit</TT>, and <TT>timelimit</TT> parameters as in the normal search specification. The <TT>searchbase</TT> parameter has no default value and must always be specified. The <TT>scope</TT> defaults to <TT>sub</TT>, the <TT>filter</TT> defaults to <TT>(objectclass=*)</TT>, <TT>attrs</TT> defaults to <TT>&quot;*,+&quot;</TT> to replicate all user and operational attributes, and <TT>attrsonly</TT> is unset by default. Both <TT>sizelimit</TT> and <TT>timelimit</TT> default to &quot;unlimited&quot;, and only integers or &quot;unlimited&quot; may be specified.</P>
@@ -2254,24 +2878,13 @@
 <P>The schema checking can be enforced at the LDAP Sync consumer site by turning on the <TT>schemachecking</TT> parameter. If it is turned on, every replicated entry will be checked for its schema as the entry is stored into the replica content. Every entry in the replica should contain those attributes required by the schema definition. If it is turned off, entries will be stored without checking schema conformance. The default is off.</P>
 <P>The <TT>binddn</TT> parameter gives the DN to bind as for the syncrepl searches to the provider slapd. It should be a DN which has read access to the replication content in the master database.</P>
 <P>The <TT>bindmethod</TT> is <TT>simple</TT> or <TT>sasl</TT>, depending on whether simple password-based authentication or <TERM>SASL</TERM> authentication is to be used when connecting to the provider slapd.</P>
-<P>Simple authentication should not be used unless adequate data integrity and confidentiality protections are in place (e.g. TLS or IPSEC). Simple authentication requires specification of <TT>binddn</TT> and <TT>credentials</TT> parameters.</P>
+<P>Simple authentication should not be used unless adequate data integrity and confidentiality protections are in place (e.g. TLS or IPsec). Simple authentication requires specification of <TT>binddn</TT> and <TT>credentials</TT> parameters.</P>
 <P>SASL authentication is generally recommended.  SASL authentication requires specification of a mechanism using the <TT>saslmech</TT> parameter. Depending on the mechanism, an authentication identity and/or credentials can be specified using <TT>authcid</TT> and <TT>credentials</TT>, respectively.  The <TT>authzid</TT> parameter may be used to specify an authorization identity.</P>
 <P>The <TT>realm</TT> parameter specifies a realm which a certain mechanisms authenticate the identity within. The <TT>secprops</TT> parameter specifies Cyrus SASL security properties.</P>
-<P>The syncrepl replication mechanism is supported by the three native backends: back-bdb, back-hdb, and back-ldbm.</P>
+<P>The syncrepl replication mechanism is supported by the two primary database backends: back-bdb and back-hdb.</P>
 <P>See the <A HREF="#LDAP Sync Replication">LDAP Sync Replication</A> chapter of the admin guide for more information on how to use this directive.</P>
-<H4><A NAME="updatedn &lt;DN&gt;">6.2.3.9. updatedn &lt;DN&gt;</A></H4>
-<P>This directive is only applicable in a slave slapd. It specifies the DN allowed to make changes to the replica.  This may be the DN <EM>slurpd</EM>(8) binds as when making changes to the replica or the DN associated with a SASL identity.</P>
-<P>Entry-based Example:</P>
-<PRE>
-        updatedn &quot;cn=Update Daemon,dc=example,dc=com&quot;
-</PRE>
-<P>SASL-based Example:</P>
-<PRE>
-        updatedn &quot;uid=slurpd,cn=example.com,cn=digest-md5,cn=auth&quot;
-</PRE>
-<P>See the <A HREF="#Replication with slurpd">Replication with slurpd</A> chapter for more information on how to use this directive.</P>
-<H4><A NAME="updateref &lt;URL&gt;">6.2.3.10. updateref &lt;URL&gt;</A></H4>
-<P>This directive is only applicable in a slave slapd. It specifies the URL to return to clients which submit update requests upon the replica. If specified multiple times, each <TERM>URL</TERM> is provided.</P>
+<H4><A NAME="updateref &lt;URL&gt;">6.2.3.7. updateref &lt;URL&gt;</A></H4>
+<P>This directive is only applicable in a <EM>slave</EM> (or <EM>shadow</EM>) <EM>slapd</EM>(8) instance. It specifies the URL to return to clients which submit update requests upon the replica. If specified multiple times, each <TERM>URL</TERM> is provided.</P>
 <P>Example:</P>
 <PRE>
         updateref       ldap://master.example.net
@@ -2284,55 +2897,11 @@
 <PRE>
         directory /usr/local/var/openldap-data
 </PRE>
-<H3><A NAME="LDBM Database Directives">6.2.5. LDBM Database Directives</A></H3>
-<P>Directives in this category only apply to a <TERM>LDBM</TERM> database. That is, they must follow a &quot;database ldbm&quot; line and come before any subsequent &quot;backend&quot; or &quot;database&quot; line.  For a complete reference of LDBM configuration directives, see <EM>slapd-ldbm</EM>(5).</P>
-<H4><A NAME="cachesize &lt;integer&gt;">6.2.5.1. cachesize &lt;integer&gt;</A></H4>
-<P>This directive specifies the size in entries of the in-memory cache maintained by the LDBM backend database instance.</P>
-<P>Default:</P>
+<H2><A NAME="The access Configuration Directive">6.3. The access Configuration Directive</A></H2>
+<P>Access to entries and attributes is controlled by the access configuration file directive. The general form of an access line is:</P>
 <PRE>
-        cachesize 1000
-</PRE>
-<H4><A NAME="dbcachesize &lt;integer&gt;">6.2.5.2. dbcachesize &lt;integer&gt;</A></H4>
-<P>This directive specifies the size in bytes of the in-memory cache associated with each open index file. If not supported by the underlying database method, this directive is ignored without comment. Increasing this number uses more memory but can cause a dramatic performance increase, especially during modifies or when building indices.</P>
-<P>Default:</P>
-<PRE>
-        dbcachesize 100000
-</PRE>
-<H4><A NAME="dbnolocking">6.2.5.3. dbnolocking</A></H4>
-<P>This option, if present, disables database locking. Enabling this option may improve performance at the expense of data security.</P>
-<H4><A NAME="dbnosync">6.2.5.4. dbnosync</A></H4>
-<P>This option causes on-disk database contents to not be immediately synchronized with in memory changes upon change.  Enabling this option may improve performance at the expense of data integrity.</P>
-<H4><A NAME="directory &lt;directory&gt;">6.2.5.5. directory &lt;directory&gt;</A></H4>
-<P>This directive specifies the directory where the LDBM files containing the database and associated indices live.</P>
-<P>Default:</P>
-<PRE>
-        directory /usr/local/var/openldap-data
-</PRE>
-<H4><A NAME="index {&lt;attrlist&gt; | default} [pres,eq,approx,sub,none]">6.2.5.6. index {&lt;attrlist&gt; | default} [pres,eq,approx,sub,none]</A></H4>
-<P>This directive specifies the indices to maintain for the given attribute. If only an <TT>&lt;attrlist&gt;</TT> is given, the default indices are maintained.</P>
-<P>Example:</P>
-<PRE>
-        index default pres,eq
-        index uid
-        index cn,sn pres,eq,sub
-        index objectClass eq
-</PRE>
-<P>The first line sets the default set of indices to maintain to present and equality.  The second line causes the default (pres,eq) set of indices to be maintained for the <TT>uid</TT> attribute type. The third line causes present, equality, and substring indices to be maintained for <TT>cn</TT> and <TT>sn</TT> attribute types.  The fourth line causes an equality index for the <TT>objectClass</TT> attribute type.</P>
-<P>By default, no indices are maintained.  It is generally advised that minimally an equality index upon objectClass be maintained.</P>
-<PRE>
-        index objectClass eq
-</PRE>
-<H4><A NAME="mode &lt;integer&gt;">6.2.5.7. mode &lt;integer&gt;</A></H4>
-<P>This directive specifies the file protection mode that newly created database index files should have.</P>
-<P>Default:</P>
-<PRE>
-        mode 0600
-</PRE>
-<H2><A NAME="Access Control">6.3. Access Control</A></H2>
-<P>Access to slapd entries and attributes is controlled by the access configuration file directive. The general form of an access line is:</P>
-<PRE>
         &lt;access directive&gt; ::= access to &lt;what&gt;
-                [by &lt;who&gt; &lt;access&gt; &lt;control&gt;]+
+                [by &lt;who&gt; [&lt;access&gt;] [&lt;control&gt;] ]+
         &lt;what&gt; ::= * |
                 [dn[.&lt;basic-style&gt;]=&lt;regex&gt; | dn.&lt;scope-style&gt;=&lt;DN&gt;]
                 [filter=&lt;ldapfilter&gt;] [attrs=&lt;attrlist&gt;]
@@ -2351,8 +2920,8 @@
                 [set=&lt;setspec&gt;]
                 [aci=&lt;attrname&gt;]
         &lt;access&gt; ::= [self]{&lt;level&gt;|&lt;priv&gt;}
-        &lt;level&gt; ::= none | auth | compare | search | read | write
-        &lt;priv&gt; ::= {=|+|-}{w|r|s|c|x|0}+
+        &lt;level&gt; ::= none | disclose | auth | compare | search | read | write | manage
+        &lt;priv&gt; ::= {=|+|-}{m|w|r|s|c|x|d|0}+
         &lt;control&gt; ::= [stop | continue | break]
 </PRE>
 <P>where the &lt;what&gt; part selects the entries and/or attributes to which the access applies, the <TT>&lt;who&gt;</TT> part specifies which entities are granted access, and the <TT>&lt;access&gt;</TT> part specifies the access granted. Multiple <TT>&lt;who&gt; &lt;access&gt; &lt;control&gt;</TT> triplets are supported, allowing many entities to be granted different access to the same set of entries and attributes. Not all of these access control options are described here; for more details see the <EM>slapd.access</EM>(5) man page.</P>
@@ -2363,7 +2932,7 @@
         to dn[.&lt;basic-style&gt;]=&lt;regex&gt;
         to dn.&lt;scope-style&gt;=&lt;DN&gt;
 </PRE>
-<P>The first form is used to select all entries.  The second form may be used to select entries by matching a regular expression against the target entry's <EM>normalized DN</EM>.   (The second form is not discussed further in this document.)  The third form is used to select entries which are within the requested scope of DN.  The &lt;DN&gt; is a string representation of the Distinguished Name, as described in <A HREF="http://www.rfc-editor.org/rfc/rfc2253.txt">RFC2253</A>.</P>
+<P>The first form is used to select all entries.  The second form may be used to select entries by matching a regular expression against the target entry's <EM>normalized DN</EM>.   (The second form is not discussed further in this document.)  The third form is used to select entries which are within the requested scope of DN.  The &lt;DN&gt; is a string representation of the Distinguished Name, as described in <A HREF="http://www.rfc-editor.org/rfc/rfc4514.txt">RFC4514</A>.</P>
 <P>The scope can be either <TT>base</TT>, <TT>one</TT>, <TT>subtree</TT>, or <TT>children</TT>.  Where <TT>base</TT> matches only the entry with provided DN, <TT>one</TT> matches the entries whose parent is the provided DN, <TT>subtree</TT> matches all entries in the subtree whose root is the provided DN, and <TT>children</TT> matches all entries under the DN (but not the entry named by the DN).</P>
 <P>For example, if the directory contained entries named:</P>
 <PRE>
@@ -2387,7 +2956,7 @@
 <PRE>
         to filter=&lt;ldap filter&gt;
 </PRE>
-<P>where &lt;ldap filter&gt; is a string representation of an LDAP search filter, as described in <A HREF="http://www.rfc-editor.org/rfc/rfc2254.txt">RFC2254</A>.  For example:</P>
+<P>where &lt;ldap filter&gt; is a string representation of an LDAP search filter, as described in <A HREF="http://www.rfc-editor.org/rfc/rfc4515.txt">RFC4515</A>.  For example:</P>
 <PRE>
         to filter=(objectClass=person)
 </PRE>
@@ -2408,7 +2977,7 @@
 <H3><A NAME="Who to grant access to">6.3.2. Who to grant access to</A></H3>
 <P>The &lt;who&gt; part identifies the entity or entities being granted access. Note that access is granted to &quot;entities&quot; not &quot;entries.&quot; The following table summarizes entity specifiers:</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
-<CAPTION ALIGN=top>Table 5.3: Access Entity Specifiers</CAPTION>
+<CAPTION ALIGN=top>Table 6.3: Access Entity Specifiers</CAPTION>
 <TR CLASS="heading">
 <TD>
 <STRONG>Specifier</STRONG>
@@ -2473,11 +3042,11 @@
         dnattr=&lt;dn-valued attribute name&gt;
 </PRE>
 <P>The dnattr specification is used to give access to an entry whose DN is listed in an attribute of the entry (e.g., give access to a group entry to whoever is listed as the owner of the group entry).</P>
-<P>Some factors may not be appropriate in all environments (or any). For example, the domain factor relies on IP to domain name lookups. As these can easily spoofed, the domain factor should not be avoided.</P>
+<P>Some factors may not be appropriate in all environments (or any). For example, the domain factor relies on IP to domain name lookups. As these can easily be spoofed, the domain factor should be avoided.</P>
 <H3><A NAME="The access to grant">6.3.3. The access to grant</A></H3>
 <P>The kind of &lt;access&gt; granted can be one of the following:</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
-<CAPTION ALIGN=top>Table 5.4: Access Levels</CAPTION>
+<CAPTION ALIGN=top>Table 6.4: Access Levels</CAPTION>
 <TR CLASS="heading">
 <TD ALIGN='Left'>
 <STRONG>Level</STRONG>
@@ -2502,13 +3071,24 @@
 </TR>
 <TR>
 <TD ALIGN='Left'>
+<TT>disclose</TT>
+</TD>
+<TD ALIGN='Right'>
+<TT>=d</TT>
+</TD>
+<TD ALIGN='Left'>
+needed for information disclosure on error
+</TD>
+</TR>
+<TR>
+<TD ALIGN='Left'>
 <TT>auth</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=x</TT>
+<TT>=dx</TT>
 </TD>
 <TD ALIGN='Left'>
-needed to bind
+needed to authenticate (bind)
 </TD>
 </TR>
 <TR>
@@ -2516,7 +3096,7 @@
 <TT>compare</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=cx</TT>
+<TT>=cdx</TT>
 </TD>
 <TD ALIGN='Left'>
 needed to compare
@@ -2527,7 +3107,7 @@
 <TT>search</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=scx</TT>
+<TT>=scdx</TT>
 </TD>
 <TD ALIGN='Left'>
 needed to apply search filters
@@ -2538,7 +3118,7 @@
 <TT>read</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=rscx</TT>
+<TT>=rscdx</TT>
 </TD>
 <TD ALIGN='Left'>
 needed to read search results
@@ -2549,15 +3129,26 @@
 <TT>write</TT>
 </TD>
 <TD ALIGN='Right'>
-<TT>=wrscx</TT>
+<TT>=wrscdx</TT>
 </TD>
 <TD ALIGN='Left'>
 needed to modify/rename
 </TD>
 </TR>
+<TR>
+<TD ALIGN='Left'>
+<TT>manage</TT>
+</TD>
+<TD ALIGN='Right'>
+<TT>=mwrscdx</TT>
+</TD>
+<TD ALIGN='Left'>
+needed to manage
+</TD>
+</TR>
 </TABLE>
 
-<P>Each level implies all lower levels of access. So, for example, granting someone <TT>write</TT> access to an entry also grants them <TT>read</TT>, <TT>search</TT>, <TT>compare</TT>, and <TT>auth</TT> access.  However, one may use the privileges specifier to grant specific permissions.</P>
+<P>Each level implies all lower levels of access. So, for example, granting someone <TT>write</TT> access to an entry also grants them <TT>read</TT>, <TT>search</TT>, <TT>compare</TT>, <TT>auth</TT> and <TT>disclose</TT> access.  However, one may use the privileges specifier to grant specific permissions.</P>
 <H3><A NAME="Access Control Evaluation">6.3.4. Access Control Evaluation</A></H3>
 <P>When evaluating whether some requester should be given access to an entry and/or attribute, slapd compares the entry and/or attribute to the <TT>&lt;what&gt;</TT> selectors given in the configuration file. For each entry, access controls provided in the database which holds the entry (or the first database if not held in any database) apply first, followed by the global access directives.  Within this priority, access directives are examined in the order in which they appear in the config file.  Slapd stops with the first <TT>&lt;what&gt;</TT> selector that matches the entry and/or attribute. The corresponding access directive is the one slapd will use to evaluate access.</P>
 <P>Next, slapd compares the entity requesting access to the <TT>&lt;who&gt;</TT> selectors within the access directive selected above in the order in which they appear. It stops with the first <TT>&lt;who&gt;</TT> selector that matches the requester. This determines the access the entity requesting access has to the entry and/or attribute.</P>
@@ -2630,34 +3221,25 @@
   8.    directory /usr/local/var/openldap-data
   9.    rootdn &quot;cn=Manager,dc=example,dc=com&quot;
  10.    rootpw secret
- 11.    # replication directives
- 12.    replogfile /usr/local/var/openldap/slapd.replog
- 13.    replica uri=ldap://slave1.example.com:389
- 14.            binddn=&quot;cn=Replicator,dc=example,dc=com&quot;
- 15.            bindmethod=simple credentials=secret
- 16.    replica uri=ldaps://slave2.example.com:636
- 17.            binddn=&quot;cn=Replicator,dc=example,dc=com&quot;
- 18.            bindmethod=simple credentials=secret
- 19.    # indexed attribute definitions
- 20.    index uid pres,eq
- 21.    index cn,sn,uid pres,eq,approx,sub
- 22.    index objectClass eq
- 23.    # database access control definitions
- 24.    access to attrs=userPassword
- 25.            by self write
- 26.            by anonymous auth
- 27.            by dn.base=&quot;cn=Admin,dc=example,dc=com&quot; write
- 28.            by * none
- 29.    access to *
- 30.            by self write
- 31.            by dn.base=&quot;cn=Admin,dc=example,dc=com&quot; write
- 32.            by * read
+ 11.    # indexed attribute definitions
+ 12.    index uid pres,eq
+ 13.    index cn,sn,uid pres,eq,approx,sub
+ 14.    index objectClass eq
+ 15.    # database access control definitions
+ 16.    access to attrs=userPassword
+ 17.            by self write
+ 18.            by anonymous auth
+ 19.            by dn.base=&quot;cn=Admin,dc=example,dc=com&quot; write
+ 20.            by * none
+ 21.    access to *
+ 22.            by self write
+ 23.            by dn.base=&quot;cn=Admin,dc=example,dc=com&quot; write
+ 24.            by * read
 </PRE>
 <P>Line 5 is a comment. The start of the database definition is marked by the database keyword on line 6. Line 7 specifies the DN suffix for queries to pass to this database. Line 8 specifies the directory in which the database files will live.</P>
 <P>Lines 9 and 10 identify the database <EM>super-user</EM> entry and associated password. This entry is not subject to access control or size or time limit restrictions.</P>
-<P>Lines 11 through 18 are for replication. Line 12 specifies the replication log file (where changes to the database are logged - this file is written by slapd and read by slurpd). Lines 13 through 15 specify the hostname and port for a replicated host, the DN to bind as when performing updates, the bind method (simple) and the credentials (password) for the binddn. Lines 16 through 18 specify a second replication site.  See the <A HREF="#Replication with slurpd">Replication with slurpd</A> chapter for more information on these directives.</P>
-<P>Lines 20 through 22 indicate the indices to maintain for various attributes.</P>
-<P>Lines 24 through 32 specify access control for entries in this database.  As this is the first database, the controls also apply to entries not held in any database (such as the Root DSE).  For all applicable entries, the <TT>userPassword</TT> attribute is writable by the entry itself and by the &quot;admin&quot; entry.  It may be used for authentication/authorization purposes, but is otherwise not readable. All other attributes are writable by the entry and the &quot;admin&quot; entry, but may be read by all users (authenticated or not).</P>
+<P>Lines 12 through 14 indicate the indices to maintain for various attributes.</P>
+<P>Lines 16 through 24 specify access control for entries in this database.  As this is the first database, the controls also apply to entries not held in any database (such as the Root DSE).  For all applicable entries, the <TT>userPassword</TT> attribute is writable by the entry itself and by the &quot;admin&quot; entry.  It may be used for authentication/authorization purposes, but is otherwise not readable. All other attributes are writable by the entry and the &quot;admin&quot; entry, but may be read by all users (authenticated or not).</P>
 <P>The next section of the example configuration file defines another BDB database. This one handles queries involving the <TT>dc=example,dc=net</TT> subtree but is managed by the same entity as the first database.  Note that without line 39, the read access would be allowed due to the global access rule at line 4.</P>
 <PRE>
  33.    # BDB definition for example.net
@@ -2671,7 +3253,7 @@
 <P></P>
 <HR>
 <H1><A NAME="Running slapd">7. Running slapd</A></H1>
-<P><EM>slapd</EM>(8) is designed to be run as a stand-alone server.  This allows the server to take advantage of caching, manage concurrency issues with underlying databases, and conserve system resources.  Running from <EM>inetd</EM>(8) is <EM>NOT</EM> an option.</P>
+<P><EM>slapd</EM>(8) is designed to be run as a standalone service.  This allows the server to take advantage of caching, manage concurrency issues with underlying databases, and conserve system resources. Running from <EM>inetd</EM>(8) is <EM>NOT</EM> an option.</P>
 <H2><A NAME="Command-Line Options">7.1. Command-Line Options</A></H2>
 <P><EM>slapd</EM>(8) supports a number of command-line options as detailed in the manual page.  This section details a few commonly used options.</P>
 <PRE>
@@ -2679,13 +3261,18 @@
 </PRE>
 <P>This option specifies an alternate configuration file for slapd. The default is normally <TT>/usr/local/etc/openldap/slapd.conf</TT>.</P>
 <PRE>
+        -F &lt;slapd-config-directory&gt;
+</PRE>
+<P>Specifies the slapd configuration directory. The default is <TT>/usr/local/etc/openldap/slapd.d</TT></P>
+<P>If both <TT>-f</TT> and <TT>-F</TT> are specified, the config file will be read and converted to config directory format and written to the specified directory. If neither option is specified, slapd will attempt to read the default config directory before trying to use the default config file. If a valid config directory exists then the default config file is ignored. All of the slap tools that use the config options observe this same behavior.</P>
+<PRE>
         -h &lt;URLs&gt;
 </PRE>
-<P>This option specifies alternative listener configurations.  The default is <TT>ldap:///</TT> which implies LDAP over TCP on all interfaces on the default LDAP port 389.  You can specify specific host-port pairs or other protocol schemes (such as ldaps:// or ldapi://).  For example, <TT>-h &quot;ldaps:// ldap://127.0.0.1:666&quot;</TT> will create two listeners: one for LDAP over SSL on all interfaces on the default LDAP/SSL port 636, and one for LDAP over TCP on the <TT>localhost</TT> (<EM>loopback</EM>) interface on port 666. Hosts may be specified using IPv4 dotted-decimal form or using host names.  Port values must be numeric.</P>
+<P>This option specifies alternative listener configurations.  The default is <TT>ldap:///</TT> which implies <TERM>LDAP</TERM> over <TERM>TCP</TERM> on all interfaces on the default LDAP port 389.  You can specify specific host-port pairs or other protocol schemes (such as <TT>ldaps://</TT> or <TT>ldapi://</TT>).  For example, <TT>-h &quot;ldaps:// ldap://127.0.0.1:666&quot;</TT> will create two listeners: one for the (non-standard) <TT>ldaps://</TT> scheme on all interfaces on the default <TT>ldaps://</TT> port 636, and one for the standard <TT>ldap://</TT> scheme on the <TT>localhost</TT> (<EM>loopback</EM>) interface on port 666.  Hosts may be specified using using hostnames or <TERM>IPv4</TERM> or <TERM>IPv6</TERM> addresses.  Port values must be numeric.</P>
 <PRE>
         -n &lt;service-name&gt;
 </PRE>
-<P>This option specifies the service name used for logging and other purposes.  The default service name is <TT>slapd</TT>.</P>
+<P>This option specifies the service name used for logging and other purposes. The default service name is <TT>slapd</TT>.</P>
 <PRE>
         -l &lt;syslog-local-user&gt;
 </PRE>
@@ -2705,7 +3292,7 @@
 </PRE>
 <P>This option sets the slapd debug level to &lt;level&gt;. When level is a `?' character, the various debugging levels are printed and slapd exits, regardless of any other options you give it. Current debugging levels are</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
-<CAPTION ALIGN=top>Table 6.1: Debugging Levels</CAPTION>
+<CAPTION ALIGN=top>Table 7.1: Debugging Levels</CAPTION>
 <TR CLASS="heading">
 <TD ALIGN='Right'>
 <STRONG>Level</STRONG>
@@ -2835,11 +3422,11 @@
 <H2><A NAME="Starting slapd">7.2. Starting slapd</A></H2>
 <P>In general, slapd is run like this:</P>
 <PRE>
-        /usr/local/etc/libexec/slapd [&lt;option&gt;]*
+        /usr/local/libexec/slapd [&lt;option&gt;]*
 </PRE>
-<P>where <TT>/usr/local/etc/libexec</TT> is determined by <TT>configure</TT> and &lt;option&gt; is one of the options described above (or in <EM>slapd</EM>(8)). Unless you have specified a debugging level (including level <TT>0</TT>), slapd will automatically fork and detach itself from its controlling terminal and run in the background.</P>
+<P>where <TT>/usr/local/libexec</TT> is determined by <TT>configure</TT> and &lt;option&gt; is one of the options described above (or in <EM>slapd</EM>(8)). Unless you have specified a debugging level (including level <TT>0</TT>), slapd will automatically fork and detach itself from its controlling terminal and run in the background.</P>
 <H2><A NAME="Stopping slapd">7.3. Stopping slapd</A></H2>
-<P>To kill off slapd safely, you should give a command like this</P>
+<P>To kill off <EM>slapd</EM>(8) safely, you should give a command like this</P>
 <PRE>
         kill -INT `cat /usr/local/var/slapd.pid`
 </PRE>
@@ -2848,8 +3435,8 @@
 <P></P>
 <HR>
 <H1><A NAME="Database Creation and Maintenance Tools">8. Database Creation and Maintenance Tools</A></H1>
-<P>This section tells you how to create a slapd database from scratch, and how to do trouble shooting if you run into problems. There are two ways to create a database. First, you can create the database on-line using LDAP. With this method, you simply start up slapd and add entries using the LDAP client of your choice. This method is fine for relatively small databases (a few hundred or thousand entries, depending on your requirements). This method works for database types which support updates.</P>
-<P>The second method of database creation is to do it off-line using special utilities provided with slapd. This method is best if you have many thousands of entries to create, which would take an unacceptably long time using the LDAP method, or if you want to ensure the database is not accessed while it is being created. Note that not all database types support these utilitites.</P>
+<P>This section tells you how to create a slapd database from scratch, and how to do trouble shooting if you run into problems. There are two ways to create a database. First, you can create the database on-line using <TERM>LDAP</TERM>. With this method, you simply start up slapd and add entries using the LDAP client of your choice. This method is fine for relatively small databases (a few hundred or thousand entries, depending on your requirements). This method works for database types which support updates.</P>
+<P>The second method of database creation is to do it off-line using special utilities provided with <EM>slapd</EM>(8). This method is best if you have many thousands of entries to create, which would take an unacceptably long time using the LDAP method, or if you want to ensure the database is not accessed while it is being created. Note that not all database types support these utilities.</P>
 <H2><A NAME="Creating a database over LDAP">8.1. Creating a database over LDAP</A></H2>
 <P>With this method, you use the LDAP client of your choice (e.g., the <EM>ldapadd</EM>(1)) to add entries, just like you would once the database is created.  You should be sure to set the following options in the configuration file before starting <EM>slapd</EM>(8).</P>
 <PRE>
@@ -2953,6 +3540,10 @@
 </PRE>
 <P>Specifies the slapd configuration file that tells where to create the indices, what indices to create, etc.</P>
 <PRE>
+        -F &lt;slapdconfdirectory&gt;
+</PRE>
+<P>Specifies a config directory.  If both <TT>-f</TT> and <TT>-F</TT> are specified, the config file will be read and converted to config  directory format and written to the specified directory.  If neither option is specified, an attempt to read the default config directory will be made before trying to use the default config file. If a valid config directory exists then the default config file is ignored. If dryrun mode is also specified, no conversion will occur.</P>
+<PRE>
         -d &lt;debuglevel&gt;
 </PRE>
 <P>Turn on debugging, as specified by <TT>&lt;debuglevel&gt;</TT>. The debug levels are the same as for slapd.  See the <A HREF="#Command-Line Options">Command-Line Options</A> section in <A HREF="#Running slapd">Running slapd</A>.</P>
@@ -3050,12 +3641,451 @@
 <HR WIDTH="80%" ALIGN="Left"></P>
 <P></P>
 <HR>
-<H1><A NAME="Schema Specification">9. Schema Specification</A></H1>
-<P>This chapter describes how to extend the user schema used by <EM>slapd</EM>(8).  The chapter assumes the reader is familar with the <TERM>LDAP</TERM>/<TERM>X.500</TERM> information model.</P>
+<H1><A NAME="Backends">9. Backends</A></H1>
+<H2><A NAME="Berkeley DB Backends">9.1. Berkeley DB Backends</A></H2>
+<H3><A NAME="Overview">9.1.1. Overview</A></H3>
+<P>The <EM>bdb</EM> backend to <EM>slapd</EM>(8) is the recommended primary backend for a normal <EM>slapd</EM> database.  It uses the Oracle Berkeley DB (<TERM>BDB</TERM>) package to store data. It makes extensive use of indexing and caching (see the <A HREF="#Tuning">Tuning</A> section) to speed data access.</P>
+<P><EM>hdb</EM> is a variant of the <EM>bdb</EM> backend that uses a hierarchical database layout which supports subtree renames. It is otherwise identical to the <EM>bdb</EM> behavior, and all the same configuration options apply.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>An <EM>hdb</EM> database needs a large <EM>idlcachesize</EM> for good search performance, typically three times the <EM>cachesize</EM> (entry cache size) or larger.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<H3><A NAME="back-bdb/back-hdb Configuration">9.1.2. back-bdb/back-hdb Configuration</A></H3>
+<P>MORE LATER</P>
+<H3><A NAME="Further Information">9.1.3. Further Information</A></H3>
+<P><EM>slapd-bdb</EM>(5)</P>
+<H2><A NAME="LDAP">9.2. LDAP</A></H2>
+<H3><A NAME="Overview">9.2.1. Overview</A></H3>
+<P>The LDAP backend to <EM>slapd</EM>(8) is not an actual database; instead it acts as a proxy to forward incoming requests to another LDAP server. While processing requests it will also chase referrals, so that referrals are fully processed instead of being returned to the <EM>slapd</EM> client.</P>
+<P>Sessions that explicitly <EM>Bind</EM> to the <EM>back-ldap</EM> database always create their own private connection to the remote LDAP server. Anonymous sessions will share a single anonymous connection to the remote server. For sessions bound through other mechanisms, all sessions with the same DN will share the same connection. This connection pooling strategy can enhance the proxy’s efficiency by reducing the overhead of repeatedly making/breaking multiple connections.</P>
+<P>The ldap database can also act as an information service, i.e. the identity of locally authenticated clients is asserted to the remote server, possibly in some modified form. For this purpose, the proxy binds to the remote server with some administrative identity, and, if required, authorizes the asserted identity.</P>
+<H3><A NAME="back-ldap Configuration">9.2.2. back-ldap Configuration</A></H3>
+<P>LATER</P>
+<H3><A NAME="Further Information">9.2.3. Further Information</A></H3>
+<P><EM>slapd-ldap</EM>(5)</P>
+<H2><A NAME="LDIF">9.3. LDIF</A></H2>
+<H3><A NAME="Overview">9.3.1. Overview</A></H3>
+<P>The LDIF backend to <EM>slapd</EM>(8) is a basic storage backend that stores entries in text files in LDIF format, and exploits the filesystem to create the tree structure of the database. It is intended as a cheap, low performance easy to use backend.</P>
+<P>When using the <EM>cn=config</EM> dynamic configuration database with persistent storage, the configuration data is stored using this backend. See <EM>slapd-config</EM>(5) for more information</P>
+<H3><A NAME="back-ldif Configuration">9.3.2. back-ldif Configuration</A></H3>
+<P>LATER</P>
+<H3><A NAME="Further Information">9.3.3. Further Information</A></H3>
+<P><EM>slapd-ldif</EM>(5)</P>
+<H2><A NAME="Metadirectory">9.4. Metadirectory</A></H2>
+<H3><A NAME="Overview">9.4.1. Overview</A></H3>
+<P>The meta backend to <EM>slapd</EM>(8) performs basic LDAP proxying with respect to a set of remote LDAP servers, called &quot;targets&quot;. The information contained in these servers can be presented as belonging to a single Directory Information Tree (<TERM>DIT</TERM>).</P>
+<P>A basic knowledge of the functionality of the <EM>slapd-ldap</EM>(5) backend is recommended. This backend has been designed as an enhancement of the ldap backend. The two backends share many features (actually they also share portions of code). While the ldap backend is intended to proxy operations directed to a single server, the meta backend is mainly intended for proxying of multiple servers and possibly naming context  masquerading.</P>
+<P>These features, although useful in many scenarios, may result in excessive overhead for some applications, so its use should be carefully considered.</P>
+<H3><A NAME="back-meta Configuration">9.4.2. back-meta Configuration</A></H3>
+<P>LATER</P>
+<H3><A NAME="Further Information">9.4.3. Further Information</A></H3>
+<P><EM>slapd-meta</EM>(5)</P>
+<H2><A NAME="Monitor">9.5. Monitor</A></H2>
+<H3><A NAME="Overview">9.5.1. Overview</A></H3>
+<P>The monitor backend to <EM>slapd</EM>(8) is not an actual database; if enabled, it is automatically generated and dynamically maintained by slapd with information about the running status of the daemon.</P>
+<P>To inspect all monitor information, issue a subtree search with base <EM>cn=Monitor</EM>, requesting that attributes &quot;+&quot; and &quot;*&quot; are returned. The monitor backend produces mostly operational attributes, and LDAP only returns operational attributes that are explicitly requested.  Requesting attribute &quot;+&quot; is an extension which requests all operational attributes.</P>
+<P>See the <A HREF="#Monitoring">Monitoring</A> section.</P>
+<H3><A NAME="back-monitor Configuration">9.5.2. back-monitor Configuration</A></H3>
+<P>LATER</P>
+<H3><A NAME="Further Information">9.5.3. Further Information</A></H3>
+<P><EM>slapd-monitor</EM>(5)</P>
+<H2><A NAME="Null">9.6. Null</A></H2>
+<H3><A NAME="Overview">9.6.1. Overview</A></H3>
+<P>The Null backend to <EM>slapd</EM>(8) is surely the most useful part of slapd:</P>
+<UL>
+<LI>Searches return success but no entries.
+<LI>Compares return compareFalse.
+<LI>Updates return success (unless readonly is on) but do nothing.
+<LI>Binds other than as the rootdn fail unless the database option &quot;bind on&quot; is given.
+<LI>The slapadd(8) and slapcat(8) tools are equally exciting.</UL>
+<P>Inspired by the <TT>/dev/null</TT> device.</P>
+<H3><A NAME="back-null Configuration">9.6.2. back-null Configuration</A></H3>
+<P>LATER</P>
+<H3><A NAME="Further Information">9.6.3. Further Information</A></H3>
+<P><EM>slapd-null</EM>(5)</P>
+<H2><A NAME="Passwd">9.7. Passwd</A></H2>
+<H3><A NAME="Overview">9.7.1. Overview</A></H3>
+<P>The PASSWD backend to <EM>slapd</EM>(8) serves up the user account information listed in the system <EM>passwd</EM>(5) file.</P>
+<P>This backend is provided for demonstration purposes only. The DN of each entry is &quot;uid=&lt;username&gt;,&lt;suffix&gt;&quot;.</P>
+<H3><A NAME="back-passwd Configuration">9.7.2. back-passwd Configuration</A></H3>
+<P>LATER</P>
+<H3><A NAME="Further Information">9.7.3. Further Information</A></H3>
+<P><EM>slapd-passwd</EM>(5)</P>
+<H2><A NAME="Perl/Shell">9.8. Perl/Shell</A></H2>
+<H3><A NAME="Overview">9.8.1. Overview</A></H3>
+<P>The Perl backend to <EM>slapd</EM>(8) works by embedding a <EM>perl</EM>(1) interpreter into <EM>slapd</EM>(8). Any perl database section of the configuration file <EM>slapd.conf</EM>(5) must then specify what Perl module to use. Slapd then creates a new Perl object that handles all the requests for that particular instance of the backend.</P>
+<P>The Shell backend to <EM>slapd</EM>(8) executes external programs to implement operations, and is designed to make it easy to tie an existing database to the slapd front-end. This backend is is primarily intended to be used in prototypes.</P>
+<H3><A NAME="back-perl/back-shell Configuration">9.8.2. back-perl/back-shell Configuration</A></H3>
+<P>LATER</P>
+<H3><A NAME="Further Information">9.8.3. Further Information</A></H3>
+<P><EM>slapd-shell</EM>(5) and <EM>slapd-perl</EM>(5)</P>
+<H2><A NAME="Relay">9.9. Relay</A></H2>
+<H3><A NAME="Overview">9.9.1. Overview</A></H3>
+<P>The primary purpose of this <EM>slapd</EM>(8) backend is to map a naming context defined in a database running in the same <EM>slapd</EM>(8) instance into a virtual naming context, with attributeType and objectClass manipulation, if required. It requires the rwm overlay.</P>
+<P>This backend and the above mentioned overlay are experimental.</P>
+<H3><A NAME="back-relay Configuration">9.9.2. back-relay Configuration</A></H3>
+<P>LATER</P>
+<H3><A NAME="Further Information">9.9.3. Further Information</A></H3>
+<P><EM>slapd-relay</EM>(5)</P>
+<H2><A NAME="SQL">9.10. SQL</A></H2>
+<H3><A NAME="Overview">9.10.1. Overview</A></H3>
+<P>The primary purpose of this <EM>slapd</EM>(8) backend is to PRESENT information stored in some RDBMS as an LDAP subtree without any programming (some SQL and maybe stored procedures can’t be considered programming, anyway ;).</P>
+<P>That is, for example, when you (some ISP) have account information you use in an RDBMS, and want to use modern solutions that expect such information in LDAP (to authenticate users, make email lookups etc.). Or you want to synchronize or distribute information between different sites/applications that use RDBMSes and/or LDAP. Or whatever else...</P>
+<P>It is <B>NOT</B> designed as a general-purpose backend that uses RDBMS instead of BerkeleyDB (as the standard BDB backend does), though it can be used as such with several limitations. Please see <A HREF="#LDAP vs RDBMS">LDAP vs RDBMS</A> for discussion.</P>
+<P>The idea is to use some meta-information to translate LDAP queries to SQL queries, leaving relational schema untouched, so that old applications can continue using it without any modifications. This allows SQL and LDAP applications to interoperate without replication, and exchange data as needed.</P>
+<P>The SQL backend is designed to be tunable to virtually any relational schema without having to change source (through that meta-information mentioned). Also, it uses ODBC to connect to RDBMSes, and is highly configurable for SQL dialects RDBMSes may use, so it may be used for integration and distribution of data on different RDBMSes, OSes, hosts etc., in other words, in highly heterogeneous environment.</P>
+<P>This backend is experimental.</P>
+<H3><A NAME="back-sql Configuration">9.10.2. back-sql Configuration</A></H3>
+<P>LATER</P>
+<H3><A NAME="Further Information">9.10.3. Further Information</A></H3>
+<P><EM>slapd-sql</EM>(5)</P>
+<P></P>
+<HR>
+<H1><A NAME="Overlays">10. Overlays</A></H1>
+<P>Overlays are software components that provide hooks to functions analogous to those provided by backends, which can be stacked on top of the backend calls and as callbacks on top of backend responses to alter their behavior.</P>
+<P>Overlays may be compiled statically into slapd, or when module support is enabled, they may be dynamically loaded. Most of the overlays are only allowed to be configured on individual databases, but some may also be configured globally.</P>
+<P>Essentially they represent a means to:</P>
+<UL>
+<LI>customize the behavior of existing backends without changing the backend code and without requiring one to write a new custom backend with complete functionality
+<LI>write functionality of general usefulness that can be applied to different backend types</UL>
+<P>Overlays are usually documented by separate specific man pages in section 5; the naming convention is</P>
+<PRE>
+        slapo-&lt;overlay name&gt;
+</PRE>
+<P>Not all distributed overlays have a man page yet. Feel free to contribute one, if you think you well understood the behavior of the component and the implications of all the related configuration directives.</P>
+<P>Official overlays are located in</P>
+<PRE>
+        servers/slapd/overlays/
+</PRE>
+<P>That directory also contains the file slapover.txt, which describes the rationale of the overlay implementation, and may serve as guideline for the development of custom overlays.</P>
+<P>Contribware overlays are located in</P>
+<PRE>
+        contrib/slapd-modules/&lt;overlay name&gt;/
+</PRE>
+<P>along with other types of run-time loadable components; they are officially distributed, but not maintained by the project.</P>
+<P>They can be stacked on the frontend as well; this means that they can be executed after a request is parsed and validated, but right before the appropriate database is selected. The main purpose is to affect operations regardless of the database they will be handled by, and, in some cases, to influence the selection of the database by massaging the request DN.</P>
+<P>All the current overlays in 2.4 are listed and described in detail in the following sections.</P>
+<H2><A NAME="Access Logging">10.1. Access Logging</A></H2>
+<H3><A NAME="Overview">10.1.1. Overview</A></H3>
+<P>This overlay can record accesses to a given backend database on another database.</P>
+<H3><A NAME="Access Logging Configuration">10.1.2. Access Logging Configuration</A></H3>
+<H2><A NAME="Audit Logging">10.2. Audit Logging</A></H2>
+<P>This overlay records changes on a given backend database to an LDIF log file.</P>
+<H3><A NAME="Overview">10.2.1. Overview</A></H3>
+<H3><A NAME="Audit Logging Configuration">10.2.2. Audit Logging Configuration</A></H3>
+<H2><A NAME="Chaining">10.3. Chaining</A></H2>
+<H3><A NAME="Overview">10.3.1. Overview</A></H3>
+<P>The chain overlay provides basic chaining capability to the underlying database.</P>
+<P>What is chaining? It indicates the capability of a DSA to follow referrals on behalf of the client, so that distributed systems are viewed as a single virtual DSA by clients that are otherwise unable to &quot;chase&quot; (i.e. follow) referrals by themselves.</P>
+<P>The chain overlay is built on top of the ldap backend; it is compiled by default when --enable-ldap.</P>
+<H3><A NAME="Chaining Configuration">10.3.2. Chaining Configuration</A></H3>
+<P>In order to demonstrate how this overlay works, we shall discuss a typical scenario which might be one master server and three Syncrepl slaves.</P>
+<P>On each replica, add this near the top of the file (global), before any database definitions:</P>
+<PRE>
+        overlay                    chain
+        chain-uri                  &quot;ldap://ldapmaster.example.com&quot;
+        chain-idassert-bind        bindmethod=&quot;simple&quot;
+                                   binddn=&quot;cn=Manager,dc=example,dc=com&quot;
+                                   credentials=&quot;&lt;secret&gt;&quot;
+                                   mode=&quot;self&quot;
+        chain-tls                  start
+        chain-return-error         TRUE
+</PRE>
+<P>Add this below your <EM>syncrepl</EM> statement:</P>
+<PRE>
+        updateref                  &quot;ldap://ldapmaster.example.com/&quot;
+</PRE>
+<P>The <B>chain-tls</B> statement enables TLS from the slave to the ldap master. The DITs are exactly the same between these machines, therefore whatever user bound to the slave will also exist on the master. If that DN does not have update privileges on the master, nothing will happen.</P>
+<P>You will need to restart the slave after these changes. Then, if you are using <EM>loglevel 256</EM>, you can monitor an <EM>ldapmodify</EM> on the slave and the master.</P>
+<P>Now start an <EM>ldapmodify</EM> on the slave and watch the logs. You should expect something like:</P>
+<PRE>
+        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 fd=31 ACCEPT from IP=143.199.102.216:45181 (IP=143.199.102.216:389)
+        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 op=0 STARTTLS
+        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 op=0 RESULT oid= err=0 text=
+        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 fd=31 TLS established tls_ssf=256 ssf=256
+        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=1 BIND dn=&quot;uid=user1,ou=people,dc=example,dc=com&quot; method=128
+        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=1 BIND dn=&quot;uid=user1,ou=People,dc=example,dc=com&quot; mech=SIMPLE ssf=0
+        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=1 RESULT tag=97 err=0 text=
+        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=2 MOD dn=&quot;uid=user1,ou=People,dc=example,dc=com&quot;
+        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=2 MOD attr=mail
+        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=2 RESULT tag=103 err=0 text=
+        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=3 UNBIND
+        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 fd=31 closed
+        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: LDAP_RES_SEARCH_ENTRY(LDAP_SYNC_MODIFY)
+        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: be_search (0)
+        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: uid=user1,ou=People,dc=example,dc=com
+        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: be_modify (0)
+</PRE>
+<P>And on the master you will see this:</P>
+<PRE>
+        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 PROXYAUTHZ dn=&quot;uid=user1,ou=people,dc=example,dc=com&quot;
+        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 MOD dn=&quot;uid=user1,ou=People,dc=example,dc=com&quot;
+        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 MOD attr=mail
+        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 RESULT tag=103 err=0 text=
+</PRE>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>You can clearly see the PROXYAUTHZ line on the master, indicating the proper identity assertion for the update on the master. Also note the slave immediately receiving the Syncrepl update from the master.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<H3><A NAME="Handling Chaining Errors">10.3.3. Handling Chaining Errors</A></H3>
+<P>By default, if chaining fails, the original referral is returned to the client under the assumption that the client might want to try and follow the referral.</P>
+<P>With the following directive however, if the chaining fails at the provider side, the actual error is returned to the client.</P>
+<PRE>
+        chain-return-error TRUE
+</PRE>
+<H2><A NAME="Constraints">10.4. Constraints</A></H2>
+<H3><A NAME="Overview">10.4.1. Overview</A></H3>
+<P>This overlay enforces a regular expression constraint on all values of specified attributes. It is used to enforce a more rigorous syntax when the underlying attribute syntax is too general.</P>
+<H3><A NAME="Constraint Configuration">10.4.2. Constraint Configuration</A></H3>
+<H2><A NAME="Dynamic Directory Services">10.5. Dynamic Directory Services</A></H2>
+<H3><A NAME="Overview">10.5.1. Overview</A></H3>
+<P>This overlay supports dynamic objects, which have a limited life after which they expire and are automatically deleted.</P>
+<H3><A NAME="Dynamic Directory Service Configuration">10.5.2. Dynamic Directory Service Configuration</A></H3>
+<H2><A NAME="Dynamic Groups">10.6. Dynamic Groups</A></H2>
+<H3><A NAME="Overview">10.6.1. Overview</A></H3>
+<P>This overlay extends the Compare operation to detect members of a dynamic group. This overlay is now deprecated as all of its functions are available using the <A HREF="#Dynamic Lists">Dynamic Lists</A> overlay.</P>
+<H3><A NAME="Dynamic Group Configuration">10.6.2. Dynamic Group Configuration</A></H3>
+<H2><A NAME="Dynamic Lists">10.7. Dynamic Lists</A></H2>
+<H3><A NAME="Overview">10.7.1. Overview</A></H3>
+<P>This overlay allows expansion of dynamic groups and lists. Instead of having the group members or list attributes hard coded, this overlay allows us to define an LDAP search whose results will make up the group or list.</P>
+<H3><A NAME="Dynamic List Configuration">10.7.2. Dynamic List Configuration</A></H3>
+<P>This module can behave both as a dynamic list and dynamic group, depending on the configuration. The syntax is as follows:</P>
+<PRE>
+       overlay dynlist
+       dynlist-attrset &lt;group-oc&gt; &lt;URL-ad&gt; [member-ad]
+</PRE>
+<P>The parameters to the <TT>dynlist-attrset</TT> directive have the following meaning:</P>
+<UL>
+<LI><TT>&lt;group-oc&gt;</TT>: specifies which object class triggers the subsequent LDAP search. Whenever an entry with this object class is retrieved, the search is performed.
+<LI><TT>&lt;URL-ad&gt;</TT>: is the name of the attribute which holds the search URI. It has to be a subtype of <TT>labeledURI</TT>. The attributes and values present in the search result are added to the entry unless <TT>member-ad</TT> is used (see below).
+<LI><TT>member-ad</TT>: if present, changes the overlay behaviour into a dynamic group. Instead of inserting the results of the search in the entry, the distinguished name of the results are added as values of this attribute.</UL>
+<P>Here is an example which will allow us to have an email alias which automatically expands to all user's emails according to our LDAP filter:</P>
+<P>In <EM>slapd.conf</EM>(5):</P>
+<PRE>
+       overlay dynlist
+       dynlist-attrset nisMailAlias labeledURI
+</PRE>
+<P>This means that whenever an entry which has the <TT>nisMailAlias</TT> object class is retrieved, the search specified in the <TT>labeledURI</TT> attribute is performed.</P>
+<P>Let's say we have this entry in our directory:</P>
+<PRE>
+       cn=all,ou=aliases,dc=example,dc=com
+       cn: all
+       objectClass: nisMailAlias
+       labeledURI: ldap:///ou=People,dc=example,dc=com?mail?one?(objectClass=inetOrgPerson)
+</PRE>
+<P>If this entry is retrieved, the search specified in <TT>labeledURI</TT> will be performed and the results will be added to the entry just as if they have always been there. In this case, the search filter selects all entries directly under <TT>ou=People</TT> that have the <TT>inetOrgPerson</TT> object class and retrieves the <TT>mail</TT> attribute, if it exists.</P>
+<P>This is what gets added to the entry when we have two users under <TT>ou=People</TT> that match the filter:</P>
+<P><CENTER><IMG SRC="allmail-en.png" ALIGN="center"></CENTER></P>
+<P ALIGN="Center">Figure X.Y: Dynamic List for all emails</P>
+<P>The configuration for a dynamic group is similar. Let's see an example which would automatically populate an <TT>allusers</TT> group with all the user accounts in the directory.</P>
+<P>In <TT>slapd.conf</TT>(5):</P>
+<PRE>
+       overlay dynlist
+       dynlist-attrset groupOfNames labeledURI member
+</PRE>
+<P>Let's apply it to the following entry:</P>
+<PRE>
+       cn=allusers,ou=group,dc=example,dc=com
+       cn: all
+       objectClass: groupOfNames
+       labeledURI: ldap:///ou=people,dc=example,dc=com??one?(objectClass=inetOrgPerson)
+</PRE>
+<P>The behaviour is similar to the dynamic list configuration we had before: whenever an entry with the <TT>groupOfNames</TT> object class is retrieved, the search specified in the <TT>labeledURI</TT> attribute is performed. But this time, only the distinguished names of the results are added, and as values of the <TT>member</TT> attribute.</P>
+<P>This is what we get:</P>
+<P><CENTER><IMG SRC="allusersgroup-en.png" ALIGN="center"></CENTER></P>
+<P ALIGN="Center">Figure X.Y: Dynamic Group for all users</P>
+<P>Note that a side effect of this scheme of dymamic groups is that the members need to be specified as full DNs. So, if you are planning in using this for <TT>posixGroup</TT>s, be sure to use RFC2307bis and some attribute which can hold distinguished names. The <TT>memberUid</TT> attribute used in the <TT>posixGroup</TT> object class can hold only names, not DNs, and is therefore not suitable for dynamic groups.</P>
+<H2><A NAME="Reverse Group Membership Maintenance">10.8. Reverse Group Membership Maintenance</A></H2>
+<H3><A NAME="Overview">10.8.1. Overview</A></H3>
+<P>In some scenarios, it may be desirable for a client to be able to determine which groups an entry is a member of, without performing an additional search. Examples of this are applications using the <TERM>DIT</TERM> for access control based on group authorization.</P>
+<P>The <B>memberof</B> overlay updates an attribute (by default <B>memberOf</B>) whenever changes occur to the membership attribute (by default <B>member</B>) of entries of the objectclass (by default <B>groupOfNames</B>) configured to trigger updates.</P>
+<P>Thus, it provides maintenance of the list of groups an entry is a member of, when usual maintenance of groups is done by modifying the members on the group entry.</P>
+<H3><A NAME="Member Of Configuration">10.8.2. Member Of Configuration</A></H3>
+<P>The typical use of this overlay requires just enabling the overlay for a specific database. For example, with the following minimal slapd.conf:</P>
+<PRE>
+        include /usr/share/openldap/schema/core.schema
+        include /usr/share/openldap/schema/cosine.schema
+        modulepath      /usr/lib/openldap
+        moduleload      memberof.la
+        authz-regexp &quot;gidNumber=0\\\+uidNumber=0,cn=peercred,cn=external,cn=auth&quot;
+                &quot;cn=Manager,dc=example,dc=com&quot;
+        database        bdb
+        suffix          &quot;dc=example,dc=com&quot;
+        rootdn          &quot;cn=Manager,dc=example,dc=com&quot;
+        rootpw          secret
+        directory       /var/lib/ldap2.4
+        checkpoint 256 5
+        index   objectClass   eq
+        index   uid           eq,sub
+
+        overlay memberof
+</PRE>
+<P>adding the following ldif:</P>
+<PRE>
+        cat memberof.ldif
+        dn: dc=example,dc=com
+        objectclass: domain
+        dc: example
+
+        dn: ou=Group,dc=example,dc=com
+        objectclass: organizationalUnit
+        ou: Group
+
+        dn: ou=People,dc=example,dc=com
+        objectclass: organizationalUnit
+        ou: People
+
+        dn: uid=test1,ou=People,dc=example,dc=com
+        objectclass: account
+        uid: test1
+
+        dn: cn=testgroup,ou=Group,dc=example,dc=com
+        objectclass: groupOfNames
+        cn: testgroup
+        member: uid=test1,ou=People,dc=example,dc=com
+</PRE>
+<P>Results in the following output from a search on the test1 user:</P>
+<PRE>
+ # ldapsearch -LL -Y EXTERNAL -H ldapi:/// &quot;(uid=test1)&quot; -b dc=example,dc=com memberOf
+ SASL/EXTERNAL authentication started
+ SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
+ SASL SSF: 0
+ version: 1
+
+ dn: uid=test1,ou=People,dc=example,dc=com
+ memberOf: cn=testgroup,ou=Group,dc=example,dc=com
+</PRE>
+<P>Note that the <B>memberOf</B> attribute is an operational attribute, so it must be requested explicitly.</P>
+<H2><A NAME="The Proxy Cache Engine">10.9. The Proxy Cache Engine</A></H2>
+<P><TERM>LDAP</TERM> servers typically hold one or more subtrees of a <TERM>DIT</TERM>. Replica (or shadow) servers hold shadow copies of entries held by one or more master servers.  Changes are propagated from the master server to replica (slave) servers using LDAP Sync replication.  An LDAP cache is a special type of replica which holds entries corresponding to search filters instead of subtrees.</P>
+<H3><A NAME="Overview">10.9.1. Overview</A></H3>
+<P>The proxy cache extension of slapd is designed to improve the responsiveness of the ldap and meta backends. It handles a search request (query) by first determining whether it is contained in any cached search filter. Contained requests are answered from the proxy cache's local database. Other requests are passed on to the underlying ldap or meta backend and processed as usual.</P>
+<P>E.g. <TT>(shoesize&gt;=9)</TT> is contained in <TT>(shoesize&gt;=8)</TT> and <TT>(sn=Richardson)</TT> is contained in <TT>(sn=Richards*)</TT></P>
+<P>Correct matching rules and syntaxes are used while comparing assertions for query containment. To simplify the query containment problem, a list of cacheable &quot;templates&quot; (defined below) is specified at configuration time. A query is cached or answered only if it belongs to one of these templates. The entries corresponding to cached queries are stored in the proxy cache local database while its associated meta information (filter, scope, base, attributes) is stored in main memory.</P>
+<P>A template is a prototype for generating LDAP search requests. Templates are described by a prototype search filter and a list of attributes which are required in queries generated from the template. The representation for prototype filter is similar to <A HREF="http://www.rfc-editor.org/rfc/rfc4515.txt">RFC4515</A>, except that the assertion values are missing. Examples of prototype filters are: (sn=),(&amp;(sn=)(givenname=)) which are instantiated by search filters (sn=Doe) and (&amp;(sn=Doe)(givenname=John)) respectively.</P>
+<P>The cache replacement policy removes the least recently used (LRU) query and entries belonging to only that query. Queries are allowed a maximum time to live (TTL) in the cache thus providing weak consistency. A background task periodically checks the cache for expired queries and removes them.</P>
+<P>The Proxy Cache paper (<A HREF="http://www.openldap.org/pub/kapurva/proxycaching.pdf">http://www.openldap.org/pub/kapurva/proxycaching.pdf</A>) provides design and implementation details.</P>
+<H3><A NAME="Proxy Cache Configuration">10.9.2. Proxy Cache Configuration</A></H3>
+<P>The cache configuration specific directives described below must appear after a <TT>overlay proxycache</TT> directive within a <TT>&quot;database meta&quot;</TT> or <TT>database ldap</TT> section of the server's <EM>slapd.conf</EM>(5) file.</P>
+<H4><A NAME="Setting cache parameters">10.9.2.1. Setting cache parameters</A></H4>
+<PRE>
+ proxyCache &lt;DB&gt; &lt;maxentries&gt; &lt;nattrsets&gt; &lt;entrylimit&gt; &lt;period&gt;
+</PRE>
+<P>This directive enables proxy caching and sets general cache parameters.  The &lt;DB&gt; parameter specifies which underlying database is to be used to hold cached entries.  It should be set to <TT>bdb</TT> or <TT>hdb</TT>.  The &lt;maxentries&gt; parameter specifies the total number of entries which may be held in the cache.  The &lt;nattrsets&gt; parameter specifies the total number of attribute sets (as specified by the <TT>proxyAttrSet</TT> directive) that may be defined.  The &lt;entrylimit&gt; parameter specifies the maximum number of entries in a cacheable query.  The &lt;period&gt; specifies the consistency check period (in seconds).  In each period, queries with expired TTLs are removed.</P>
+<H4><A NAME="Defining attribute sets">10.9.2.2. Defining attribute sets</A></H4>
+<PRE>
+ proxyAttrset &lt;index&gt; &lt;attrs...&gt;
+</PRE>
+<P>Used to associate a set of attributes to an index. Each attribute set is associated with an index number from 0 to &lt;numattrsets&gt;-1. These indices are used by the proxyTemplate directive to define cacheable templates.</P>
+<H4><A NAME="Specifying cacheable templates">10.9.2.3. Specifying cacheable templates</A></H4>
+<PRE>
+ proxyTemplate &lt;prototype_string&gt; &lt;attrset_index&gt; &lt;TTL&gt;
+</PRE>
+<P>Specifies a cacheable template and the &quot;time to live&quot; (in sec) &lt;TTL&gt; for queries belonging to the template. A template is described by its prototype filter string and set of required attributes identified by &lt;attrset_index&gt;.</P>
+<H4><A NAME="Example">10.9.2.4. Example</A></H4>
+<P>An example <EM>slapd.conf</EM>(5) database section for a caching server which proxies for the <TT>&quot;dc=example,dc=com&quot;</TT> subtree held at server <TT>ldap.example.com</TT>.</P>
+<PRE>
+        database        ldap
+        suffix          &quot;dc=example,dc=com&quot;
+        rootdn          &quot;dc=example,dc=com&quot;
+        uri             ldap://ldap.example.com/
+        overlay proxycache
+        proxycache    bdb 100000 1 1000 100
+        proxyAttrset  0 mail postaladdress telephonenumber
+        proxyTemplate (sn=) 0 3600
+        proxyTemplate (&amp;(sn=)(givenName=)) 0 3600
+        proxyTemplate (&amp;(departmentNumber=)(secretary=*)) 0 3600
+
+        cachesize 20
+        directory ./testrun/db.2.a
+        index       objectClass eq
+        index       cn,sn,uid,mail  pres,eq,sub
+</PRE>
+<H5><A NAME="Cacheable Queries">10.9.2.4.1. Cacheable Queries</A></H5>
+<P>A LDAP search query is cacheable when its filter matches one of the templates as defined in the &quot;proxyTemplate&quot; statements and when it references only the attributes specified in the corresponding attribute set. In the example above the attribute set number 0 defines that only the attributes: <TT>mail postaladdress telephonenumber</TT> are cached for the following proxyTemplates.</P>
+<H5><A NAME="Examples:">10.9.2.4.2. Examples:</A></H5>
+<PRE>
+        Filter: (&amp;(sn=Richard*)(givenName=jack))
+        Attrs: mail telephoneNumber
+</PRE>
+<P>is cacheable, because it matches the template <TT>(&amp;(sn=)(givenName=))</TT> and its attributes are contained in proxyAttrset 0.</P>
+<PRE>
+        Filter: (&amp;(sn=Richard*)(telephoneNumber))
+        Attrs: givenName
+</PRE>
+<P>is not cacheable, because the filter does not match the template, nor is the attribute givenName stored in the cache</P>
+<PRE>
+        Filter: (|(sn=Richard*)(givenName=jack))
+        Attrs: mail telephoneNumber
+</PRE>
+<P>is not cacheable, because the filter does not match the template ( logical OR &quot;|&quot; condition instead of logical AND &quot;&amp;&quot; )</P>
+<H2><A NAME="Password Policies">10.10. Password Policies</A></H2>
+<H3><A NAME="Overview">10.10.1. Overview</A></H3>
+<P>This overlay provides a variety of password control mechanisms, e.g. password aging, password reuse and duplication control, mandatory password resets, etc.</P>
+<H3><A NAME="Password Policy Configuration">10.10.2. Password Policy Configuration</A></H3>
+<H2><A NAME="Referential Integrity">10.11. Referential Integrity</A></H2>
+<H3><A NAME="Overview">10.11.1. Overview</A></H3>
+<P>This overlay can be used with a backend database such as slapd-bdb(5) to maintain the cohesiveness of a schema which utilizes reference attributes.</P>
+<P>Whenever a <EM>modrdn</EM> or <EM>delete</EM> is performed, that is, when an entry's DN is renamed or an entry is removed, the server will search the directory for references to this DN (in selected attributes: see below) and update them accordingly. If it was a <EM>delete</EM> operation, the reference is deleted. If it was a <EM>modrdn</EM> operation, then the reference is updated with the new DN.</P>
+<P>For example, a very common administration task is to maintain group membership lists, specially when users are removed from the directory. When an user account is deleted or renamed, all groups this user is a member of have to be updated. LDAP administrators usually have scripts for that. But we can use the <TT>refint</TT> overlay to automate this task. In this example, if the user is removed from the directory, the overlay will take care to remove the user from all the groups he/she was a member of. No more scripting for this.</P>
+<H3><A NAME="Referential Integrity Configuration">10.11.2. Referential Integrity Configuration</A></H3>
+<P>The configuration for this overlay is as follows:</P>
+<PRE>
+       overlay refint
+       refint_attributes &lt;attribute [attribute ...]&gt;
+       refint_nothing &lt;string&gt;
+</PRE>
+<UL>
+<LI><TT>refint_attributes</TT>: this parameter specifies a space separated list of attributes which will have the referential integrity maintained. When an entry is removed or has its DN renamed, the server will do an internal search for any of the <TT>refint_attributes</TT> that point to the affected DN and update them accordingly. IMPORTANT: the attributes listed here must have the <TT>distinguishedName</TT> syntax, that is, hold DNs as values.
+<LI><TT>refint_nothing</TT>: some times, while trying to maintain the referential integrity, the server has to remove the last attribute of its kind from an entry. This may be prohibited by the schema: for example, the <TT>groupOfNames</TT> object class requires at least one member. In these cases, the server will add the attribute value specified in <TT>refint_nothing</TT> to the entry.</UL>
+<P>To illustrate this overlay, we will use the group membership scenario.</P>
+<P>In <TT>slapd.conf</TT>:</P>
+<PRE>
+       overlay refint
+       refint_attributes member
+       refint_nothing &quot;cn=admin,dc=example,dc=com&quot;
+</PRE>
+<P>This configuration tells the overlay to maintain the referential integrity of the <TT>member</TT> attribute. This attribute is used in the <TT>groupOfNames</TT> object class which always needs a member, so we add the <TT>refint_nothing</TT> directive to fill in the group with a standard member should all the members vanish.</P>
+<P>If we have the following group membership, the refint overlay will automatically remove <TT>john</TT> from the group if his entry is removed from the directory:</P>
+<P><CENTER><IMG SRC="refint.png" ALIGN="center"></CENTER></P>
+<P ALIGN="Center">Figure X.Y: Maintaining referential integrity in groups</P>
+<P>Notice that if we rename (<TT>modrdn</TT>) the <TT>john</TT> entry to, say, <TT>jsmith</TT>, the refint overlay will also rename the reference in the <TT>member</TT> attribute, so the group membership stays correct.</P>
+<P>If we removed all users from the directory who are a member of this group, then the end result would be a single member in the group: <TT>cn=admin,dc=example,dc=com</TT>. This is the <TT>refint_nothing</TT> parameter kicking into action so that the schema is not violated.</P>
+<H2><A NAME="Return Code">10.12. Return Code</A></H2>
+<H3><A NAME="Overview">10.12.1. Overview</A></H3>
+<P>This overlay is useful to test the behavior of clients when server-generated erroneous and/or unusual responses occur.</P>
+<H3><A NAME="Return Code Configuration">10.12.2. Return Code Configuration</A></H3>
+<H2><A NAME="Rewrite/Remap">10.13. Rewrite/Remap</A></H2>
+<H3><A NAME="Overview">10.13.1. Overview</A></H3>
+<P>It performs basic DN/data rewrite and objectClass/attributeType mapping.</P>
+<H3><A NAME="Rewrite/Remap Configuration">10.13.2. Rewrite/Remap Configuration</A></H3>
+<H2><A NAME="Sync Provider">10.14. Sync Provider</A></H2>
+<H3><A NAME="Overview">10.14.1. Overview</A></H3>
+<P>This overlay implements the provider-side support for syncrepl replication, including persistent search functionality</P>
+<H3><A NAME="Sync Provider Configuration">10.14.2. Sync Provider Configuration</A></H3>
+<H2><A NAME="Translucent Proxy">10.15. Translucent Proxy</A></H2>
+<H3><A NAME="Overview">10.15.1. Overview</A></H3>
+<P>This overlay can be used with a backend database such as slapd-bdb (5) to create a &quot;translucent proxy&quot;.</P>
+<P>Content of entries retrieved from a remote LDAP server can be partially overridden by the database.</P>
+<H3><A NAME="Translucent Proxy Configuration">10.15.2. Translucent Proxy Configuration</A></H3>
+<H2><A NAME="Attribute Uniqueness">10.16. Attribute Uniqueness</A></H2>
+<H3><A NAME="Overview">10.16.1. Overview</A></H3>
+<P>This overlay can be used with a backend database such as slapd-bdb (5) to enforce the uniqueness of some or all attributes within a subtree.</P>
+<H3><A NAME="Attribute Uniqueness Configuration">10.16.2. Attribute Uniqueness Configuration</A></H3>
+<H2><A NAME="Value Sorting">10.17. Value Sorting</A></H2>
+<H3><A NAME="Overview">10.17.1. Overview</A></H3>
+<P>This overlay can be used to enforce a specific order for the values of an attribute when it is returned in a search.</P>
+<H3><A NAME="Value Sorting Configuration">10.17.2. Value Sorting Configuration</A></H3>
+<H2><A NAME="Overlay Stacking">10.18. Overlay Stacking</A></H2>
+<H3><A NAME="Overview">10.18.1. Overview</A></H3>
+<H3><A NAME="Example Scenarios">10.18.2. Example Scenarios</A></H3>
+<H4><A NAME="Samba">10.18.2.1. Samba</A></H4>
+<P></P>
+<HR>
+<H1><A NAME="Schema Specification">11. Schema Specification</A></H1>
+<P>This chapter describes how to extend the user schema used by <EM>slapd</EM>(8).  The chapter assumes the reader is familiar with the <TERM>LDAP</TERM>/<TERM>X.500</TERM> information model.</P>
 <P>The first section, <A HREF="#Distributed Schema Files">Distributed Schema Files</A> details optional schema definitions provided in the distribution and where to obtain other definitions. The second section, <A HREF="#Extending Schema">Extending Schema</A>, details how to define new schema items.</P>
 <P>This chapter does not discuss how to extend system schema used by <EM>slapd</EM>(8) as this requires source code modification.  System schema includes all operational attribute types or any object class which allows or requires an operational attribute (directly or indirectly).</P>
-<H2><A NAME="Distributed Schema Files">9.1. Distributed Schema Files</A></H2>
-<P>OpenLDAP is distributed with a set of schema specifications for your use.  Each set is defined in a file suitable for inclusion (using the <TT>include</TT> directive) in your <EM>slapd.conf</EM>(5) file.  These schema files are normally installed in the <TT>/usr/local/etc/openldap/schema</TT> directory.</P>
+<H2><A NAME="Distributed Schema Files">11.1. Distributed Schema Files</A></H2>
+<P>OpenLDAP Software is distributed with a set of schema specifications for your use.  Each set is defined in a file suitable for inclusion (using the <TT>include</TT> directive) in your <EM>slapd.conf</EM>(5) file.  These schema files are normally installed in the <TT>/usr/local/etc/openldap/schema</TT> directory.</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
 <CAPTION ALIGN=top>Table 8.1: Provided Schema Specifications</CAPTION>
 <TR CLASS="heading">
@@ -3123,20 +4153,20 @@
         include /usr/local/etc/openldap/schema/cosine.schema
         include /usr/local/etc/openldap/schema/inetorgperson.schema
 </PRE>
-<P>Additional files may be available.  Please consult the OpenLDAP FAQ (<A HREF="http://www.openldap.org/faq/">http://www.openldap.org/faq/</A>).</P>
+<P>Additional files may be available.  Please consult the OpenLDAP <TERM>FAQ</TERM> (<A HREF="http://www.openldap.org/faq/">http://www.openldap.org/faq/</A>).</P>
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>You should not modify any of the schema items defined in provided files.
 <HR WIDTH="80%" ALIGN="Left"></P>
-<H2><A NAME="Extending Schema">9.2. Extending Schema</A></H2>
+<H2><A NAME="Extending Schema">11.2. Extending Schema</A></H2>
 <P>Schema used by <EM>slapd</EM>(8) may be extended to support additional syntaxes, matching rules, attribute types, and object classes.  This chapter details how to add user application attribute types and object classes using the syntaxes and matching rules already supported by slapd.  slapd can also be extended to support additional syntaxes, matching rules and system schema, but this requires some programming and hence is not discussed here.</P>
 <P>There are five steps to defining new schema:</P>
 <OL>
-<LI>obtain Object Identifer
+<LI>obtain Object Identifier
 <LI>choose a name prefix
 <LI>create local schema file
 <LI>define custom attribute types (if necessary)
 <LI>define custom object classes</OL>
-<H3><A NAME="Object Identifiers">9.2.1. Object Identifiers</A></H3>
+<H3><A NAME="Object Identifiers">11.2.1. Object Identifiers</A></H3>
 <P>Each schema element is identified by a globally unique <TERM>Object Identifier</TERM> (OID).  OIDs are also used to identify other objects.  They are commonly found in protocols described by <TERM>ASN.1</TERM>.  In particular, they are heavily used by the <TERM>Simple Network Management Protocol</TERM> (SNMP). As OIDs are hierarchical, your organization can obtain one OID and branch it as needed.  For example, if your organization were assigned OID <TT>1.1</TT>, you could branch the tree as follows:</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
 <CAPTION ALIGN=top>Table 8.2: Example OID hierarchy</CAPTION>
@@ -3185,7 +4215,7 @@
 <TT>1.1.2.1.1</TT>
 </TD>
 <TD ALIGN='Right'>
-myAttribute
+x-my-Attribute
 </TD>
 </TR>
 <TR>
@@ -3201,25 +4231,26 @@
 <TT>1.1.2.2.1</TT>
 </TD>
 <TD ALIGN='Right'>
-myObjectClass
+x-my-ObjectClass
 </TD>
 </TR>
 </TABLE>
 
-<P>You are, of course, free to design a hierarchy suitable to your organizational needs under your organization's OID.  No matter what hierarchy you choose, you should maintain a registry of assignments you make.  This can be a simple flat file or something more sophisticated such as the <EM>OpenLDAP OID Registry</EM> (<A HREF="http://www.openldap.org/faq/index.cgi?file=197">http://www.openldap.org/faq/index.cgi?file=197</A>).</P>
-<P>For more information about Object Identifers (and a listing service) see <A HREF="http://www.alvestrand.no/harald/objectid/">http://www.alvestrand.no/harald/objectid/</A>.</P>
+<P>You are, of course, free to design a hierarchy suitable to your organizational needs under your organization's OID. No matter what hierarchy you choose, you should maintain a registry of assignments you make.  This can be a simple flat file or something more sophisticated such as the <EM>OpenLDAP OID Registry</EM> (<A HREF="http://www.openldap.org/faq/index.cgi?file=197">http://www.openldap.org/faq/index.cgi?file=197</A>).</P>
+<P>For more information about Object Identifiers (and a listing service) see <A HREF="http://www.alvestrand.no/harald/objectid/">http://www.alvestrand.no/harald/objectid/</A>.</P>
 <UL>
 <EM>Under no circumstances should you hijack OID namespace!</EM></UL>
-<P>To obtain a registered OID at <EM>no cost</EM>, apply for an OID under the <A HREF="http://www.iana.org/">Internet Assigned Numbers Authority</A> (IANA) maintained <EM>Private Enterprise</EM> arc.  Any private enterprise (organization) may request an OID to be assigned under this arc.  Just fill out the <A HREF="http://www.iana.org/">IANA</A> form at <A HREF="http://www.iana.org/cgi-bin/enterprise.pl">http://www.iana.org/cgi-bin/enterprise.pl</A> and your official OID will be sent to you usually within a few days.  Your base OID will be something like <TT>1.3.6.1.4.1.X</TT> where <TT>X</TT> is an integer.</P>
+<P>To obtain a registered OID at <EM>no cost</EM>, apply for a OID under the <A HREF="http://www.iana.org/">Internet Assigned Numbers Authority</A> (ORG:IANA) maintained <EM>Private Enterprise</EM> arc. Any private enterprise (organization) may request a <TERM>Private Enterprise Number</TERM> (PEN) to be assigned under this arc. Just fill out the IANA form at <A HREF="http://pen.iana.org/pen/PenApplication.page">http://pen.iana.org/pen/PenApplication.page</A> and your official PEN will be sent to you usually within a few days. Your base OID will be something like <TT>1.3.6.1.4.1.X</TT> where <TT>X</TT> is an integer.</P>
 <P><HR WIDTH="80%" ALIGN="Left">
-<STRONG>Note: </STRONG>Don't let the &quot;MIB/SNMP&quot; statement on the IANA page confuse you.  OIDs obtained using this form may be used for any purpose including identifying LDAP schema elements.
+<STRONG>Note: </STRONG>PENs obtained using this form may be used for any purpose including identifying LDAP schema elements.
 <HR WIDTH="80%" ALIGN="Left"></P>
-<P>Alternatively, OID name space may be available from a national authority (e.g., <A HREF="http://www.ansi.org/">ANSI</A>, <A HREF="http://www.bsa-global.com/">BSI</A>).</P>
-<H3><A NAME="Name Prefix">9.2.2. Name Prefix</A></H3>
-<P>In addition to assigning a unique object identifier to each schema element, you should provide a least one textual name for each element.  The name should be both descriptive and not likely to clash with names of other schema elements.  In particular, any name you choose should not clash with present or future Standard Track names.</P>
-<P>To reduce (but not eliminate) the potential for name clashes, the convention is to prefix names of non-Standard Track with a few letters to localize the changes to your organization.  The smaller the organization, the longer your prefix should be.</P>
-<P>In the examples below, we have chosen a short prefix '<TT>my</TT>' (to save space).  Such a short prefix would only be suitable for a very large, global organization.  In general, we recommend something like '<TT>deFirm</TT>' (German company) or '<TT>comExample</TT>' (elements associated with organization associated with <TT>example.com</TT>).</P>
-<H3><A NAME="Local schema file">9.2.3. Local schema file</A></H3>
+<P>Alternatively, OID name space may be available from a national authority (e.g., <A HREF="http://www.ansi.org/">ANSI</A>, <A HREF="http://www.bsi-global.com/">BSI</A>).</P>
+<H3><A NAME="Naming Elements">11.2.2. Naming Elements</A></H3>
+<P>In addition to assigning a unique object identifier to each schema element, you should provide a least one textual name for each element.  Names should be registered with the <A HREF="http://www.iana.org/">IANA</A> or prefixed with &quot;x-&quot; to place in the &quot;private use&quot; name space.</P>
+<P>The name should be both descriptive and not likely to clash with names of other schema elements.  In particular, any name you choose should not clash with present or future Standard Track names (this is assured if you registered names or use names beginning with &quot;x-&quot;).</P>
+<P>It is noted that you can obtain your own registered name prefix so as to avoid having to register your names individually. See <A HREF="http://www.rfc-editor.org/rfc/rfc4520.txt">RFC4520</A> for details.</P>
+<P>In the examples below, we have used a short prefix '<TT>x-my-</TT>'. Such a short prefix would only be suitable for a very large, global organization.  In general, we recommend something like '<TT>x-de-Firm-</TT>' (German company) or '<TT>x-com-Example</TT>' (elements associated with organization associated with <TT>example.com</TT>).</P>
+<H3><A NAME="Local schema file">11.2.3. Local schema file</A></H3>
 <P>The <TT>objectclass</TT> and <TT>attributeTypes</TT> configuration file directives can be used to define schema rules on entries in the directory.  It is customary to create a file to contain definitions of your custom schema items.  We recommend you create a file <TT>local.schema</TT> in <TT>/usr/local/etc/openldap/schema/local.schema</TT> and then include this file in your <EM>slapd.conf</EM>(5) file immediately after other schema <TT>include</TT> directives.</P>
 <PRE>
         # include schema
@@ -3229,12 +4260,12 @@
         # include local schema
         include /usr/local/etc/openldap/schema/local.schema
 </PRE>
-<H3><A NAME="Attribute Type Specification">9.2.4. Attribute Type Specification</A></H3>
-<P>The <EM>attributetype</EM> directive is used to define a new attribute type.  The directive uses the same Attribute Type Description (as defined in <A HREF="http://www.rfc-editor.org/rfc/rfc2252.txt">RFC2252</A>) used by the attributeTypes attribute found in the subschema subentry, e.g.:</P>
+<H3><A NAME="Attribute Type Specification">11.2.4. Attribute Type Specification</A></H3>
+<P>The <EM>attributetype</EM> directive is used to define a new attribute type.  The directive uses the same Attribute Type Description (as defined in <A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4512</A>) used by the attributeTypes attribute found in the subschema subentry, e.g.:</P>
 <PRE>
-        attributetype &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc2252.txt">RFC2252</A> Attribute Type Description&gt;
+        attributetype &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4512</A> Attribute Type Description&gt;
 </PRE>
-<P>where Attribute Type Description is defined by the following <TERM>BNF</TERM>:</P>
+<P>where Attribute Type Description is defined by the following <TERM>ABNF</TERM>:</P>
 <PRE>
       AttributeTypeDescription = &quot;(&quot; whsp
             numericoid whsp              ; AttributeType identifier
@@ -3273,7 +4304,7 @@
                 SUP name )
 </PRE>
 <P>Notice that each defines the attribute's OID, provides a short name, and a brief description.  Each name is an alias for the OID. <EM>slapd</EM>(8) returns the first listed name when returning results.</P>
-<P>The first attribute, <TT>name</TT>, holds values of <TT>directoryString</TT> (UTF-8 encoded Unicode) syntax.  The syntax is specified by OID (1.3.6.1.4.1.1466.115.121.1.15 identifies the directoryString syntax).  A length recommendation of 32768 is specified.  Servers should support values of this length, but may support longer values The field does NOT specify a size constraint, so is ignored on servers (such as slapd) which don't impose such size limits.  In addition, the equality and substring matching uses case ignore rules.  Below are tables listing commonly used syntax and matching rules (OpenLDAP supports these and many more).</P>
+<P>The first attribute, <TT>name</TT>, holds values of <TT>directoryString</TT> (<TERM>UTF-8</TERM> encoded Unicode) syntax.  The syntax is specified by OID (1.3.6.1.4.1.1466.115.121.1.15 identifies the directoryString syntax).  A length recommendation of 32768 is specified.  Servers should support values of this length, but may support longer values The field does NOT specify a size constraint, so is ignored on servers (such as slapd) which don't impose such size limits.  In addition, the equality and substring matching uses case ignore rules.  Below are tables listing commonly used syntax and matching rules (<EM>slapd</EM>(8) supports these and many more).</P>
 <TABLE CLASS="columns" BORDER ALIGN='Center'>
 <CAPTION ALIGN=top>Table 8.3: Commonly Used Syntaxes</CAPTION>
 <TR CLASS="heading">
@@ -3317,7 +4348,7 @@
 <TT>1.3.6.1.4.1.1466.115.121.1.12</TT>
 </TD>
 <TD>
-LDAP DN
+LDAP <TERM>DN</TERM>
 </TD>
 </TR>
 <TR>
@@ -3361,7 +4392,7 @@
 <TT>1.3.6.1.4.1.1466.115.121.1.40</TT>
 </TD>
 <TD>
-arbitary octets
+arbitrary octets
 </TD>
 </TR>
 </TABLE>
@@ -3574,26 +4605,26 @@
 <P>The second attribute, <TT>cn</TT>, is a subtype of <TT>name</TT> hence it inherits the syntax, matching rules, and usage of <TT>name</TT>. <TT>commonName</TT> is an alternative name.</P>
 <P>Neither attribute is restricted to a single value.  Both are meant for usage by user applications.  Neither is obsolete nor collective.</P>
 <P>The following subsections provide a couple of examples.</P>
-<H4><A NAME="myUniqueName">9.2.4.1. myUniqueName</A></H4>
+<H4><A NAME="x-my-UniqueName">11.2.4.1. x-my-UniqueName</A></H4>
 <P>Many organizations maintain a single unique name for each user. Though one could use <TT>displayName</TT> (<A HREF="http://www.rfc-editor.org/rfc/rfc2798.txt">RFC2798</A>), this attribute is really meant to be controlled by the user, not the organization.  We could just copy the definition of <TT>displayName</TT> from <TT>inetorgperson.schema</TT> and replace the OID, name, and description, e.g:</P>
 <PRE>
-        attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
+        attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
                 DESC 'unique name with my organization'
                 EQUALITY caseIgnoreMatch
                 SUBSTR caseIgnoreSubstringsMatch
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
                 SINGLE-VALUE )
 </PRE>
-<P>However, if we want this name to be included in <TT>name</TT> assertions [e.g. <TT>(name=*Jane*)</TT>], the attribute could alternatively be defined as a subtype of <TT>name</TT>, e.g.:</P>
+<P>However, if we want this name to be used in <TT>name</TT> assertions, e.g. <TT>(name=*Jane*)</TT>, the attribute could alternatively be defined as a subtype of <TT>name</TT>, e.g.:</P>
 <PRE>
-        attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
+        attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
                 DESC 'unique name with my organization'
                 SUP name )
 </PRE>
-<H4><A NAME="myPhoto">9.2.4.2. myPhoto</A></H4>
-<P>Many organizations maintain a photo of each each user.  A <TT>myPhoto</TT> attribute type could be defined to hold a photo. Of course, one could use just use <TT>jpegPhoto</TT> (<A HREF="http://www.rfc-editor.org/rfc/rfc2798.txt">RFC2798</A>) (or a subtype) to hold the photo.  However, you can only do this if the photo is in <EM>JPEG File Interchange Format</EM>. Alternatively, an attribute type which uses the <EM>Octet String</EM> syntax can be defined, e.g.:</P>
+<H4><A NAME="x-my-Photo">11.2.4.2. x-my-Photo</A></H4>
+<P>Many organizations maintain a photo of each each user.  A <TT>x-my-Photo</TT> attribute type could be defined to hold a photo. Of course, one could use just use <TT>jpegPhoto</TT> (<A HREF="http://www.rfc-editor.org/rfc/rfc2798.txt">RFC2798</A>) (or a subtype) to hold the photo.  However, you can only do this if the photo is in <EM>JPEG File Interchange Format</EM>. Alternatively, an attribute type which uses the <EM>Octet String</EM> syntax can be defined, e.g.:</P>
 <PRE>
-        attributetype ( 1.1.2.1.2 NAME 'myPhoto'
+        attributetype ( 1.1.2.1.2 NAME 'x-my-Photo'
                 DESC 'a photo (application defined format)'
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
                 SINGLE-VALUE )
@@ -3602,16 +4633,16 @@
 <P>If you wanted to support multiple photo formats, you could define a separate attribute type for each format, prefix the photo with some typing information, or describe the value using <TERM>ASN.1</TERM> and use the <TT>;binary</TT> transfer option.</P>
 <P>Another alternative is for the attribute to hold a <TERM>URI</TERM> pointing to the photo.  You can model such an attribute after <TT>labeledURI</TT> (<A HREF="http://www.rfc-editor.org/rfc/rfc2079.txt">RFC2079</A>) or simply create a subtype, e.g.:</P>
 <PRE>
-        attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'
+        attributetype ( 1.1.2.1.3 NAME 'x-my-PhotoURI'
                 DESC 'URI and optional label referring to a photo'
                 SUP labeledURI )
 </PRE>
-<H3><A NAME="Object Class Specification">9.2.5. Object Class Specification</A></H3>
-<P>The <EM>objectclasses</EM> directive is used to define a new object class.  The directive uses the same Object Class Description (as defined in <A HREF="http://www.rfc-editor.org/rfc/rfc2252.txt">RFC2252</A>) used by the objectClasses attribute found in the subschema subentry, e.g.:</P>
+<H3><A NAME="Object Class Specification">11.2.5. Object Class Specification</A></H3>
+<P>The <EM>objectclasses</EM> directive is used to define a new object class.  The directive uses the same Object Class Description (as defined in <A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4512</A>) used by the objectClasses attribute found in the subschema subentry, e.g.:</P>
 <PRE>
-        objectclass &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc2252.txt">RFC2252</A> Object Class Description&gt;
+        objectclass &lt;<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4512</A> Object Class Description&gt;
 </PRE>
-<P>where Object Class Description is defined by the following <TERM>BNF</TERM>:</P>
+<P>where Object Class Description is defined by the following <TERM>ABNF</TERM>:</P>
 <PRE>
         ObjectClassDescription = &quot;(&quot; whsp
                 numericoid whsp      ; ObjectClass identifier
@@ -3625,26 +4656,26 @@
                 [ &quot;MAY&quot; oids ]       ; AttributeTypes
                 whsp &quot;)&quot;
 </PRE>
-<P>where whsp is a space ('<TT> </TT>'), numericoid is a globally unique OID in numeric form (e.g. <TT>1.1.0</TT>), qdescrs is one or more names, and oids is one or more names and/or OIDs.</P>
-<H4><A NAME="myPhotoObject">9.2.5.1. myPhotoObject</A></H4>
-<P>To define an <EM>auxiliary</EM> object class which allows myPhoto to be added to any existing entry.</P>
+<P>where whsp is a space ('<TT> </TT>'), numericoid is a globally unique OID in dotted-decimal form (e.g. <TT>1.1.0</TT>), qdescrs is one or more names, and oids is one or more names and/or OIDs.</P>
+<H4><A NAME="x-my-PhotoObject">11.2.5.1. x-my-PhotoObject</A></H4>
+<P>To define an <EM>auxiliary</EM> object class which allows x-my-Photo to be added to any existing entry.</P>
 <PRE>
-        objectclass ( 1.1.2.2.1 NAME 'myPhotoObject'
-                DESC 'mixin myPhoto'
+        objectclass ( 1.1.2.2.1 NAME 'x-my-PhotoObject'
+                DESC 'mixin x-my-Photo'
                 AUXILIARY
-                MAY myPhoto )
+                MAY x-my-Photo )
 </PRE>
-<H4><A NAME="myPerson">9.2.5.2. myPerson</A></H4>
+<H4><A NAME="x-my-Person">11.2.5.2. x-my-Person</A></H4>
 <P>If your organization would like have a private <EM>structural</EM> object class to instantiate users, you can subclass one of the existing person classes, such as <TT>inetOrgPerson</TT> (<A HREF="http://www.rfc-editor.org/rfc/rfc2798.txt">RFC2798</A>), and add any additional attributes which you desire.</P>
 <PRE>
-        objectclass ( 1.1.2.2.2 NAME 'myPerson'
+        objectclass ( 1.1.2.2.2 NAME 'x-my-Person'
                 DESC 'my person'
                 SUP inetOrgPerson
-                MUST ( myUniqueName $ givenName )
-                MAY myPhoto )
+                MUST ( x-my-UniqueName $ givenName )
+                MAY x-my-Photo )
 </PRE>
-<P>The object class inherits the required/allowed attribute types of <TT>inetOrgPerson</TT> but requires <TT>myUniqueName</TT> and <TT>givenName</TT> and allows <TT>myPhoto</TT>.</P>
-<H3><A NAME="OID Macros">9.2.6. OID Macros</A></H3>
+<P>The object class inherits the required/allowed attribute types of <TT>inetOrgPerson</TT> but requires <TT>x-my-UniqueName</TT> and <TT>givenName</TT> and allows <TT>x-my-Photo</TT>.</P>
+<H3><A NAME="OID Macros">11.2.6. OID Macros</A></H3>
 <P>To ease the management and use of OIDs, <EM>slapd</EM>(8) supports <EM>Object Identifier</EM> macros.  The <TT>objectIdentifier</TT> directive is used to equate a macro (name) with a OID.  The OID may possibly be derived from a previously defined OID macro.   The <EM>slapd.conf</EM>(5) syntax is:</P>
 <PRE>
         objectIdentifier &lt;name&gt; { &lt;oid&gt; | &lt;name&gt;[:&lt;suffix&gt;] }
@@ -3656,31 +4687,31 @@
         objectIdentifier myLDAP myOID:2
         objectIdentifier myAttributeType        myLDAP:1
         objectIdentifier myObjectClass  myLDAP:2
-        attributetype ( myAttributeType:3 NAME 'myPhotoURI'
+        attributetype ( myAttributeType:3 NAME 'x-my-PhotoURI'
                 DESC 'URI and optional label referring to a photo'
                 SUP labeledURI )
-        objectclass ( myObjectClass:1 NAME 'myPhotoObject'
-                DESC 'mixin myPhoto'
+        objectclass ( myObjectClass:1 NAME 'x-my-PhotoObject'
+                DESC 'mixin x-my-Photo'
                 AUXILIARY
-                MAY myPhoto )
+                MAY x-my-Photo )
 </PRE>
 <P></P>
 <HR>
-<H1><A NAME="Security Considerations">10. Security Considerations</A></H1>
+<H1><A NAME="Security Considerations">12. Security Considerations</A></H1>
 <P>OpenLDAP Software is designed to run in a wide variety of computing environments from tightly-controlled closed networks to the global Internet.  Hence, OpenLDAP Software supports many different security mechanisms.  This chapter describes these mechanisms and discusses security considerations for using OpenLDAP Software.</P>
-<H2><A NAME="Network Security">10.1. Network Security</A></H2>
-<H3><A NAME="Selective Listening">10.1.1. Selective Listening</A></H3>
+<H2><A NAME="Network Security">12.1. Network Security</A></H2>
+<H3><A NAME="Selective Listening">12.1.1. Selective Listening</A></H3>
 <P>By default, <EM>slapd</EM>(8) will listen on both the IPv4 and IPv6 &quot;any&quot; addresses.  It is often desirable to have <EM>slapd</EM> listen on select address/port pairs.  For example, listening only on the IPv4 address <TT>127.0.0.1</TT> will disallow remote access to the directory server. E.g.:</P>
 <PRE>
         slapd -h ldap://127.0.0.1
 </PRE>
 <P>While the server can be configured to listen on a particular interface address, this doesn't necessarily restrict access to the server to only those networks accessible via that interface.   To selective restrict remote access, it is recommend that an <A HREF="#IP Firewall">IP Firewall</A> be used to restrict access.</P>
 <P>See <A HREF="#Command-line Options">Command-line Options</A> and <EM>slapd</EM>(8) for more information.</P>
-<H3><A NAME="IP Firewall">10.1.2. IP Firewall</A></H3>
+<H3><A NAME="IP Firewall">12.1.2. IP Firewall</A></H3>
 <P><TERM>IP</TERM> firewall capabilities of the server system can be used to restrict access based upon the client's IP address and/or network interface used to communicate with the client.</P>
 <P>Generally, <EM>slapd</EM>(8) listens on port 389/tcp for <A HREF="ldap://">ldap://</A> sessions and port 636/tcp for <A HREF="ldaps://">ldaps://</A>) sessions.  <EM>slapd</EM>(8) may be configured to listen on other ports.</P>
 <P>As specifics of how to configure IP firewall are dependent on the particular kind of IP firewall used, no examples are provided here. See the document associated with your IP firewall.</P>
-<H3><A NAME="TCP Wrappers">10.1.3. TCP Wrappers</A></H3>
+<H3><A NAME="TCP Wrappers">12.1.3. TCP Wrappers</A></H3>
 <P><EM>slapd</EM>(8) supports <TERM>TCP</TERM> Wrappers.  TCP Wrappers provide a rule-based access control system for controlling TCP/IP access to the server.  For example, the <EM>host_options</EM>(5) rule:</P>
 <PRE>
         slapd: 10.0.0.0/255.0.0.0 127.0.0.1 : ALLOW
@@ -3689,10 +4720,10 @@
 <P>allows only incoming connections from the private network <TT>10.0.0.0</TT> and localhost (<TT>127.0.0.1</TT>) to access the directory service. Note that IP addresses are used as <EM>slapd</EM>(8) is not normally configured to perform reverse lookups.</P>
 <P>It is noted that TCP wrappers require the connection to be accepted. As significant processing is required just to deny a connection, it is generally advised that IP firewall protection be used instead of TCP wrappers.</P>
 <P>See <EM>hosts_access</EM>(5) for more information on TCP wrapper rules.</P>
-<H2><A NAME="Data Integrity and Confidentiality Protection">10.2. Data Integrity and Confidentiality Protection</A></H2>
+<H2><A NAME="Data Integrity and Confidentiality Protection">12.2. Data Integrity and Confidentiality Protection</A></H2>
 <P><TERM>Transport Layer Security</TERM> (TLS) can be used to provide data integrity and confidentiality protection.  OpenLDAP supports negotiation of <TERM>TLS</TERM> (<TERM>SSL</TERM>) via both StartTLS and <A HREF="ldaps://">ldaps://</A>. See the <A HREF="#Using TLS">Using TLS</A> chapter for more information.  StartTLS is the standard track mechanism.</P>
-<P>A number of <TERM>Simple Authentication and Security Layer</TERM> (SASL) mechanisms, such as DIGEST-MD5 and <TERM>GSSAPI</TERM>, also provide data integrity and confidentiality protection.  See the <A HREF="#Using SASL">Using SASL</A> chapter for more information.</P>
-<H3><A NAME="Security Strength Factors">10.2.1. Security Strength Factors</A></H3>
+<P>A number of <TERM>Simple Authentication and Security Layer</TERM> (SASL) mechanisms, such as <TERM>DIGEST-MD5</TERM> and <TERM>GSSAPI</TERM>, also provide data integrity and confidentiality protection.  See the <A HREF="#Using SASL">Using SASL</A> chapter for more information.</P>
+<H3><A NAME="Security Strength Factors">12.2.1. Security Strength Factors</A></H3>
 <P>The server uses <TERM>Security Strength Factor</TERM>s (SSF) to indicate the relative strength of protection.  A SSF of zero (0) indicates no protections are in place.  A SSF of one (1) indicates integrity protection are in place.  A SSF greater than one (&gt;1) roughly correlates to the effective encryption key length.  For example, <TERM>DES</TERM> is 56, <TERM>3DES</TERM> is 112, and <TERM>AES</TERM> 128, 192, or 256.</P>
 <P>A number of administrative controls rely on SSFs associated with TLS and SASL protection in place on an LDAP session.</P>
 <P><TT>security</TT> controls disallow operations when appropriate protections are not in place.  For example:</P>
@@ -3700,9 +4731,9 @@
         security ssf=1 update_ssf=112
 </PRE>
 <P>requires integrity protection for all operations and encryption protection, 3DES equivalent, for update operations (e.g. add, delete, modify, etc.).  See <EM>slapd.conf</EM>(5) for details.</P>
-<P>For fine-grained control, SSFs may be used in access controls.  See <A HREF="#Access Control">Access Control</A> section of the <A HREF="#The slapd Configuration File">The slapd Configuration File</A> for more information.</P>
-<H2><A NAME="Authentication Methods">10.3. Authentication Methods</A></H2>
-<H3><A NAME="&quot;simple&quot; method">10.3.1. &quot;simple&quot; method</A></H3>
+<P>For fine-grained control, SSFs may be used in access controls. See <A HREF="#The access Configuration Directive">The access Configuration Directive</A> section of the <A HREF="#The slapd Configuration File">The slapd Configuration File</A> for more information.</P>
+<H2><A NAME="Authentication Methods">12.3. Authentication Methods</A></H2>
+<H3><A NAME="&quot;simple&quot; method">12.3.1. &quot;simple&quot; method</A></H3>
 <P>The LDAP &quot;simple&quot; method has three modes of operation:</P>
 <UL>
 <LI>anonymous,
@@ -3711,31 +4742,31 @@
 <P>Anonymous access is requested by providing no name and no password to the &quot;simple&quot; bind operation.  Unauthenticated access is requested by providing a name but no password.  Authenticated access is requested by providing a valid name and password.</P>
 <P>An anonymous bind results in an <EM>anonymous</EM> authorization association.  Anonymous bind mechanism is enabled by default, but can be disabled by specifying &quot;<TT>disallow bind_anon</TT>&quot; in <EM>slapd.conf</EM>(5).  Note that disabling the anonymous bind mechanism does not prevent anonymous access to the directory.  To require authentication to access the directory, one should instead specify &quot;<TT>require authc</TT>&quot;.</P>
 <P>An unauthenticated bind also results in an <EM>anonymous</EM> authorization association.  Unauthenticated bind mechanism is disabled by default, but can be enabled by specifying &quot;<TT>allow bind_anon_cred</TT>&quot; in <EM>slapd.conf</EM>(5).  As a number of LDAP applications mistakenly generate unauthenticated bind request when authenticated access was intended (that is, they do not ensure a password was provided), this mechanism should generally remain disabled.</P>
-<P>A successful user/password authenticated bind results in a user authorization identity, the provided name, being associated with the session.  User/password authenticated bind is enabled by default. However, as this mechanism itself offers no evesdropping protection (e.g., the password is set in the clear), it is recommended that it be used only in tightly controlled systems or when the LDAP session is protected by other means (e.g., TLS, <TERM>IPSEC</TERM>). Where the administrator relies on TLS to protect the password, it is recommended that unprotected authentication be disabled.  This is done using the <TT>security</TT> directive's <TT>simple_bind</TT> option, which provides fine grain control over the level of confidential protection to require for <EM>simple</EM> user/password authentication. E.g., using <TT>security simple_bind=56</TT> would require <EM>simple</EM> binds to use encryption of DES equivalent or better.</P>
+<P>A successful user/password authenticated bind results in a user authorization identity, the provided name, being associated with the session.  User/password authenticated bind is enabled by default. However, as this mechanism itself offers no eavesdropping protection (e.g., the password is set in the clear), it is recommended that it be used only in tightly controlled systems or when the LDAP session is protected by other means (e.g., TLS, <TERM>IPsec</TERM>). Where the administrator relies on TLS to protect the password, it is recommended that unprotected authentication be disabled.  This is done using the <TT>security</TT> directive's <TT>simple_bind</TT> option, which provides fine grain control over the level of confidential protection to require for <EM>simple</EM> user/password authentication. E.g., using <TT>security simple_bind=56</TT> would require <EM>simple</EM> binds to use encryption of DES equivalent or better.</P>
 <P>The user/password authenticated bind mechanism can be completely disabled by setting &quot;<TT>disallow bind_simple</TT>&quot;.</P>
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>An unsuccessful bind always results in the session having an <EM>anonymous</EM> authorization association.
 <HR WIDTH="80%" ALIGN="Left"></P>
-<H3><A NAME="SASL method">10.3.2. SASL method</A></H3>
+<H3><A NAME="SASL method">12.3.2. SASL method</A></H3>
 <P>The LDAP <TERM>SASL</TERM> method allows use of any SASL authentication mechanism.  The <A HREF="#Using SASL">Using SASL</A> discusses use of SASL.</P>
 <P></P>
 <HR>
-<H1><A NAME="Using SASL">11. Using SASL</A></H1>
-<P>OpenLDAP clients and servers are capable of authenticating via the <TERM>Simple Authentication and Security Layer</TERM> (<TERM>SASL</TERM>) framework, which is detailed in <A HREF="http://www.rfc-editor.org/rfc/rfc2222.txt">RFC2222</A>.   This chapter describes how to make use of SASL in OpenLDAP.</P>
-<P>There are several industry standard authentication mechanisms that can be used with SASL, including <TERM>GSSAPI</TERM> for <TERM>Kerberos</TERM> V, DIGEST-MD5, and PLAIN and EXTERNAL for use with <TERM>Transport Layer Security</TERM> (TLS).</P>
-<P>The standard client tools provided with OpenLDAP Software, such as <EM>ldapsearch</EM>(1) and <EM>ldapmodify</EM>(1), will by default attempt to authenticate the user to the <EM>slapd</EM>(8) server using SASL. Basic authentication service can be set up by the LDAP administrator with a few steps, allowing users to be authenticated to the slapd server as their LDAP entry.  With a few extra steps, some users and services can be allowed to exploit SASL's proxy authorization feature, allowing them to authenticate themselves and then switch their identity to that of another user or service.</P>
-<P>This chapter assumes you have read <EM>Cyrus SASL for System Administrators</EM>, provided with the <A HREF="http://asg.web.cmu.edu/cyrus/">Cyrus</A> <A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">SASL</A> package (in <TT>doc/sysadmin.html</TT>) and have a working Cyrus SASL installation.  You should use the Cyrus SASL <TT>sample_client</TT> and <TT>sample_server</TT> to test your SASL installation before attempting to make use of it with OpenLDAP Software.</P>
+<H1><A NAME="Using SASL">13. Using SASL</A></H1>
+<P>OpenLDAP clients and servers are capable of authenticating via the <TERM>Simple Authentication and Security Layer</TERM> (<TERM>SASL</TERM>) framework, which is detailed in <A HREF="http://www.rfc-editor.org/rfc/rfc4422.txt">RFC4422</A>.   This chapter describes how to make use of SASL in OpenLDAP.</P>
+<P>There are several industry standard authentication mechanisms that can be used with SASL, including <TERM>GSSAPI</TERM> for <TERM>Kerberos</TERM> V, <TERM>DIGEST-MD5</TERM>, and <TERM>PLAIN</TERM> and <TERM>EXTERNAL</TERM> for use with <TERM>Transport Layer Security</TERM> (TLS).</P>
+<P>The standard client tools provided with OpenLDAP Software, such as <EM>ldapsearch</EM>(1) and <EM>ldapmodify</EM>(1), will by default attempt to authenticate the user to the <TERM>LDAP</TERM> directory server using SASL.  Basic authentication service can be set up by the LDAP administrator with a few steps, allowing users to be authenticated to the slapd server as their LDAP entry.  With a few extra steps, some users and services can be allowed to exploit SASL's proxy authorization feature, allowing them to authenticate themselves and then switch their identity to that of another user or service.</P>
+<P>This chapter assumes you have read <EM>Cyrus SASL for System Administrators</EM>, provided with the <A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">Cyrus SASL</A> package (in <TT>doc/sysadmin.html</TT>) and have a working Cyrus SASL installation.  You should use the Cyrus SASL <TT>sample_client</TT> and <TT>sample_server</TT> to test your SASL installation before attempting to make use of it with OpenLDAP Software.</P>
 <P>Note that in the following text the term <EM>user</EM> is used to describe a person or application entity who is connecting to the LDAP server via an LDAP client, such as <EM>ldapsearch</EM>(1).  That is, the term <EM>user</EM> not only applies to both an individual using an LDAP client, but to an application entity which issues LDAP client operations without direct user control.  For example, an e-mail server which uses LDAP operations to access information held in an LDAP server is an application entity.</P>
-<H2><A NAME="SASL Security Considerations">11.1. SASL Security Considerations</A></H2>
+<H2><A NAME="SASL Security Considerations">13.1. SASL Security Considerations</A></H2>
 <P>SASL offers many different authentication mechanisms.  This section briefly outlines security considerations.</P>
 <P>Some mechanisms, such as PLAIN and LOGIN, offer no greater security over LDAP <EM>simple</EM> authentication.  Like LDAP <EM>simple</EM> authentication, such mechanisms should not be used unless you have adequate security protections in place.  It is recommended that these mechanisms be used only in conjunction with <TERM>Transport Layer Security</TERM> (TLS).  Use of PLAIN and LOGIN are not discussed further in this document.</P>
-<P>The DIGEST-MD5 mechanism is the mandatory-to-implement authentication mechanism for LDAPv3.  Though DIGEST-MD5 is not a strong authentication mechanism in comparison with trusted third party authentication systems (such as Kerberos or public key systems), it does offer significant protections against a number of attacks.  Unlike the CRAM-MD5 mechanism, it prevents chosen plaintext attacks.  DIGEST-MD5 is favored over the use of plaintext password mechanisms.  The CRAM-MD5 mechanism is deprecated in favor of DIGEST-MD5.  Use of <A HREF="#DIGEST-MD5">DIGEST-MD5</A> is discussed below.</P>
-<P>The GSSAPI mechanism utilizes Kerberos V to provide secure authentication services.  The KERBEROS_V4 mechanism is available for those using Kerberos IV.  Kerberos is viewed as a secure, distributed authentication system suitable for both small and large enterprises.  Use of <A HREF="#GSSAPI">GSSAPI</A> and <A HREF="#KERBEROS_V4">KERBEROS_V4</A> are discussed below.</P>
+<P>The DIGEST-MD5 mechanism is the mandatory-to-implement authentication mechanism for LDAPv3.  Though DIGEST-MD5 is not a strong authentication mechanism in comparison with trusted third party authentication systems (such as <TERM>Kerberos</TERM> or public key systems), it does offer significant protections against a number of attacks.  Unlike the <TERM>CRAM-MD5</TERM> mechanism, it prevents chosen plaintext attacks.  DIGEST-MD5 is favored over the use of plaintext password mechanisms.  The CRAM-MD5 mechanism is deprecated in favor of DIGEST-MD5.  Use of <A HREF="#DIGEST-MD5">DIGEST-MD5</A> is discussed below.</P>
+<P>The GSSAPI mechanism utilizes <TERM>GSS-API</TERM> <TERM>Kerberos</TERM> V to provide secure authentication services.  The KERBEROS_V4 mechanism is available for those using Kerberos IV.  Kerberos is viewed as a secure, distributed authentication system suitable for both small and large enterprises.  Use of <A HREF="#GSSAPI">GSSAPI</A> and <A HREF="#KERBEROS_V4">KERBEROS_V4</A> are discussed below.</P>
 <P>The EXTERNAL mechanism utilizes authentication services provided by lower level network services such as <TERM>TLS</TERM> (TLS).  When used in conjunction with <TERM>TLS</TERM> <TERM>X.509</TERM>-based public key technology, EXTERNAL offers strong authentication.  Use of EXTERNAL is discussed in the <A HREF="#Using TLS">Using TLS</A> chapter.</P>
 <P>There are other strong authentication mechanisms to choose from, including <TERM>OTP</TERM> (one time passwords) and <TERM>SRP</TERM> (secure remote passwords).  These mechanisms are not discussed in this document.</P>
-<H2><A NAME="SASL Authentication">11.2. SASL Authentication</A></H2>
-<P>Getting basic SASL authentication running involves a few steps. The first step configures your slapd server environment so that it can communicate with client programs using the security system in place at your site. This usually involves setting up a service key, a public key, or other form of secret. The second step concerns mapping authentication identities to LDAP DN's, which depends on how entries are laid out in your directory. An explanation of the first step will be given in the next section using Kerberos V4 as an example mechanism. The steps necessary for your site's authentication mechanism will be similar, but a guide to every mechanism available under SASL is beyond the scope of this chapter. The second step is described in the section <A HREF="#Mapping Authentication Identities">Mapping Authentication Identities</A>.</P>
-<H3><A NAME="GSSAPI">11.2.1. GSSAPI</A></H3>
+<H2><A NAME="SASL Authentication">13.2. SASL Authentication</A></H2>
+<P>Getting basic SASL authentication running involves a few steps. The first step configures your slapd server environment so that it can communicate with client programs using the security system in place at your site. This usually involves setting up a service key, a public key, or other form of secret. The second step concerns mapping authentication identities to LDAP <TERM>DN</TERM>'s, which depends on how entries are laid out in your directory. An explanation of the first step will be given in the next section using Kerberos V4 as an example mechanism. The steps necessary for your site's authentication mechanism will be similar, but a guide to every mechanism available under SASL is beyond the scope of this chapter. The second step is described in the section <A HREF="#Mapping Authentication Identities">Mapping Authentication Identities</A>.</P>
+<H3><A NAME="GSSAPI">13.2.1. GSSAPI</A></H3>
 <P>This section describes the use of the SASL GSSAPI mechanism and Kerberos V with OpenLDAP.  It will be assumed that you have Kerberos V deployed, you are familiar with the operation of the system, and that your users are trained in its use.  This section also assumes you have familiarized yourself with the use of the GSSAPI mechanism by reading <EM>Configuring GSSAPI and Cyrus SASL</EM> (provided with Cyrus SASL in the <TT>doc/gssapi</TT> file) and successfully experimented with the Cyrus provided <TT>sample_server</TT> and <TT>sample_client</TT> applications.  General information about Kerberos is available at <A HREF="http://web.mit.edu/kerberos/www/">http://web.mit.edu/kerberos/www/</A>.</P>
 <P>To use the GSSAPI mechanism with <EM>slapd</EM>(8) one must create a service key with a principal for <EM>ldap</EM> service within the realm for the host on which the service runs.  For example, if you run <EM>slapd</EM> on <TT>directory.example.com</TT> and your realm is <TT>EXAMPLE.COM</TT>, you need to create a service key with the principal:</P>
 <PRE>
@@ -3756,7 +4787,7 @@
         uid=ursula/admin,cn=foreign.realm,cn=gssapi,cn=auth
 </PRE>
 <P>The authentication request DN can be used directly ACLs and <TT>groupOfNames</TT> &quot;member&quot; attributes, since it is of legitimate LDAP DN format.  Or alternatively, the authentication DN could be mapped before use.  See the section <A HREF="#Mapping Authentication Identities">Mapping Authentication Identities</A> for details.</P>
-<H3><A NAME="KERBEROS_V4">11.2.2. KERBEROS_V4</A></H3>
+<H3><A NAME="KERBEROS_V4">13.2.2. KERBEROS_V4</A></H3>
 <P>This section describes the use of the SASL KERBEROS_V4 mechanism with OpenLDAP.  It will be assumed that you are familiar with the workings of the Kerberos IV security system, and that your site has Kerberos IV deployed.  Your users should be familiar with authentication policy, how to receive credentials in a Kerberos ticket cache, and how to refresh expired credentials.</P>
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>KERBEROS_V4 and Kerberos IV are deprecated in favor of GSSAPI and Kerberos V.
@@ -3779,7 +4810,7 @@
         uid=adamsom,cn=example.com,cn=kerberos_v4,cn=auth
 </PRE>
 <P>This authentication request DN can be used directly ACLs or, alternatively, mapped prior to use.  See the section <A HREF="#Mapping Authentication Identities">Mapping Authentication Identities</A> for details.</P>
-<H3><A NAME="DIGEST-MD5">11.2.3. DIGEST-MD5</A></H3>
+<H3><A NAME="DIGEST-MD5">13.2.3. DIGEST-MD5</A></H3>
 <P>This section describes the use of the SASL DIGEST-MD5 mechanism using secrets stored either in the directory itself or in Cyrus SASL's own database. DIGEST-MD5 relies on the client and the server sharing a &quot;secret&quot;, usually a password. The server generates a challenge and the client a response proving that it knows the shared secret. This is much more secure than simply sending the secret over the wire.</P>
 <P>Cyrus SASL supports several shared-secret mechanisms. To do this, it needs access to the plaintext password (unlike mechanisms which pass plaintext passwords over the wire, where the server can store a hashed version of the password).</P>
 <P>The server's copy of the shared-secret may be stored in Cyrus SASL's own <EM>sasldb</EM> database, in an external system accessed via <EM>saslauthd</EM>, or in LDAP database itself.  In either case it is very important to apply file access controls and LDAP access controls to prevent exposure of the passwords.  The configuration and commands discussed in this section assume the use of Cyrus SASL 2.1.</P>
@@ -3818,7 +4849,7 @@
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>in each of the above cases, no authorization identity (e.g. <TT>-X</TT>) was provided.   Unless you are attempting <A HREF="#SASL Proxy Authorization">SASL Proxy Authorization</A>, no authorization identity should be specified. The server will infer an authorization identity from authentication identity (as described below).
 <HR WIDTH="80%" ALIGN="Left"></P>
-<H3><A NAME="Mapping Authentication Identities">11.2.4. Mapping Authentication Identities</A></H3>
+<H3><A NAME="Mapping Authentication Identities">13.2.4. Mapping Authentication Identities</A></H3>
 <P>The authentication mechanism in the slapd server will use SASL library calls to obtain the authenticated user's &quot;username&quot;, based on whatever underlying authentication mechanism was used.  This username is in the namespace of the authentication mechanism, and not in the normal LDAP namespace. As stated in the sections above, that username is reformatted into an authentication request DN of the form</P>
 <PRE>
         uid=&lt;username&gt;,cn=&lt;realm&gt;,cn=&lt;mechanism&gt;,cn=auth
@@ -3839,8 +4870,8 @@
 </PRE>
 <P>The authentication request DN is compared to the search pattern using the regular expression functions <EM>regcomp</EM>() and <EM>regexec</EM>(), and if it matches, it is rewritten as the replacement pattern. If there are multiple <TT>authz-regexp</TT> directives, only the first whose search pattern matches the authentication identity is used. The string that is output from the replacement pattern should be the authentication DN of the user or an LDAP URL.  If replacement string produces a DN, the entry named by this DN need not be held by this server.  If the replace string produces an LDAP URL, that LDAP URL must evaluate to one and only one entry held by this server.</P>
 <P>The search pattern can contain any of the regular expression characters listed in <EM>regexec</EM>(3C). The main characters of note are dot &quot;.&quot;, asterisk &quot;*&quot;, and the open and close parenthesis &quot;(&quot; and &quot;)&quot;.  Essentially, the dot matches any character, the asterisk allows zero or more repeats of the immediately preceding character or pattern, and terms in parenthesis are remembered for the replacement pattern.</P>
-<P>The replacement pattern will produce either a DN or URL refering to the user.  Anything from the authentication request DN that matched a string in parenthesis in the search pattern is stored in the variable &quot;$1&quot;. That variable &quot;$1&quot; can appear in the replacement pattern, and will be replaced by the string from the authentication request DN. If there were multiple sets of parentheses in the search pattern, the variables $2, $3, etc are used.</P>
-<H3><A NAME="Direct Mapping">11.2.5. Direct Mapping</A></H3>
+<P>The replacement pattern will produce either a DN or URL referring to the user.  Anything from the authentication request DN that matched a string in parenthesis in the search pattern is stored in the variable &quot;$1&quot;. That variable &quot;$1&quot; can appear in the replacement pattern, and will be replaced by the string from the authentication request DN. If there were multiple sets of parentheses in the search pattern, the variables $2, $3, etc are used.</P>
+<H3><A NAME="Direct Mapping">13.2.5. Direct Mapping</A></H3>
 <P>Where possible, direct mapping of the authentication request DN to the user's DN is generally recommended.  Aside from avoiding the expense of searching for the user's DN, it allows mapping to DNs which refer to entries not held by this server.</P>
 <P>Suppose the authentication request DN is written as:</P>
 <PRE>
@@ -3864,7 +4895,7 @@
 </PRE>
 <P>Be careful about setting the search pattern too leniently, however, since it may mistakenly allow persons to become authenticated as a DN to which they should not have access.  It is better to write several strict directives than one lenient directive which has security holes.  If there is only one authentication mechanism in place at your site, and zero or one realms in use, you might be able to map between authentication identities and LDAP DN's with a single <TT>authz-regexp</TT> directive.</P>
 <P>Don't forget to allow for the case where the realm is omitted as well as the case with an explicitly specified realm. This may well require a separate <TT>authz-regexp</TT> directive for each case, with the explicit-realm entry being listed first.</P>
-<H3><A NAME="Search-based mappings">11.2.6. Search-based mappings</A></H3>
+<H3><A NAME="Search-based mappings">13.2.6. Search-based mappings</A></H3>
 <P>There are a number of cases where mapping to a LDAP URL may be appropriate.  For instance, some sites may have person objects located in multiple areas of the LDAP tree, such as if there were an <TT>ou=accounting</TT> tree and an <TT>ou=engineering</TT> tree, with persons interspersed between them.  Or, maybe the desired mapping must be based upon information in the user's information. Consider the need to map the above authentication request DN to user whose entry is as follows:</P>
 <PRE>
         dn: cn=Mark Adamson,ou=People,dc=Example,dc=COM
@@ -3904,19 +4935,20 @@
            ldap:///dc=customers,dc=example,dc=com??one?(&amp;(uid=$1)(objectClass=person))
 </PRE>
 <P>Note that the explicitly-named realms are handled first, to avoid the realm name becoming part of the UID.  Also note the use of scope and filters to limit matching to desirable entries.</P>
+<P>Note as well that <TT>authz-regexp</TT> internal search are subject to access controls.  Specifically, the authentication identity must have <TT>auth</TT> access.</P>
 <P>See <EM>slapd.conf</EM>(5) for more detailed information.</P>
-<H2><A NAME="SASL Proxy Authorization">11.3. SASL Proxy Authorization</A></H2>
+<H2><A NAME="SASL Proxy Authorization">13.3. SASL Proxy Authorization</A></H2>
 <P>The SASL offers a feature known as <EM>proxy authorization</EM>, which allows an authenticated user to request that they act on the behalf of another user.  This step occurs after the user has obtained an authentication DN, and involves sending an authorization identity to the server. The server will then make a decision on whether or not to allow the authorization to occur. If it is allowed, the user's LDAP connection is switched to have a binding DN derived from the authorization identity, and the LDAP session proceeds with the access of the new authorization DN.</P>
 <P>The decision to allow an authorization to proceed depends on the rules and policies of the site where LDAP is running, and thus cannot be made by SASL alone. The SASL library leaves it up to the server to make the decision. The LDAP administrator sets the guidelines of who can authorize to what identity by adding information into the LDAP database entries. By default, the authorization features are disabled, and must be explicitly configured by the LDAP administrator before use.</P>
-<H3><A NAME="Uses of Proxy Authorization">11.3.1. Uses of Proxy Authorization</A></H3>
+<H3><A NAME="Uses of Proxy Authorization">13.3.1. Uses of Proxy Authorization</A></H3>
 <P>This sort of service is useful when one entity needs to act on the behalf of many other users. For example, users may be directed to a web page to make changes to their personal information in their LDAP entry. The users authenticate to the web server to establish their identity, but the web server CGI cannot authenticate to the LDAP server as that user to make changes for them. Instead, the web server authenticates itself to the LDAP server as a service identity, say,</P>
 <PRE>
         cn=WebUpdate,dc=example,dc=com
 </PRE>
 <P>and then it will SASL authorize to the DN of the user. Once so authorized, the CGI makes changes to the LDAP entry of the user, and as far as the slapd server can tell for its ACLs, it is the user themself on the other end of the connection. The user could have connected to the LDAP server directly and authenticated as themself, but that would require the user to have more knowledge of LDAP clients, knowledge which the web page provides in an easier format.</P>
-<P>Proxy authorization can also be used to limit access to an account that has greater access to the database. Such an account, perhaps even the root DN specified in <EM>slapd.conf</EM>(5), can have a strict list of people who can authorize to that DN. Changes to the LDAP database could then be only allowed by that DN, and in order to become that DN, users must first authenticate as one of the persons on the list. This allows for better auditing of who made changes to the LDAP database.  If people were allowed to authenticate directly to the priviliged account, possibly through the <TT>rootpw</TT> <EM>slapd.conf</EM>(5) directive or through a <TT>userPassword</TT> attribute, then auditing becomes more difficult.</P>
+<P>Proxy authorization can also be used to limit access to an account that has greater access to the database. Such an account, perhaps even the root DN specified in <EM>slapd.conf</EM>(5), can have a strict list of people who can authorize to that DN. Changes to the LDAP database could then be only allowed by that DN, and in order to become that DN, users must first authenticate as one of the persons on the list. This allows for better auditing of who made changes to the LDAP database.  If people were allowed to authenticate directly to the privileged account, possibly through the <TT>rootpw</TT> <EM>slapd.conf</EM>(5) directive or through a <TT>userPassword</TT> attribute, then auditing becomes more difficult.</P>
 <P>Note that after a successful proxy authorization, the original authentication DN of the LDAP connection is overwritten by the new DN from the authorization request. If a service program is able to authenticate itself as its own authentication DN and then authorize to other DN's, and it is planning on switching to several different identities during one LDAP session, it will need to authenticate itself each time before authorizing to another DN (or use a different proxy authorization mechanism).  The slapd server does not keep record of the service program's ability to switch to other DN's. On authentication mechanisms like Kerberos this will not require multiple connections being made to the Kerberos server, since the user's TGT and &quot;ldap&quot; session key are valid for multiple uses for the several hours of the ticket lifetime.</P>
-<H3><A NAME="SASL Authorization Identities">11.3.2. SASL Authorization Identities</A></H3>
+<H3><A NAME="SASL Authorization Identities">13.3.2. SASL Authorization Identities</A></H3>
 <P>The SASL authorization identity is sent to the LDAP server via the <TT>-X</TT> switch for <EM>ldapsearch</EM>(1) and other tools, or in the <TT>*authzid</TT> parameter to the <EM>lutil_sasl_defaults</EM>() call. The identity can be in one of two forms, either</P>
 <PRE>
         u:&lt;username&gt;
@@ -3925,101 +4957,104 @@
 <PRE>
         dn:&lt;dn&gt;
 </PRE>
-<P>In the first form, the &lt;username&gt; is from the same namespace as the authentication identities above. It is the user's username as it is refered to by the underlying authentication mechanism. Authorization identities of this form are converted into a DN format by the same function that the authentication process used, producing an <EM>authorization request DN</EM> of the form</P>
+<P>In the first form, the &lt;username&gt; is from the same namespace as the authentication identities above. It is the user's username as it is referred to by the underlying authentication mechanism. Authorization identities of this form are converted into a DN format by the same function that the authentication process used, producing an <EM>authorization request DN</EM> of the form</P>
 <PRE>
         uid=&lt;username&gt;,cn=&lt;realm&gt;,cn=&lt;mechanism&gt;,cn=auth
 </PRE>
 <P>That authorization request DN is then run through the same <TT>authz-regexp</TT> process to convert it into a legitimate authorization DN from the database. If it cannot be converted due to a failed search from an LDAP URL, the authorization request fails with &quot;inappropriate access&quot;.  Otherwise, the DN string is now a legitimate authorization DN ready to undergo approval.</P>
 <P>If the authorization identity was provided in the second form, with a <TT>&quot;dn:&quot;</TT> prefix, the string after the prefix is already in authorization DN form, ready to undergo approval.</P>
-<H3><A NAME="Proxy Authorization Rules">11.3.3. Proxy Authorization Rules</A></H3>
+<H3><A NAME="Proxy Authorization Rules">13.3.3. Proxy Authorization Rules</A></H3>
 <P>Once slapd has the authorization DN, the actual approval process begins. There are two attributes that the LDAP administrator can put into LDAP entries to allow authorization:</P>
 <PRE>
         authzTo
         authzFrom
 </PRE>
 <P>Both can be multivalued.  The <TT>authzTo</TT> attribute is a source rule, and it is placed into the entry associated with the authentication DN to tell what authorization DNs the authenticated DN is allowed to assume.  The second attribute is a destination rule, and it is placed into the entry associated with the requested authorization DN to tell which authenticated DNs may assume it.</P>
-<P>The choice of which authorization policy attribute to use is up to the administrator.  Source rules are checked first in the person's authentication DN entry, and if none of the <TT>authzTo</TT> rules specify the authorization is permitted, the <TT>authzFrom</TT> rules in the authorization DN entry are then checked. If neither case specifies that the request be honored, the request is denied. Since the default behaviour is to deny authorization requests, rules only specify that a request be allowed; there are no negative rules telling what authorizations to deny.</P>
+<P>The choice of which authorization policy attribute to use is up to the administrator.  Source rules are checked first in the person's authentication DN entry, and if none of the <TT>authzTo</TT> rules specify the authorization is permitted, the <TT>authzFrom</TT> rules in the authorization DN entry are then checked. If neither case specifies that the request be honored, the request is denied. Since the default behavior is to deny authorization requests, rules only specify that a request be allowed; there are no negative rules telling what authorizations to deny.</P>
 <P>The value(s) in the two attributes are of the same form as the output of the replacement pattern of a <TT>authz-regexp</TT> directive: either a DN or an LDAP URL. For example, if a <TT>authzTo</TT> value is a DN, that DN is one the authenticated user can authorize to. On the other hand, if the <TT>authzTo</TT> value is an LDAP URL, the URL is used as an internal search of the LDAP database, and the authenticated user can become ANY DN returned by the search. If an LDAP entry looked like:</P>
 <PRE>
         dn: cn=WebUpdate,dc=example,dc=com
         authzTo: ldap:///dc=example,dc=com??sub?(objectclass=person)
 </PRE>
 <P>then any user who authenticated as <TT>cn=WebUpdate,dc=example,dc=com</TT> could authorize to any other LDAP entry under the search base <TT>dc=example,dc=com</TT> which has an objectClass of <TT>Person</TT>.</P>
-<H4><A NAME="Notes on Proxy Authorization Rules">11.3.3.1. Notes on Proxy Authorization Rules</A></H4>
+<H4><A NAME="Notes on Proxy Authorization Rules">13.3.3.1. Notes on Proxy Authorization Rules</A></H4>
 <P>An LDAP URL in a <TT>authzTo</TT> or <TT>authzFrom</TT> attribute will return a set of DNs.  Each DN returned will be checked.  Searches which return a large set can cause the authorization process to take an uncomfortably long time. Also, searches should be performed on attributes that have been indexed by slapd.</P>
 <P>To help produce more sweeping rules for <TT>authzFrom</TT> and <TT>authzTo</TT>, the values of these attributes are allowed to be DNs with regular expression characters in them. This means a source rule like</P>
 <PRE>
-        authzTo: uid=[^,]*,dc=example,dc=com
+        authzTo: dn.regex=^uid=[^,]*,dc=example,dc=com$
 </PRE>
 <P>would allow that authenticated user to authorize to any DN that matches the regular expression pattern given. This regular expression comparison can be evaluated much faster than an LDAP search for <TT>(uid=*)</TT>.</P>
-<P>Also note that the values in an authorization rule must be one of the two forms: an LDAP URL or a DN (with or without regular expression characters). Anything that does not begin with &quot;<TT>ldap://</TT>&quot; is taken as a DN. It is not permissable to enter another authorization identity of the form &quot;<TT>u:&lt;username&gt;</TT>&quot; as an authorization rule.</P>
-<H4><A NAME="Policy Configuration">11.3.3.2. Policy Configuration</A></H4>
+<P>Also note that the values in an authorization rule must be one of the two forms: an LDAP URL or a DN (with or without regular expression characters). Anything that does not begin with &quot;<TT>ldap://</TT>&quot; is taken as a DN. It is not permissible to enter another authorization identity of the form &quot;<TT>u:&lt;username&gt;</TT>&quot; as an authorization rule.</P>
+<H4><A NAME="Policy Configuration">13.3.3.2. Policy Configuration</A></H4>
 <P>The decision of which type of rules to use, <TT>authzFrom</TT> or <TT>authzTo</TT>, will depend on the site's situation. For example, if the set of people who may become a given identity can easily be written as a search filter, then a single destination rule could be written. If the set of people is not easily defined by a search filter, and the set of people is small, it may be better to write a source rule in the entries of each of those people who should be allowed to perform the proxy authorization.</P>
 <P>By default, processing of proxy authorization rules is disabled. The <TT>authz-policy</TT> directive must be set in the <EM>slapd.conf</EM>(5) file to enable authorization. This directive can be set to <TT>none</TT> for no rules (the default), <TT>to</TT> for source rules, <TT>from</TT> for destination rules, or <TT>both</TT> for both source and destination rules.</P>
-<P>Destination rules are extremely powerful. If ordinary users have access to write the <TT>authzTo</TT> attribute in their own entries, then they can write rules that would allow them to authorize as anyone else.  As such, when using destination rules, the <TT>authzTo</TT> attribute should be protected with an ACL that only allows privileged users to set its values.</P>
+<P>Source rules are extremely powerful. If ordinary users have access to write the <TT>authzTo</TT> attribute in their own entries, then they can write rules that would allow them to authorize as anyone else.  As such, when using source rules, the <TT>authzTo</TT> attribute should be protected with an ACL that only allows privileged users to set its values.</P>
 <P></P>
 <HR>
-<H1><A NAME="Using TLS">12. Using TLS</A></H1>
-<P>OpenLDAP clients and servers are capable of using the <TERM>Transport Layer Security</TERM> (<TERM>TLS</TERM>) framework to provide integrity and confidentiality protections and to support LDAP authentication using the <TERM>SASL</TERM> EXTERNAL mechanism.</P>
-<H2><A NAME="TLS Certificates">12.1. TLS Certificates</A></H2>
-<P>TLS uses <TERM>X.509</TERM> certificates to carry client and server identities. All servers are required to have valid certificates, whereas client certificates are optional. Clients must have a valid certificate in order to authenticate via SASL EXTERNAL. For more information on creating and managing certificates, see the <A HREF="http://www.openssl.org/">OpenSSL</A> documentation.</P>
-<H3><A NAME="Server Certificates">12.1.1. Server Certificates</A></H3>
-<P>The DN of a server certificate must use the CN attribute to name the server, and the <TT>CN</TT> must carry the server's fully qualified domain name. Additional alias names and wildcards may be present in the <TT>subjectAltName</TT> certificate extension. More details on server certificate names are in <A HREF="http://www.rfc-editor.org/rfc/rfc2830.txt">RFC2830</A>.</P>
-<H3><A NAME="Client Certificates">12.1.2. Client Certificates</A></H3>
-<P>The DN of a client certificate can be used directly as an authentication DN. Since X.509 is a part of the <TERM>X.500</TERM> standard and LDAP is also based on X.500, both use the same DN formats and generally the DN in a user's X.509 certificate should be identical to the DN of their LDAP entry. However, sometimes the DNs may not be exactly the same, and so the mapping facility described in <A HREF="#Mapping Authentication identities to LDAP entries">Mapping Authentication identities to LDAP entries</A> can be applied to these DNs as well.</P>
-<H2><A NAME="TLS Configuration">12.2. TLS Configuration</A></H2>
-<P>After obtaining the required certificates, a number of options must be configured on both the client and the server to enable TLS and make use of the certificates. At a minimum, the clients must be configured with the filename containing all of the <TERM>Certificate Authority</TERM> (CA) certificates it will trust. The server must be configured with the <TERM>CA</TERM> certificates and also its own server certificate and private key.</P>
+<H1><A NAME="Using TLS">14. Using TLS</A></H1>
+<P>OpenLDAP clients and servers are capable of using the <TERM>Transport Layer Security</TERM> (<TERM>TLS</TERM>) framework to provide integrity and confidentiality protections and to support LDAP authentication using the <TERM>SASL</TERM> <TERM>EXTERNAL</TERM> mechanism. TLS is defined in <A HREF="http://www.rfc-editor.org/rfc/rfc4346.txt">RFC4346</A>.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>For generating certifcates, please reference <A HREF="http://www.openldap.org/faq/data/cache/185.html">http://www.openldap.org/faq/data/cache/185.html</A>
+<HR WIDTH="80%" ALIGN="Left"></P>
+<H2><A NAME="TLS Certificates">14.1. TLS Certificates</A></H2>
+<P>TLS uses <TERM>X.509</TERM> certificates to carry client and server identities.  All servers are required to have valid certificates, whereas client certificates are optional.  Clients must have a valid certificate in order to authenticate via SASL EXTERNAL. For more information on creating and managing certificates, see the <A HREF="http://www.openssl.org/">OpenSSL</A> documentation.</P>
+<H3><A NAME="Server Certificates">14.1.1. Server Certificates</A></H3>
+<P>The <TERM>DN</TERM> of a server certificate must use the <TT>CN</TT> attribute to name the server, and the <TT>CN</TT> must carry the server's fully qualified domain name. Additional alias names and wildcards may be present in the <TT>subjectAltName</TT> certificate extension.  More details on server certificate names are in <A HREF="http://www.rfc-editor.org/rfc/rfc4513.txt">RFC4513</A>.</P>
+<H3><A NAME="Client Certificates">14.1.2. Client Certificates</A></H3>
+<P>The DN of a client certificate can be used directly as an authentication DN. Since X.509 is a part of the <TERM>X.500</TERM> standard and LDAP is also based on X.500, both use the same DN formats and generally the DN in a user's X.509 certificate should be identical to the DN of their LDAP entry. However, sometimes the DNs may not be exactly the same, and so the mapping facility described in <A HREF="#Mapping Authentication Identities">Mapping Authentication Identities</A> can be applied to these DNs as well.</P>
+<H2><A NAME="TLS Configuration">14.2. TLS Configuration</A></H2>
+<P>After obtaining the required certificates, a number of options must be configured on both the client and the server to enable TLS and make use of the certificates.  At a minimum, the clients must be configured with the name of the file containing all of the <TERM>Certificate Authority</TERM> (CA) certificates it will trust. The server must be configured with the <TERM>CA</TERM> certificates and also its own server certificate and private key.</P>
 <P>Typically a single CA will have issued the server certificate and all of the trusted client certificates, so the server only needs to trust that one signing CA. However, a client may wish to connect to a variety of secure servers managed by different organizations, with server certificates generated by many different CAs. As such, a client is likely to need a list of many different trusted CAs in its configuration.</P>
-<H3><A NAME="Server Configuration">12.2.1. Server Configuration</A></H3>
+<H3><A NAME="Server Configuration">14.2.1. Server Configuration</A></H3>
 <P>The configuration directives for slapd belong in the global directives section of <EM>slapd.conf</EM>(5).</P>
-<H4><A NAME="TLSCACertificateFile &lt;filename&gt;">12.2.1.1. TLSCACertificateFile &lt;filename&gt;</A></H4>
+<H4><A NAME="TLSCACertificateFile &lt;filename&gt;">14.2.1.1. TLSCACertificateFile &lt;filename&gt;</A></H4>
 <P>This directive specifies the <TERM>PEM</TERM>-format file containing certificates for the CA's that slapd will trust. The certificate for the CA that signed the server certificate must be included among these certificates. If the signing CA was not a top-level (root) CA, certificates for the entire sequence of CA's from the signing CA to the top-level CA should be present. Multiple certificates are simply appended to the file; the order is not significant.</P>
-<H4><A NAME="TLSCACertificatePath &lt;path&gt;">12.2.1.2. TLSCACertificatePath &lt;path&gt;</A></H4>
+<H4><A NAME="TLSCACertificatePath &lt;path&gt;">14.2.1.2. TLSCACertificatePath &lt;path&gt;</A></H4>
 <P>This directive specifies the path of a directory that contains individual <TERM>CA</TERM> certificates in separate files.  In addition, this directory must be specially managed using the OpenSSL <EM>c_rehash</EM> utility. When using this feature, the OpenSSL library will attempt to locate certificate files based on a hash of their name and serial number. The <EM>c_rehash</EM> utility is used to generate symbolic links with the hashed names that point to the actual certificate files. As such, this option can only be used with a filesystem that actually supports symbolic links. In general, it is simpler to use the <TT>TLSCACertificateFile</TT> directive instead.</P>
-<H4><A NAME="TLSCertificateFile &lt;filename&gt;">12.2.1.3. TLSCertificateFile &lt;filename&gt;</A></H4>
+<H4><A NAME="TLSCertificateFile &lt;filename&gt;">14.2.1.3. TLSCertificateFile &lt;filename&gt;</A></H4>
 <P>This directive specifies the file that contains the slapd server certificate. Certificates are generally public information and require no special protection.</P>
-<H4><A NAME="TLSCertificateKeyFile &lt;filename&gt;">12.2.1.4. TLSCertificateKeyFile &lt;filename&gt;</A></H4>
+<H4><A NAME="TLSCertificateKeyFile &lt;filename&gt;">14.2.1.4. TLSCertificateKeyFile &lt;filename&gt;</A></H4>
 <P>This directive specifies the file that contains the private key that matches the certificate stored in the <TT>TLSCertificateFile</TT> file. Private keys themselves are sensitive data and are usually password encrypted for protection. However, the current implementation doesn't support encrypted keys so the key must not be encrypted and the file itself must be protected carefully.</P>
-<H4><A NAME="TLSCipherSuite &lt;cipher-suite-spec&gt;">12.2.1.5. TLSCipherSuite &lt;cipher-suite-spec&gt;</A></H4>
+<H4><A NAME="TLSCipherSuite &lt;cipher-suite-spec&gt;">14.2.1.5. TLSCipherSuite &lt;cipher-suite-spec&gt;</A></H4>
 <P>This directive configures what ciphers will be accepted and the preference order. <TT>&lt;cipher-suite-spec&gt;</TT> should be a cipher specification for OpenSSL. You can use the command</P>
 <PRE>
         openssl ciphers -v ALL
 </PRE>
 <P>to obtain a verbose list of available cipher specifications. Besides the individual cipher names, the specifiers <TT>HIGH</TT>, <TT>MEDIUM</TT>, <TT>LOW</TT>, <TT>EXPORT</TT>, and <TT>EXPORT40</TT> may be helpful, along with <TT>TLSv1</TT>, <TT>SSLv3</TT>, and <TT>SSLv2</TT>.</P>
-<H4><A NAME="TLSRandFile &lt;filename&gt;">12.2.1.6. TLSRandFile &lt;filename&gt;</A></H4>
-<P>This directive specifies the file to obtain random bits from when <TT>/dev/urandom</TT> is not available. If the system provides <TT>/dev/urandom</TT> then this option is not needed, otherwise a source of random data must be configured. Some systems (e.g. Linux) provide <TT>/dev/urandom</TT> by default, while others (e.g. Solaris) require the installation of a patch to provide it, and others may not support it at all. In the latter case, EGD or PRNGD should be installed, and this directive should specify the name of the EGD/PRNGD socket. The environment variable <TT>RANDFILE</TT> can also be used to specify the filename. Also, in the absence of these options, the <TT>.rnd</TT> file in the slapd user's home directory may be used if it exists. To use the <TT>.rnd</TT> file, just create the file and copy a few hundred bytes of arbitrary data into the file. The file is only used to provide a seed for the pseudo-random number generator, and it doesn't need very much data to work.</P>
-<H4><A NAME="TLSEphemeralDHParamFile &lt;filename&gt;">12.2.1.7. TLSEphemeralDHParamFile &lt;filename&gt;</A></H4>
-<P>This directive specifies the file that contains parameters for Diffie-Hellman ephemeral key exchange.  This is required in order to use a DSA certificate on the server side (i.e. <TT>TLSCertificateKeyFile</TT> points to a DSA key). Multiple sets of parameters can be included in the file; all of them will be processed.  Parameters can be generated using the following command</P>
+<H4><A NAME="TLSRandFile &lt;filename&gt;">14.2.1.6. TLSRandFile &lt;filename&gt;</A></H4>
+<P>This directive specifies the file to obtain random bits from when <TT>/dev/urandom</TT> is not available. If the system provides <TT>/dev/urandom</TT> then this option is not needed, otherwise a source of random data must be configured.  Some systems (e.g. Linux) provide <TT>/dev/urandom</TT> by default, while others (e.g. Solaris) require the installation of a patch to provide it, and others may not support it at all. In the latter case, EGD or PRNGD should be installed, and this directive should specify the name of the EGD/PRNGD socket. The environment variable <TT>RANDFILE</TT> can also be used to specify the filename. Also, in the absence of these options, the <TT>.rnd</TT> file in the slapd user's home directory may be used if it exists. To use the <TT>.rnd</TT> file, just create the file and copy a few hundred bytes of arbitrary data into the file. The file is only used to provide a seed for the pseudo-random number generator, and it doesn't need very much data to work.</P>
+<H4><A NAME="TLSEphemeralDHParamFile &lt;filename&gt;">14.2.1.7. TLSEphemeralDHParamFile &lt;filename&gt;</A></H4>
+<P>This directive specifies the file that contains parameters for Diffie-Hellman ephemeral key exchange.  This is required in order to use a DSA certificate on the server side (i.e. <TT>TLSCertificateKeyFile</TT> points to a DSA key).  Multiple sets of parameters can be included in the file; all of them will be processed.  Parameters can be generated using the following command</P>
 <PRE>
         openssl dhparam [-dsaparam] -out &lt;filename&gt; &lt;numbits&gt;
 </PRE>
-<H4><A NAME="TLSVerifyClient { never | allow | try | demand }">12.2.1.8. TLSVerifyClient { never | allow | try | demand }</A></H4>
+<H4><A NAME="TLSVerifyClient { never | allow | try | demand }">14.2.1.8. TLSVerifyClient { never | allow | try | demand }</A></H4>
 <P>This directive specifies what checks to perform on client certificates in an incoming TLS session, if any. This option is set to <TT>never</TT> by default, in which case the server never asks the client for a certificate. With a setting of <TT>allow</TT> the server will ask for a client certificate; if none is provided the session proceeds normally. If a certificate is provided but the server is unable to verify it, the certificate is ignored and the session proceeds normally, as if no certificate had been provided. With a setting of <TT>try</TT> the certificate is requested, and if none is provided, the session proceeds normally. If a certificate is provided and it cannot be verified, the session is immediately terminated. With a setting of <TT>demand</TT> the certificate is requested and a valid certificate must be provided, otherwise the session is immediately terminated.</P>
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>The server must request a client certificate in order to use the SASL EXTERNAL authentication mechanism with a TLS session. As such, a non-default <TT>TLSVerifyClient</TT> setting must be configured before SASL EXTERNAL authentication may be attempted, and the SASL EXTERNAL mechanism will only be offered to the client if a valid client certificate was received.
 <HR WIDTH="80%" ALIGN="Left"></P>
-<H3><A NAME="Client Configuration">12.2.2. Client Configuration</A></H3>
+<H3><A NAME="Client Configuration">14.2.2. Client Configuration</A></H3>
 <P>Most of the client configuration directives parallel the server directives. The names of the directives are different, and they go into <EM>ldap.conf</EM>(5) instead of <EM>slapd.conf</EM>(5), but their functionality is mostly the same. Also, while most of these options may be configured on a system-wide basis, they may all be overridden by individual users in their <EM>.ldaprc</EM> files.</P>
-<P>The LDAP Start TLS operation is used in LDAP to initiate TLS negotatation.  All OpenLDAP command line tools support a <E>-Z</E> and <E>-ZZ</E> flag to indicate whether a Start TLS operation is to be issued.  The latter flag indicates that the tool is to cease processing if TLS cannot be started while the former allows the command to continue.</P>
-<P>In LDAPv2 environments, TLS is normally started using the LDAP Secure URI scheme (<TT>ldaps://</TT>) instead of the normal LDAP URI scheme (<TT>ldap://</TT>).  OpenLDAP command line tools allow either scheme to used with the <TT>-U</TT> flag and with the <TT>URI</TT> <EM>ldap.conf</EM>(5) option.</P>
-<H4><A NAME="TLS_CACERT &lt;filename&gt;">12.2.2.1. TLS_CACERT &lt;filename&gt;</A></H4>
+<P>The LDAP Start TLS operation is used in LDAP to initiate TLS negotiation.  All OpenLDAP command line tools support a <TT>-Z</TT> and <TT>-ZZ</TT> flag to indicate whether a Start TLS operation is to be issued.  The latter flag indicates that the tool is to cease processing if TLS cannot be started while the former allows the command to continue.</P>
+<P>In LDAPv2 environments, TLS is normally started using the LDAP Secure URI scheme (<TT>ldaps://</TT>) instead of the normal LDAP URI scheme (<TT>ldap://</TT>).  OpenLDAP command line tools allow either scheme to used with the <TT>-H</TT> flag and with the <TT>URI</TT> <EM>ldap.conf</EM>(5) option.</P>
+<H4><A NAME="TLS_CACERT &lt;filename&gt;">14.2.2.1. TLS_CACERT &lt;filename&gt;</A></H4>
 <P>This is equivalent to the server's <TT>TLSCACertificateFile</TT> option. As noted in the <A HREF="#TLS Configuration">TLS Configuration</A> section, a client typically may need to know about more CAs than a server, but otherwise the same considerations apply.</P>
-<H4><A NAME="TLS_CACERTDIR &lt;path&gt;">12.2.2.2. TLS_CACERTDIR &lt;path&gt;</A></H4>
+<H4><A NAME="TLS_CACERTDIR &lt;path&gt;">14.2.2.2. TLS_CACERTDIR &lt;path&gt;</A></H4>
 <P>This is equivalent to the server's <TT>TLSCACertificatePath</TT> option. The specified directory must be managed with the OpenSSL <EM>c_rehash</EM> utility as well.</P>
-<H4><A NAME="TLS_CERT &lt;filename&gt;">12.2.2.3. TLS_CERT &lt;filename&gt;</A></H4>
+<H4><A NAME="TLS_CERT &lt;filename&gt;">14.2.2.3. TLS_CERT &lt;filename&gt;</A></H4>
 <P>This directive specifies the file that contains the client certificate. This is a user-only directive and can only be specified in a user's <EM>.ldaprc</EM> file.</P>
-<H4><A NAME="TLS_KEY &lt;filename&gt;">12.2.2.4. TLS_KEY &lt;filename&gt;</A></H4>
+<H4><A NAME="TLS_KEY &lt;filename&gt;">14.2.2.4. TLS_KEY &lt;filename&gt;</A></H4>
 <P>This directive specifies the file that contains the private key that matches the certificate stored in the <TT>TLS_CERT</TT> file. The same constraints mentioned for <TT>TLSCertificateKeyFile</TT> apply here. This is also a user-only directive.</P>
-<H4><A NAME="TLS_RANDFILE &lt;filename&gt;">12.2.2.5. TLS_RANDFILE &lt;filename&gt;</A></H4>
+<H4><A NAME="TLS_RANDFILE &lt;filename&gt;">14.2.2.5. TLS_RANDFILE &lt;filename&gt;</A></H4>
 <P>This directive is the same as the server's <TT>TLSRandFile</TT> option.</P>
-<H4><A NAME="TLS_REQCERT { never | allow | try | demand }">12.2.2.6. TLS_REQCERT { never | allow | try | demand }</A></H4>
+<H4><A NAME="TLS_REQCERT { never | allow | try | demand }">14.2.2.6. TLS_REQCERT { never | allow | try | demand }</A></H4>
 <P>This directive is equivalent to the server's <TT>TLSVerifyClient</TT> option. However, for clients the default value is <TT>demand</TT> and there generally is no good reason to change this setting.</P>
 <P></P>
 <HR>
-<H1><A NAME="Constructing a Distributed Directory Service">13. Constructing a Distributed Directory Service</A></H1>
+<H1><A NAME="Constructing a Distributed Directory Service">15. Constructing a Distributed Directory Service</A></H1>
 <P>For many sites, running one or more <EM>slapd</EM>(8) that hold an entire subtree of data is sufficient. But often it is desirable to have one <EM>slapd</EM> refer to other directory services for a certain part of the tree (which may or may not be running <EM>slapd</EM>).</P>
 <P><EM>slapd</EM> supports <EM>subordinate</EM> and <EM>superior</EM> knowledge information. Subordinate knowledge information is held in <TT>referral</TT> objects (<A HREF="http://www.rfc-editor.org/rfc/rfc3296.txt">RFC3296</A>).</P>
-<H2><A NAME="Subordinate Knowledge Information">13.1. Subordinate Knowledge Information</A></H2>
+<H2><A NAME="Subordinate Knowledge Information">15.1. Subordinate Knowledge Information</A></H2>
 <P>Subordinate knowledge information may be provided to delegate a subtree. Subordinate knowledge information is maintained in the directory as a special <EM>referral</EM> object at the delegate point. The referral object acts as a delegation point, gluing two services together. This mechanism allows for hierarchical directory services to be constructed.</P>
 <P>A referral object has a structural object class of <TT>referral</TT> and has the same <TERM>Distinguished Name</TERM> as the delegated subtree.  Generally, the referral object will also provide the auxiliary object class <TT>extensibleObject</TT>. This allows the entry to contain appropriate <TERM>Relative Distinguished Name</TERM> values.  This is best demonstrated by example.</P>
 <P>If the server <TT>a.example.net</TT> holds <TT>dc=example,dc=net</TT> and wished to delegate the subtree <TT>ou=subtree,dc=example,dc=net</TT> to another server <TT>b.example.net</TT>, the following named referral object would be added to <TT>a.example.net</TT>:</P>
@@ -4031,8 +5066,8 @@
         ref: ldap://b.example.net/dc=subtree,dc=example,dc=net
 </PRE>
 <P>The server uses this information to generate referrals and search continuations to subordinate servers.</P>
-<P>For those familiar with X.500, a <EM>named referral</EM> object is similar to an X.500 knowledge reference held in a <EM>subr</EM> <TERM>DSE</TERM>.</P>
-<H2><A NAME="Superior Knowledge Information">13.2. Superior Knowledge Information</A></H2>
+<P>For those familiar with <TERM>X.500</TERM>, a <EM>named referral</EM> object is similar to an X.500 knowledge reference held in a <EM>subr</EM> <TERM>DSE</TERM>.</P>
+<H2><A NAME="Superior Knowledge Information">15.2. Superior Knowledge Information</A></H2>
 <P>Superior knowledge information may be specified using the <TT>referral</TT> directive.  The value is a list of <TERM>URI</TERM>s referring to superior directory services.  For servers without immediate superiors, such as for <TT>a.example.net</TT> in the example above, the server can be configured to use a directory service with <EM>global knowledge</EM>, such as the <EM>OpenLDAP Root Service</EM> (<A HREF="http://www.openldap.org/faq/index.cgi?file=393">http://www.openldap.org/faq/index.cgi?file=393</A>).</P>
 <PRE>
         referral        ldap://root.openldap.org/
@@ -4042,8 +5077,8 @@
         referral        ldap://a.example.net/
 </PRE>
 <P>The server uses this information to generate referrals for operations acting upon entries not within or subordinate to any of the naming contexts held by the server.</P>
-<P>For those familiar with X.500, this use of the <TT>ref</TT> attribute is similar to an X.500 knowledge reference held in a <EM>Supr</EM> <TERM>DSE</TERM>.</P>
-<H2><A NAME="The ManageDsaIT Control">13.3. The ManageDsaIT Control</A></H2>
+<P>For those familiar with <TERM>X.500</TERM>, this use of the <TT>ref</TT> attribute is similar to an X.500 knowledge reference held in a <EM>Supr</EM> <TERM>DSE</TERM>.</P>
+<H2><A NAME="The ManageDsaIT Control">15.3. The ManageDsaIT Control</A></H2>
 <P>Adding, modifying, and deleting referral objects is generally done using <EM>ldapmodify</EM>(1) or similar tools which support the ManageDsaIT control.  The ManageDsaIT control informs the server that you intend to manage the referral object as a regular entry.  This keeps the server from sending a referral result for requests which interrogate or update referral objects.</P>
 <P>The ManageDsaIT control should not be specified when managing regular entries.</P>
 <P>The <TT>-M</TT> option of <EM>ldapmodify</EM>(1) (and other tools) enables ManageDsaIT.  For example:</P>
@@ -4057,196 +5092,134 @@
 <P><HR WIDTH="80%" ALIGN="Left">
 <STRONG>Note: </STRONG>the <TT>ref</TT> attribute is operational and must be explicitly requested when desired in search results.
 <HR WIDTH="80%" ALIGN="Left"></P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>the use of referrals to construct a Distributed Directory Service is extremely clumsy and not well supported by common clients. If an existing installation has already been built using referrals, the use of the <EM>chain</EM> overlay to hide the referrals will greatly improve the usability of the Directory system. A better approach would be to use explicitly defined local and proxy databases in <EM>subordinate</EM> configurations to provide a seamless view of the Distributed Directory.
+<HR WIDTH="80%" ALIGN="Left"></P>
 <P></P>
 <HR>
-<H1><A NAME="Replication with slurpd">14. Replication with slurpd</A></H1>
-<P>In certain configurations, a single <EM>slapd</EM>(8) instance may be insufficient to handle the number of clients requiring directory service via LDAP. It may become necessary to run more than one slapd instance.  At many sites, for instance, there are multiple slapd servers: one master and one or more slaves.  <TERM>DNS</TERM> can be setup such that a lookup of <TT>ldap.example.com</TT> returns the <TERM>IP</TERM> addresses of these servers, distributing the load among them (or just the slaves). This master/slave arrangement provides a simple and effective way to increase capacity, availability and reliability.</P>
-<P><EM>slurpd</EM>(8) provides the capability for a master slapd to propagate changes to slave slapd instances, implementing the master/slave replication scheme described above.  slurpd runs on the same host as the master slapd instance.</P>
-<H2><A NAME="Overview">14.1. Overview</A></H2>
-<P><EM>slurpd</EM>(8) provides replication services &quot;in band&quot;. That is, it uses the LDAP protocol to update a slave database from the master. Perhaps the easiest way to illustrate this is with an example. In this example, we trace the propagation of an LDAP modify operation from its initiation by the LDAP client to its distribution to the slave slapd instance.</P>
-<P><B>Sample replication scenario:</B></P>
-<OL>
-<LI>The LDAP client submits an LDAP modify operation to the slave slapd.
-<LI>The slave slapd returns a referral to the LDAP client referring the client to the master slapd.
-<LI>The LDAP client submits the LDAP modify operation to the master slapd.
-<LI>The master slapd performs the modify operation, writes out the change to its replication log file and returns a success code to the client.
-<LI>The slurpd process notices that a new entry has been appended to the replication log file, reads the replication log entry, and sends the change to the slave slapd via LDAP.
-<LI>The slave slapd performs the modify operation and returns a success code to the slurpd process.</OL>
-<P><HR WIDTH="80%" ALIGN="Left">
-<STRONG>Note: </STRONG><EM>ldapmodify</EM>(1) and other clients distributed as part of OpenLDAP Software do not support automatic referral chasing (for security reasons).
-<HR WIDTH="80%" ALIGN="Left"></P>
-<H2><A NAME="Replication Logs">14.2. Replication Logs</A></H2>
-<P>When slapd is configured to generate a replication logfile, it writes out a file containing <TERM>LDIF</TERM> change records.  The replication log gives the replication site(s), a timestamp, the DN of the entry being modified, and a series of lines which specify the changes to make. In the example below, Barbara (<TT>uid=bjensen</TT>) has replaced the <TT>description</TT> value.  The change is to be propagated to the slapd instance running on <TT>slave.example.net</TT> Changes to various operational attributes, such as <TT>modifiersName</TT> and <TT>modifyTimestamp</TT>, are included in the change record and will be propagated to the slave slapd.</P>
+<H1><A NAME="Replication">16. Replication</A></H1>
+<P>Replicated directories are a fundamental requirement for delivering a resilient enterprise deployment.</P>
+<P><A HREF="http://www.openldap.org/">OpenLDAP</A> has various configuration options for creating a replicated directory. The following sections will discuss these.</P>
+<H2><A NAME="Replication Strategies">16.1. Replication Strategies</A></H2>
+<H3><A NAME="Push Based">16.1.1. Push Based</A></H3>
+<H5><A NAME="Replacing Slurpd">16.1.1..1. Replacing Slurpd</A></H5>
+<P><EM>Slurpd</EM> replication has been deprecated in favor of Syncrepl replication and has been completely removed from OpenLDAP 2.4.</P>
+<P><EM>Why was it replaced?</EM></P>
+<P>The <EM>slurpd</EM> daemon was the original replication mechanism inherited from UMich's LDAP and operates in push mode: the master pushes changes to the slaves. It has been replaced for many reasons, in brief:</P>
+<UL>
+<LI>It is not reliable
+<LI>It is extremely sensitive to the ordering of records in the replog
+<LI>It can easily go out of sync, at which point manual intervention is required to resync the slave database with the master directory
+<LI>It isn't very tolerant of unavailable servers. If a slave goes down for a long time, the replog may grow to a size that's too large for slurpd to process</UL>
+<P><EM>What was it replaced with?</EM></P>
+<P>Syncrepl</P>
+<P><EM>Why is Syncrepl better?</EM></P>
+<UL>
+<LI>Syncrepl is self-synchronizing; you can start with a database in any state from totally empty to fully synced and it will automatically do the right thing to achieve and maintain synchronization
+<LI>Syncrepl can operate in either direction
+<LI>Data updates can be minimal or maximal</UL>
+<P><EM>How do I implement a pushed based replication system using Syncrepl?</EM></P>
+<P>The easiest way is to point an LDAP backend (<A HREF="#Backends">Backends</A> and <EM>slapd-ldap(8)</EM>) to your slave directory and setup Syncrepl to point to your Master database.</P>
+<P>REFERENCE test045/048 for better explanation of above.</P>
+<P>If you imagine Syncrepl pulling down changes from the Master server, and then pushing those changes out to your slave servers via <EM>slapd-ldap(8)</EM>. This is called proxy mode (elaborate/confirm?).</P>
+<P>DIAGRAM HERE</P>
+<P>BETTER EXAMPLE here from test045/048 for different push/multiproxy examples.</P>
+<P>Here's an example:</P>
 <PRE>
-        replica: slave.example.com:389
-        time: 809618633
-        dn: uid=bjensen,dc=example,dc=com
-        changetype: modify
-        replace: multiLineDescription
-        description: A dreamer...
-        -
-        replace: modifiersName
-        modifiersName: uid=bjensen,dc=example,dc=com
-        -
-        replace: modifyTimestamp
-        modifyTimestamp: 20000805073308Z
-        -
-</PRE>
-<P>The modifications to <TT>modifiersName</TT> and <TT>modifyTimestamp</TT> operational attributes were added by the master <EM>slapd</EM>.</P>
-<H2><A NAME="Command-Line Options">14.3. Command-Line Options</A></H2>
-<P>This section details commonly used <EM>slurpd</EM>(8) command-line options.</P>
-<PRE>
-        -d &lt;level&gt; | ?
-</PRE>
-<P>This option sets the slurpd debug level to <TT> &lt;level&gt;</TT>. When level is a `?' character, the various debugging levels are printed and slurpd exits, regardless of any other options you give it. Current debugging levels (a subset of slapd's debugging levels) are</P>
-<TABLE CLASS="columns" BORDER ALIGN='Center'>
-<CAPTION ALIGN=top>Table 13.1: Debugging Levels</CAPTION>
-<TR CLASS="heading">
-<TD ALIGN='Right'>
-<STRONG>Level</STRONG>
-</TD>
-<TD ALIGN='Left'>
-<STRONG>Description</STRONG>
-</TD>
-</TR>
-<TR>
-<TD ALIGN='Right'>
-4
-</TD>
-<TD ALIGN='Left'>
-heavy trace debugging
-</TD>
-</TR>
-<TR>
-<TD ALIGN='Right'>
-64
-</TD>
-<TD ALIGN='Left'>
-configuration file processing
-</TD>
-</TR>
-<TR>
-<TD ALIGN='Right'>
-65535
-</TD>
-<TD ALIGN='Left'>
-enable all debugging
-</TD>
-</TR>
-</TABLE>
+        include         ./schema/core.schema
+        include         ./schema/cosine.schema
+        include         ./schema/inetorgperson.schema
+        include         ./schema/openldap.schema
+        include         ./schema/nis.schema
 
-<P>Debugging levels are additive. That is, if you want heavy trace debugging and want to watch the config file being processed, you would set level to the sum of those two levels (in this case, 68).</P>
-<PRE>
-        -f &lt;filename&gt;
+        pidfile         /home/ghenry/openldap/ldap/tests/testrun/slapd.3.pid
+        argsfile        /home/ghenry/openldap/ldap/tests/testrun/slapd.3.args
+
+        modulepath      ../servers/slapd/back-bdb/
+        moduleload      back_bdb.la
+        modulepath  ../servers/slapd/back-monitor/
+        moduleload  back_monitor.la
+        modulepath  ../servers/slapd/overlays/
+        moduleload  syncprov.la
+        modulepath  ../servers/slapd/back-ldap/
+        moduleload  back_ldap.la
+
+        # We don't need any access to this DSA
+        restrict        all
+
+        #######################################################################
+        # consumer proxy database definitions
+        #######################################################################
+
+        database        ldap
+        suffix          &quot;dc=example,dc=com&quot;
+        rootdn          &quot;cn=Whoever&quot;
+        uri             ldap://localhost:9012/
+
+        lastmod         on
+
+        # HACK: use the RootDN of the monitor database as UpdateDN so ACLs apply
+        # without the need to write the UpdateDN before starting replication
+        acl-bind        bindmethod=simple
+                        binddn=&quot;cn=Monitor&quot;
+                        credentials=monitor
+
+        # HACK: use the RootDN of the monitor database as UpdateDN so ACLs apply
+        # without the need to write the UpdateDN before starting replication
+        syncrepl        rid=1
+                        provider=ldap://localhost:9011/
+                        binddn=&quot;cn=Manager,dc=example,dc=com&quot;
+                        bindmethod=simple
+                        credentials=secret
+                        searchbase=&quot;dc=example,dc=com&quot;
+                        filter=&quot;(objectClass=*)&quot;
+                        attrs=&quot;*,structuralObjectClass,entryUUID,entryCSN,creatorsName,createTimestamp,modifiersName,modifyTimestamp&quot;
+                        schemachecking=off
+                        scope=sub
+                        type=refreshAndPersist
+                        retry=&quot;5 5 300 5&quot;
+
+        overlay         syncprov
+
+        database        monitor
 </PRE>
-<P>This option specifies an alternate slapd configuration file.  Slurpd does not have its own configuration file. Instead, all configuration information is read from the slapd configuration file.</P>
-<PRE>
-        -r &lt;filename&gt;
-</PRE>
-<P>This option specifies an alternate slapd replication log file. Under normal circumstances, slurpd reads the name of the slapd replication log file from the slapd configuration file. However, you can override this with the -r flag, to cause slurpd to process a different replication log file. See the <A HREF="#Advanced slurpd Operation">Advanced slurpd Operation</A> section for a discussion of how you might use this option.</P>
-<PRE>
-        -o
-</PRE>
-<P>Operate in &quot;one-shot&quot; mode. Under normal circumstances, when slurpd finishes processing a replication log, it remains active and periodically checks to see if new entries have been added to the replication log.  In one-shot mode, by comparison, slurpd processes a replication log and exits immediately. If the -o option is given, the replication log file must be explicitly specified with the -r option.  See the <A HREF="#One-shot mode and reject files">One-shot mode and reject files</A> section for  a discussion of this mode.</P>
-<PRE>
-        -t &lt;directory&gt;
-</PRE>
-<P>Specify an alternate directory for slurpd's temporary copies of replication logs. The default location is <TT>/usr/tmp</TT>.</P>
-<H2><A NAME="Configuring slurpd and a slave slapd instance">14.4. Configuring slurpd and a slave slapd instance</A></H2>
-<P>To bring up a replica slapd instance, you must configure the master and slave slapd instances for replication, then shut down the master slapd so you can copy the database. Finally, you bring up the master slapd instance, the slave slapd instance, and the slurpd instance. These steps are detailed in the following sections. You can set up as many slave slapd instances as you wish.</P>
-<H3><A NAME="Set up the master {{slapd}}">14.4.1. Set up the master <EM>slapd</EM></A></H3>
-<P>The following section assumes you have a properly working <EM>slapd</EM>(8) instance. To configure your working <EM>slapd</EM>(8) server as a replication master, you need to make the following changes to your <EM>slapd.conf</EM>(5).</P>
-<OL>
-<LI>Add a <TT>replica</TT> directive for each replica. The <TT>binddn=</TT> parameter should match the <TT>updatedn</TT> option in the corresponding slave slapd configuration file, and should name an entry with write permission to the slave database (e.g., an entry allowed access via <TT>access</TT> directives in the slave slapd configuration file). This DN generally <EM>should not</EM> be the same as the master's <TT>rootdn</TT>.
-<LI>Add a <TT>replogfile</TT> directive, which tells slapd where to log changes. This file will be read by slurpd.</OL>
-<H3><A NAME="Set up the slave {{slapd}}">14.4.2. Set up the slave <EM>slapd</EM></A></H3>
-<P>Install the slapd software on the host which is to be the slave slapd server. The configuration of the slave server should be identical to that of the master, with the following exceptions:</P>
-<OL>
-<LI>Do not include a <TT>replica</TT> directive. While it is possible to create &quot;chains&quot; of replicas, in most cases this is inappropriate.
-<LI>Do not include a <TT>replogfile</TT> directive.
-<LI>Do include an <TT>updatedn</TT> line. The DN given should match the DN given in the <TT>binddn=</TT> parameter of the corresponding <TT>replica=</TT> directive in the master slapd config file.  The <TT>updatedn</TT> generally <EM>should not</EM> be the same as the <TT>rootdn</TT> of the master database.
-<LI>Make sure the DN given in the <TT>updatedn</TT> directive has permission to write the database (e.g., it is is allowed <TT>access</TT> by one or more access directives).
-<LI>Use the <TT>updateref</TT> directive to define the URL the slave should return if an update request is received.</OL>
-<H3><A NAME="Shut down the master server">14.4.3. Shut down the master server</A></H3>
-<P>In order to ensure that the slave starts with an exact copy of the master's data, you must shut down the master slapd. Do this by sending the master slapd process an interrupt signal with <TT>kill -INT &lt;pid&gt;</TT>, where <TT>&lt;pid&gt;</TT> is the process-id of the master slapd process.</P>
-<P>If you like, you may restart the master slapd in read-only mode while you are replicating the database. During this time, the master slapd will return an &quot;unwilling to perform&quot; error to clients that attempt to modify data.</P>
-<H3><A NAME="Copy the master slapd\'s database to the slave">14.4.4. Copy the master slapd's database to the slave</A></H3>
-<P>Copy the master's database(s) to the slave. For an <TERM>BDB</TERM> and <TERM>LDBM</TERM> databases, you must copy all database files located in the database <TT>directory</TT> specified in <EM>slapd.conf</EM>(5). In general, you should copy each file found in the database <TT> directory</TT> unless you know it is not used by <EM>slapd</EM>(8).</P>
-<P><HR WIDTH="80%" ALIGN="Left">
-<STRONG>Note: </STRONG>This copy process assumes homogeneous servers with identically configured OpenLDAP installations. Alternatively, you may use <EM>slapcat</EM> to output the master's database in LDIF format and use the LDIF with <EM>slapadd</EM> to populate the slave. Using LDIF avoids any potential incompatibilities due to differing server architectures or software configurations.  See the <A HREF="#Database Creation and Maintenance Tools">Database Creation and Maintenance Tools</A> chapter for details on these tools.
-<HR WIDTH="80%" ALIGN="Left"></P>
-<H3><A NAME="Configure the master slapd for replication">14.4.5. Configure the master slapd for replication</A></H3>
-<P>To configure slapd to generate a replication logfile, you add a &quot;<TT> replica</TT>&quot; configuration option to the master slapd's config file. For example, if we wish to propagate changes to the slapd instance running on host <TT>slave.example.com</TT>:</P>
-<PRE>
-        replica uri=ldap://slave.example.com:389
-                binddn=&quot;cn=Replicator,dc=example,dc=com&quot;
-                bindmethod=simple credentials=secret
-</PRE>
-<P>In this example, changes will be sent to port 389 (the standard LDAP port) on host slave.example.com. The slurpd process will bind to the slave slapd as &quot;<TT>cn=Replicator,dc=example,dc=com</TT>&quot; using simple authentication with password &quot;<TT>secret</TT>&quot;.</P>
-<P>If we wish to perform the same replication using ldaps on port 636:</P>
-<PRE>
-        replica uri=ldaps://slave.example.com:636
-                binddn=&quot;cn=Replicator,dc=example,dc=com&quot;
-                bindmethod=simple credentials=secret
-</PRE>
-<P>The host option is deprecated in favor of uri, but the following replica configuration is still supported:</P>
-<PRE>
-        replica host=slave.example.com:389
-                binddn=&quot;cn=Replicator,dc=example,dc=com&quot;
-                bindmethod=simple credentials=secret
-</PRE>
-<P>Note that the DN given by the <TT>binddn=</TT> directive must exist in the slave slapd's database (or be the rootdn specified in the slapd config file) in order for the bind operation to succeed.  The DN should also be listed as the <TT>updatedn</TT> for the database in the slave's slapd.conf(5).  It is generally recommended that this DN be different than the <TT>rootdn</TT> of the master database.</P>
-<P><HR WIDTH="80%" ALIGN="Left">
-<STRONG>Note: </STRONG>The use of strong authentication and transport security is highly recommended.
-<HR WIDTH="80%" ALIGN="Left"></P>
-<H3><A NAME="Restart the master slapd and start the slave slapd">14.4.6. Restart the master slapd and start the slave slapd</A></H3>
-<P>Restart the master slapd process. To check that it is generating replication logs, perform a modification of any entry in the database, and check that data has been written to the log file.</P>
-<H3><A NAME="Start slurpd">14.4.7. Start slurpd</A></H3>
-<P>Start the slurpd process. Slurpd should immediately send the test modification you made to the slave slapd. Watch the slave slapd's logfile to be sure that the modification was sent.</P>
-<PRE>
-        slurpd -f &lt;masterslapdconfigfile&gt;
-</PRE>
-<H2><A NAME="Advanced slurpd Operation">14.5. Advanced slurpd Operation</A></H2>
-<H3><A NAME="Replication errors">14.5.1. Replication errors</A></H3>
-<P>When slurpd propagates a change to a slave slapd and receives an error return code, it writes the reason for the error and the replication record to a reject file. The reject file is located in the same directory as the per-replica replication logfile, and has the same name, but with the string &quot;<TT>.rej</TT>&quot; appended. For example, for a replica running on host <TT>slave.example.com</TT>, port 389, the reject file, if it exists, will be named</P>
-<PRE>
-        /usr/local/var/openldap/replog.slave.example.com:389.rej
-</PRE>
-<P>A sample rejection log entry follows:</P>
-<PRE>
-        ERROR: No such attribute
-        replica: slave.example.com:389
-        time: 809618633
-        dn: uid=bjensen,dc=example,dc=com
-        changetype: modify
-        replace: description
-        description: A dreamer...
-        -
-        replace: modifiersName
-        modifiersName: uid=bjensen,dc=example,dc=com
-        -
-        replace: modifyTimestamp
-        modifyTimestamp: 20000805073308Z
-        -
-</PRE>
-<P>Note that this is precisely the same format as the original replication log entry, but with an <TT>ERROR</TT> line prepended to the entry.</P>
-<H3><A NAME="One-shot mode and reject files">14.5.2. One-shot mode and reject files</A></H3>
-<P>It is possible to use slurpd to process a rejection log with its &quot;one-shot mode.&quot; In normal operation, slurpd watches for more replication records to be appended to the replication log file. In one-shot mode, by contrast, slurpd processes a single log file and exits. Slurpd ignores <TT>ERROR</TT> lines at the beginning of replication log entries, so it's not necessary to edit them out before feeding it the rejection log.</P>
-<P>To use one-shot mode, specify the name of the rejection log on the command line as the argument to the -r flag, and specify one-shot mode with the -o flag. For example, to process the rejection log file <TT>/usr/local/var/openldap/replog.slave.example.com:389</TT> and exit, use the command</P>
-<PRE>
-        slurpd -r /usr/tmp/replog.slave.example.com:389 -o
-</PRE>
-<P></P>
-<HR>
-<H1><A NAME="LDAP Sync Replication">15. LDAP Sync Replication</A></H1>
-<P>The LDAP Sync replication engine, syncrepl for short, is a consumer-side replication engine that enables the consumer LDAP server to maintain a shadow copy of a DIT fragment. A syncrepl engine resides at the consumer-side as one of the <EM>slapd</EM> (8) threads. It creates and maintains a consumer replica by connecting to the replication provider to perform the initial DIT content load followed either by periodic content polling or by timely updates upon content changes.</P>
+<P>DETAILED EXPLANATION OF ABOVE LIKE IN OTHER SECTIONS (line numbers?)</P>
+<P>ANOTHER DIAGRAM HERE</P>
+<P>As you can see, you can let your imagination go wild using Syncrepl and <EM>slapd-ldap(8)</EM> tailoring your replication to fit your specific network topology.</P>
+<H3><A NAME="Pull Based">16.1.2. Pull Based</A></H3>
+<H4><A NAME="syncrepl replication">16.1.2.1. syncrepl replication</A></H4>
+<H4><A NAME="delta-syncrepl replication">16.1.2.2. delta-syncrepl replication</A></H4>
+<H2><A NAME="Replication Types">16.2. Replication Types</A></H2>
+<H3><A NAME="syncrepl replication">16.2.1. syncrepl replication</A></H3>
+<H3><A NAME="delta-syncrepl replication">16.2.2. delta-syncrepl replication</A></H3>
+<H3><A NAME="N-Way Multi-Master replication">16.2.3. N-Way Multi-Master replication</A></H3>
+<P>Multi-Master replication is a replication technique using Syncrepl to replicate data to multiple Master Directory servers.</P>
+<UL>
+<LI>Advantages of Multi-Master replication:<UL>
+<LI>If any master fails, other masters will continue to accept updates
+<LI>Avoids a single point of failure
+<LI>Masters can be located in several physical sites i.e. distributed across the network/globe.
+<LI>Good for Automatic failover/High Availability</UL>
+<LI>Disadvantages of Multi-Master replication:<UL>
+<LI>It has <B>NOTHING</B> to do with load balancing
+<LI><A HREF="http://www.openldap.org/faq/data/cache/1240.html">http://www.openldap.org/faq/data/cache/1240.html</A>
+<LI>If connectivity with a master is lost because of a network partition, then &quot;automatic failover&quot; can just compound the problem
+<LI>Typically, a particular machine cannot distinguish between losing contact with a peer because that peer crashed, or because the network link has failed
+<LI>If a network is partitioned and multiple clients start writing to each of the &quot;masters&quot; then reconciliation will be a pain; it may be best to simply deny writes to the clients that are partitioned from the single master
+<LI>Masters <B>must</B> propagate writes to <B>all</B> the other servers, which means the network traffic and write load is constant and spreads across all of the servers</UL></UL>
+<P>This is discussed in full in the <A HREF="#N-Way Multi-Master">N-Way Multi-Master</A> section below</P>
+<H3><A NAME="MirrorMode replication">16.2.4. MirrorMode replication</A></H3>
+<P>MirrorMode is a hybrid configuration that provides all of the consistency guarantees of single-master replication, while also providing the high availability of multi-master. In MirrorMode two masters are set up to replicate from each other (as a multi-master configuration) but an external frontend is employed to direct all writes to only one of the two servers. The second master will only be used for writes if the first master crashes, at which point the frontend will switch to directing all writes to the second master. When a crashed master is repaired and restarted it will automatically catch up to any changes on the running master and resync.</P>
+<P>This is discussed in full in the <A HREF="#MirrorMode">MirrorMode</A> section below</P>
+<H2><A NAME="LDAP Sync Replication">16.3. LDAP Sync Replication</A></H2>
+<P>The <TERM>LDAP Sync</TERM> Replication engine, <TERM>syncrepl</TERM> for short, is a consumer-side replication engine that enables the consumer <TERM>LDAP</TERM> server to maintain a shadow copy of a <TERM>DIT</TERM> fragment. A syncrepl engine resides at the consumer-side as one of the <EM>slapd</EM>(8) threads. It creates and maintains a consumer replica by connecting to the replication provider to perform the initial DIT content load followed either by periodic content polling or by timely updates upon content changes.</P>
 <P>Syncrepl uses the LDAP Content Synchronization (or LDAP Sync for short) protocol as the replica synchronization protocol.  It provides a stateful replication which supports both pull-based and push-based synchronization and does not mandate the use of a history store.</P>
 <P>Syncrepl keeps track of the status of the replication content by maintaining and exchanging synchronization cookies. Because the syncrepl consumer and provider maintain their content status, the consumer can poll the provider content to perform incremental synchronization by asking for the entries required to make the consumer replica up-to-date with the provider content. Syncrepl also enables convenient management of replicas by maintaining replica status.  The consumer replica can be constructed from a consumer-side or a provider-side backup at any synchronization status. Syncrepl can automatically resynchronize the consumer replica up-to-date with the current provider content.</P>
 <P>Syncrepl supports both pull-based and push-based synchronization. In its basic refreshOnly synchronization mode, the provider uses pull-based synchronization where the consumer servers need not be tracked and no history information is maintained.  The information required for the provider to process periodic polling requests is contained in the synchronization cookie of the request itself.  To optimize the pull-based synchronization, syncrepl utilizes the present phase of the LDAP Sync protocol as well as its delete phase, instead of falling back on frequent full reloads. To further optimize the pull-based synchronization, the provider can maintain a per-scope session log as a history store. In its refreshAndPersist mode of synchronization, the provider uses a push-based synchronization. The provider keeps track of the consumer servers that have requested a persistent search and sends them necessary updates as the provider replication content gets modified.</P>
 <P>With syncrepl, a consumer server can create a replica without changing the provider's configurations and without restarting the provider server, if the consumer server has appropriate access privileges for the DIT fragment to be replicated. The consumer server can stop the replication also without the need for provider-side changes and restart.</P>
 <P>Syncrepl supports both partial and sparse replications.  The shadow DIT fragment is defined by a general search criteria consisting of base, scope, filter, and attribute list.  The replica content is also subject to the access privileges of the bind identity of the syncrepl replication connection.</P>
-<H2><A NAME="The LDAP Content Synchronization Protocol">15.1. The LDAP Content Synchronization Protocol</A></H2>
-<P>The LDAP Sync protocol allows a client to maintain a synchronized copy of a DIT fragment. The LDAP Sync operation is defined as a set of controls and other protocol elements which extend the LDAP search operation. This section introduces the LDAP Content Sync protocol only briefly. For more information, refer to the Internet Draft <EM>The LDAP Content Synchronization Operation &lt;draft-zeilenga-ldup-sync-05.txt&gt;</EM>.</P>
+<H3><A NAME="The LDAP Content Synchronization Protocol">16.3.1. The LDAP Content Synchronization Protocol</A></H3>
+<P>The LDAP Sync protocol allows a client to maintain a synchronized copy of a DIT fragment. The LDAP Sync operation is defined as a set of controls and other protocol elements which extend the LDAP search operation. This section introduces the LDAP Content Sync protocol only briefly.  For more information, refer to <A HREF="http://www.rfc-editor.org/rfc/rfc4533.txt">RFC4533</A>.</P>
 <P>The LDAP Sync protocol supports both polling and listening for changes by defining two respective synchronization operations: <EM>refreshOnly</EM> and <EM>refreshAndPersist</EM>.  Polling is implemented by the <EM>refreshOnly</EM> operation.  The client copy is synchronized to the server copy at the time of polling.  The server finishes the search operation by returning <EM>SearchResultDone</EM> at the end of the search operation as in the normal search.  The listening is implemented by the <EM>refreshAndPersist</EM> operation.  Instead of finishing the search after returning all entries currently matching the search criteria, the synchronization search remains persistent in the server. Subsequent updates to the synchronization content in the server cause additional entry updates to be sent to the client.</P>
 <P>The <EM>refreshOnly</EM> operation and the refresh stage of the <EM>refreshAndPersist</EM> operation can be performed with a present phase or a delete phase.</P>
 <P>In the present phase, the server sends the client the entries updated within the search scope since the last synchronization. The server sends all requested attributes, be it changed or not, of the updated entries.  For each unchanged entry which remains in the scope, the server sends a present message consisting only of the name of the entry and the synchronization control representing state present. The present message does not contain any attributes of the entry. After the client receives all update and present entries, it can reliably determine the new client copy by adding the entries added to the server, by replacing the entries modified at the server, and by deleting entries in the client copy which have not been updated nor specified as being present at the server.</P>
@@ -4255,11 +5228,11 @@
 <P>At the end of the <EM>refreshOnly</EM> synchronization, the server sends a synchronization cookie to the client as a state indicator of the client copy after the synchronization is completed.  The client will present the received cookie when it requests the next incremental synchronization to the server.</P>
 <P>When <EM>refreshAndPersist</EM> synchronization is used, the server sends a synchronization cookie at the end of the refresh stage by sending a Sync Info message with TRUE refreshDone.  It also sends a synchronization cookie by attaching it to <EM>SearchResultEntry</EM> generated in the persist stage of the synchronization search. During the persist stage, the server can also send a Sync Info message containing the synchronization cookie at any time the server wants to update the client-side state indicator.  The server also updates a synchronization indicator of the client at the end of the persist stage.</P>
 <P>In the LDAP Sync protocol, entries are uniquely identified by the <TT>entryUUID</TT> attribute value. It can function as a reliable identifier of the entry. The DN of the entry, on the other hand, can be changed over time and hence cannot be considered as the reliable identifier.  The <TT>entryUUID</TT> is attached to each <EM>SearchResultEntry</EM> or <EM>SearchResultReference</EM> as a part of the synchronization control.</P>
-<H2><A NAME="Syncrepl Details">15.2. Syncrepl Details</A></H2>
-<P>The syncrepl engine utilizes both the <EM>refreshOnly</EM> and the <EM>refreshAndPersist</EM> operations of the LDAP Sync protocol.  If a syncrepl specification is included in a database definition, <EM>slapd</EM> (8) launches a syncrepl engine as a <EM>slapd</EM> (8) thread and schedules its execution. If the <EM>refreshOnly</EM> operation is specified, the syncrepl engine will be rescheduled at the interval time after a synchronization operation is completed.  If the <EM>refreshAndPersist</EM> operation is specified, the engine will remain active and process the persistent synchronization messages from the provider.</P>
+<H3><A NAME="Syncrepl Details">16.3.2. Syncrepl Details</A></H3>
+<P>The syncrepl engine utilizes both the <EM>refreshOnly</EM> and the <EM>refreshAndPersist</EM> operations of the LDAP Sync protocol.  If a syncrepl specification is included in a database definition, <EM>slapd</EM>(8) launches a syncrepl engine as a <EM>slapd</EM>(8) thread and schedules its execution. If the <EM>refreshOnly</EM> operation is specified, the syncrepl engine will be rescheduled at the interval time after a synchronization operation is completed.  If the <EM>refreshAndPersist</EM> operation is specified, the engine will remain active and process the persistent synchronization messages from the provider.</P>
 <P>The syncrepl engine utilizes both the present phase and the delete phase of the refresh synchronization. It is possible to configure a per-scope session log in the provider server which stores the <TT>entryUUID</TT>s of a finite number of entries deleted from a replication content.  Multiple replicas of single provider content share the same per-scope session log. The syncrepl engine uses the delete phase if the session log is present and the state of the consumer server is recent enough that no session log entries are truncated after the last synchronization of the client.  The syncrepl engine uses the present phase if no session log is configured for the replication content or if the consumer replica is too outdated to be covered by the session log.  The current design of the session log store is memory based, so the information contained in the session log is not persistent over multiple provider invocations. It is not currently supported to access the session log store by using LDAP operations. It is also not currently supported to impose access control to the session log.</P>
 <P>As a further optimization, even in the case the synchronization search is not associated with any session log, no entries will be transmitted to the consumer server when there has been no update in the replication context.</P>
-<P>The syncrepl engine, which is a consumer-side replication engine, can work with any backends. The LDAP Sync provider can be configured as an overlay on any backend, but works best with the <EM>back-bdb</EM> or <EM>back-hdb</EM> backend. The provider can not support refreshAndPersist mode on <EM>back-ldbm</EM> due to limits in that backend's locking architecture.</P>
+<P>The syncrepl engine, which is a consumer-side replication engine, can work with any backends. The LDAP Sync provider can be configured as an overlay on any backend, but works best with the <EM>back-bdb</EM> or <EM>back-hdb</EM> backend.</P>
 <P>The LDAP Sync provider maintains a <TT>contextCSN</TT> for each database as the current synchronization state indicator of the provider content.  It is the largest <TT>entryCSN</TT> in the provider context such that no transactions for an entry having smaller <TT>entryCSN</TT> value remains outstanding.  The <TT>contextCSN</TT> could not just be set to the largest issued <TT>entryCSN</TT> because <TT>entryCSN</TT> is obtained before a transaction starts and transactions are not committed in the issue order.</P>
 <P>The provider stores the <TT>contextCSN</TT> of a context in the <TT>contextCSN</TT> attribute of the context suffix entry. The attribute is not written to the database after every update operation though; instead it is maintained primarily in memory. At database start time the provider reads the last saved <TT>contextCSN</TT> into memory and uses the in-memory copy exclusively thereafter. By default, changes to the <TT>contextCSN</TT> as a result of database updates will not be written to the database until the server is cleanly shut down. A checkpoint facility exists to cause the contextCSN to be written out more frequently if desired.</P>
 <P>Note that at startup time, if the provider is unable to read a <TT>contextCSN</TT> from the suffix entry, it will scan the entire database to determine the value, and this scan may take quite a long time on a large database. When a <TT>contextCSN</TT> value is read, the database will still be scanned for any <TT>entryCSN</TT> values greater than it, to make sure the <TT>contextCSN</TT> value truly reflects the greatest committed <TT>entryCSN</TT> in the database. On databases which support inequality indexing, setting an eq index on the <TT>entryCSN</TT> attribute and configuring <EM>contextCSN</EM> checkpoints will greatly speed up this scanning step.</P>
@@ -4267,12 +5240,12 @@
 <P>The consumer also stores its replica state, which is the provider's <TT>contextCSN</TT> received as a synchronization cookie, in the <TT>contextCSN</TT> attribute of the suffix entry.  The replica state maintained by a consumer server is used as the synchronization state indicator when it performs subsequent incremental synchronization with the provider server. It is also used as a provider-side synchronization state indicator when it functions as a secondary provider server in a cascading replication configuration.  Since the consumer and provider state information are maintained in the same location within their respective databases, any consumer can be promoted to a provider (and vice versa) without any special actions.</P>
 <P>Because a general search filter can be used in the syncrepl specification, some entries in the context may be omitted from the synchronization content.  The syncrepl engine creates a glue entry to fill in the holes in the replica context if any part of the replica content is subordinate to the holes. The glue entries will not be returned in the search result unless <EM>ManageDsaIT</EM> control is provided.</P>
 <P>Also as a consequence of the search filter used in the syncrepl specification, it is possible for a modification to remove an entry from the replication scope even though the entry has not been deleted on the provider. Logically the entry must be deleted on the consumer but in <EM>refreshOnly</EM> mode the provider cannot detect and propagate this change without the use of the session log.</P>
-<H2><A NAME="Configuring Syncrepl">15.3. Configuring Syncrepl</A></H2>
-<P>Because syncrepl is a consumer-side replication engine, the syncrepl specification is defined in <EM>slapd.conf</EM> (5) of the consumer server, not in the provider server's configuration file.  The initial loading of the replica content can be performed either by starting the syncrepl engine with no synchronization cookie or by populating the consumer replica by adding an <TERM>LDIF</TERM> file dumped as a backup at the provider.</P>
+<H3><A NAME="Configuring Syncrepl">16.3.3. Configuring Syncrepl</A></H3>
+<P>Because syncrepl is a consumer-side replication engine, the syncrepl specification is defined in <EM>slapd.conf</EM>(5) of the consumer server, not in the provider server's configuration file.  The initial loading of the replica content can be performed either by starting the syncrepl engine with no synchronization cookie or by populating the consumer replica by adding an <TERM>LDIF</TERM> file dumped as a backup at the provider.</P>
 <P>When loading from a backup, it is not required to perform the initial loading from the up-to-date backup of the provider content. The syncrepl engine will automatically synchronize the initial consumer replica to the current provider content. As a result, it is not required to stop the provider server in order to avoid the replica inconsistency caused by the updates to the provider content during the content backup and loading process.</P>
 <P>When replicating a large scale directory, especially in a bandwidth constrained environment, it is advised to load the consumer replica from a backup instead of performing a full initial load using syncrepl.</P>
-<H3><A NAME="Set up the provider slapd">15.3.1. Set up the provider slapd</A></H3>
-<P>The provider is implemented as an overlay, so the overlay itself must first be configured in <EM>slapd.conf</EM> (5) before it can be used. The provider has only two configuration directives, for setting checkpoints on the <TT>contextCSN</TT> and for configuring the session log.  Because the LDAP Sync search is subject to access control, proper access control privileges should be set up for the replicated content.</P>
+<H4><A NAME="Set up the provider slapd">16.3.3.1. Set up the provider slapd</A></H4>
+<P>The provider is implemented as an overlay, so the overlay itself must first be configured in <EM>slapd.conf</EM>(5) before it can be used. The provider has only two configuration directives, for setting checkpoints on the <TT>contextCSN</TT> and for configuring the session log.  Because the LDAP Sync search is subject to access control, proper access control privileges should be set up for the replicated content.</P>
 <P>The <TT>contextCSN</TT> checkpoint is configured by the</P>
 <PRE>
         syncprov-checkpoint &lt;ops&gt; &lt;minutes&gt;
@@ -4284,7 +5257,7 @@
 </PRE>
 <P>directive, where <EM>&lt;size&gt;</EM> is the maximum number of session log entries the session log can record. When a session log is configured, it is automatically used for all LDAP Sync searches within the database.</P>
 <P>Note that using the session log requires searching on the <EM>entryUUID</EM> attribute. Setting an eq index on this attribute will greatly benefit the performance of the session log on the provider.</P>
-<P>A more complete example of the <EM>slapd.conf</EM> content is thus:</P>
+<P>A more complete example of the <EM>slapd.conf</EM>(5) content is thus:</P>
 <PRE>
         database bdb
         suffix dc=Example,dc=com
@@ -4296,8 +5269,8 @@
         syncprov-checkpoint 100 10
         syncprov-sessionlog 100
 </PRE>
-<H3><A NAME="Set up the consumer slapd">15.3.2. Set up the consumer slapd</A></H3>
-<P>The syncrepl replication is specified in the database section of <EM>slapd.conf</EM> (5) for the replica context.  The syncrepl engine is backend independent and the directive can be defined with any database type.</P>
+<H4><A NAME="Set up the consumer slapd">16.3.3.2. Set up the consumer slapd</A></H4>
+<P>The syncrepl replication is specified in the database section of <EM>slapd.conf</EM>(5) for the replica context.  The syncrepl engine is backend independent and the directive can be defined with any database type.</P>
 <PRE>
         database hdb
         suffix dc=Example,dc=com
@@ -4318,81 +5291,3336 @@
                 binddn=&quot;cn=syncuser,dc=example,dc=com&quot;
                 credentials=secret
 </PRE>
-<P>In this example, the consumer will connect to the provider slapd at port 389 of <A HREF="ldap://provider.example.com">ldap://provider.example.com</A> to perform a polling (<EM>refreshOnly</EM>) mode of synchronization once a day.  It will bind as <TT>cn=syncuser,dc=example,dc=com</TT> using simple authentication with password &quot;secret&quot;.  Note that the access control privilege of <TT>cn=syncuser,dc=example,dc=com</TT> should be set appropriately in the provider to retrieve the desired replication content. Also the search limits must be high enough on the provider to allow the syncuser to retrieve a complete copy of the requested content.  The consumer uses the rootdn to write to its database so it always has full permissions to write all content.</P>
-<P>The synchronization search in the above example will search for the entries whose objectClass is organizationalPerson in the entire subtree rooted at <TT>dc=example,dc=com</TT>. The requested attributes are <TT>cn</TT>, <TT>sn</TT>, <TT>ou</TT>, <TT>telephoneNumber</TT>, <TT>title</TT>, and <TT>l</TT>. The schema checking is turned off, so that the consumer <EM>slapd</EM> (8) will not enforce entry schema checking when it process updates from the provider <EM>slapd</EM> (8).</P>
+<P>In this example, the consumer will connect to the provider <EM>slapd</EM>(8) at port 389 of <A HREF="ldap://provider.example.com">ldap://provider.example.com</A> to perform a polling (<EM>refreshOnly</EM>) mode of synchronization once a day.  It will bind as <TT>cn=syncuser,dc=example,dc=com</TT> using simple authentication with password &quot;secret&quot;.  Note that the access control privilege of <TT>cn=syncuser,dc=example,dc=com</TT> should be set appropriately in the provider to retrieve the desired replication content. Also the search limits must be high enough on the provider to allow the syncuser to retrieve a complete copy of the requested content.  The consumer uses the rootdn to write to its database so it always has full permissions to write all content.</P>
+<P>The synchronization search in the above example will search for the entries whose objectClass is organizationalPerson in the entire subtree rooted at <TT>dc=example,dc=com</TT>. The requested attributes are <TT>cn</TT>, <TT>sn</TT>, <TT>ou</TT>, <TT>telephoneNumber</TT>, <TT>title</TT>, and <TT>l</TT>. The schema checking is turned off, so that the consumer <EM>slapd</EM>(8) will not enforce entry schema checking when it process updates from the provider <EM>slapd</EM>(8).</P>
 <P>For more detailed information on the syncrepl directive, see the <A HREF="#syncrepl">syncrepl</A> section of <A HREF="#The slapd Configuration File">The slapd Configuration File</A> chapter of this admin guide.</P>
-<H3><A NAME="Start the provider and the consumer slapd">15.3.3. Start the provider and the consumer slapd</A></H3>
-<P>The provider <EM>slapd</EM> (8) is not required to be restarted. <EM>contextCSN</EM> is automatically generated as needed: it might be originally contained in the <TERM>LDIF</TERM> file, generated by <EM>slapadd</EM> (8), generated upon changes in the context, or generated when the first LDAP Sync search arrives at the provider.  If an LDIF file is being loaded which did not previously contain the <EM>contextCSN</EM>, the <EM>-w</EM> option should be used with <EM>slapadd</EM> (8) to cause it to be generated. This will allow the server to startup a little quicker the first time it runs.</P>
-<P>When starting a consumer <EM>slapd</EM> (8), it is possible to provide a synchronization cookie as the <EM>-c cookie</EM> command line option in order to start the synchronization from a specific state.  The cookie is a comma separated list of name=value pairs. Currently supported syncrepl cookie fields are <EM>csn=&lt;csn&gt;</EM> and <EM>rid=&lt;rid&gt;</EM>. <EM>&lt;csn&gt;</EM> represents the current synchronization state of the consumer replica.  <EM>&lt;rid&gt;</EM> identifies a consumer replica locally within the consumer server. It is used to relate the cookie to the syncrepl definition in <EM>slapd.conf</EM> (5) which has the matching replica identifier.  The <EM>&lt;rid&gt;</EM> must have no more than 3 decimal digits.  The command line cookie overrides the synchronization cookie stored in the consumer replica database.</P>
+<H4><A NAME="Start the provider and the consumer slapd">16.3.3.3. Start the provider and the consumer slapd</A></H4>
+<P>The provider <EM>slapd</EM>(8) is not required to be restarted. <EM>contextCSN</EM> is automatically generated as needed: it might be originally contained in the <TERM>LDIF</TERM> file, generated by <EM>slapadd</EM> (8), generated upon changes in the context, or generated when the first LDAP Sync search arrives at the provider.  If an LDIF file is being loaded which did not previously contain the <EM>contextCSN</EM>, the <EM>-w</EM> option should be used with <EM>slapadd</EM> (8) to cause it to be generated. This will allow the server to startup a little quicker the first time it runs.</P>
+<P>When starting a consumer <EM>slapd</EM>(8), it is possible to provide a synchronization cookie as the <EM>-c cookie</EM> command line option in order to start the synchronization from a specific state.  The cookie is a comma separated list of name=value pairs. Currently supported syncrepl cookie fields are <EM>csn=&lt;csn&gt;</EM> and <EM>rid=&lt;rid&gt;</EM>. <EM>&lt;csn&gt;</EM> represents the current synchronization state of the consumer replica.  <EM>&lt;rid&gt;</EM> identifies a consumer replica locally within the consumer server. It is used to relate the cookie to the syncrepl definition in <EM>slapd.conf</EM>(5) which has the matching replica identifier.  The <EM>&lt;rid&gt;</EM> must have no more than 3 decimal digits.  The command line cookie overrides the synchronization cookie stored in the consumer replica database.</P>
+<H2><A NAME="N-Way Multi-Master">16.4. N-Way Multi-Master</A></H2>
+<P>Import and expand from link:</P>
+<P><A HREF="http://blog.suretecsystems.com/archives/40-OpenLDAP-Weekly-News-Issue-5.html#extended">http://blog.suretecsystems.com/archives/40-OpenLDAP-Weekly-News-Issue-5.html#extended</A></P>
+<H2><A NAME="MirrorMode">16.5. MirrorMode</A></H2>
+<H3><A NAME="Arguments for MirrorMode">16.5.1. Arguments for MirrorMode</A></H3>
+<UL>
+<LI>Provides a high-availability (HA) solution for directory writes (replicas handle reads)
+<LI>As long as one Master is operational, writes can safely be accepted
+<LI>Master nodes replicate from each other, so they are always up to date and can be ready to take over (hot standby)
+<LI>Syncrepl also allows the master nodes to re-synchronize after any downtime
+<LI>Delta-Syncrepl can be used</UL>
+<H3><A NAME="Arguments against MirrorMode">16.5.2. Arguments against MirrorMode</A></H3>
+<UL>
+<LI>MirrorMode is not what is termed as a Multi-Master solution. This is because writes have to go to one of the mirror nodes at a time
+<LI>MirrorMode can be termed as Active-Active Hot-Standby, therefor an external server (slapd in proxy mode) or device (hardware load balancer) to manage which master is currently active
+<LI>While syncrepl can recover from a completely empty database, slapadd is much faster
+<LI>Does not provide faster or more scalable write performance (neither could any Multi-Master solution)
+<LI>Backups are managed slightly differently<UL>
+<LI>If backing up the Berkeley database itself and periodically backing up the transaction log files, then the same member of the mirror pair needs to be used to collect logfiles until the next database backup is taken
+<LI>To ensure that both databases are consistent, each database might have to be put in read-only mode while performing a slapcat.
+<LI>When using slapcat, the generated LDIF files can be rather large. This can happen with a non-MirrorMode deployment also.</UL></UL>
+<H3><A NAME="MirrorMode Configuration">16.5.3. MirrorMode Configuration</A></H3>
+<P>MirrorMode configuration is actually very easy. If you have ever setup a normal slapd syncrepl provider, then the only change is the following two directives:</P>
+<PRE>
+       mirrormode  on
+       serverID    1
+</PRE>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>You need to make sure that the <EM>serverID</EM> of each mirror node pair is different and that the <EM>provider</EM> syncrepl directive points to the opposite mirror node.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<H4><A NAME="Mirror Node Configuration">16.5.3.1. Mirror Node Configuration</A></H4>
+<P>This is the same as the <A HREF="#Set up the provider slapd">Set up the provider slapd</A> section, reference <A HREF="#delta-syncrepl replication">delta-syncrepl replication</A> if using <EM>delta-syncrepl</EM>.</P>
+<P>Here's a specific cut down example using <A HREF="#LDAP Sync Replication">LDAP Sync Replication</A> in <EM>refreshAndPersist</EM> mode (<EM>delta-syncrepl</EM> can be used also):</P>
+<P>MirrorMode node 1:</P>
+<PRE>
+       # syncrepl directives
+       syncrepl      rid=1
+                     provider=ldap://ldap-rid2.example.com
+                     bindmethod=simple
+                     binddn=&quot;cn=mirrormode,dc=example,dc=com&quot;
+                     credentials=mirrormode
+                     searchbase=&quot;dc=example,dc=com&quot;
+                     schemachecking=on
+                     type=refreshAndPersist
+                     retry=&quot;60 +&quot;
+
+       mirrormode on
+       serverID    1
+</PRE>
+<P>MirrorMode node 2:</P>
+<PRE>
+       # syncrepl directives
+       syncrepl      rid=1
+                     provider=ldap://ldap-rid1.example.com
+                     bindmethod=simple
+                     binddn=&quot;cn=mirrormode,dc=example,dc=com&quot;
+                     credentials=mirrormode
+                     searchbase=&quot;dc=example,dc=com&quot;
+                     schemachecking=on
+                     type=refreshAndPersist
+                     retry=&quot;60 +&quot;
+
+       mirrormode on
+       serverID    2
+</PRE>
+<P>It's simple really; each MirrorMode node is setup <B>exactly</B> the same, except that the <B>provider</B> directive is set to point to the other MirrorMode node and the <EM>serverID</EM> is unique.</P>
+<H4><A NAME="Failover Configuration">16.5.3.2. Failover Configuration</A></H4>
+<P>There are generally 2 choices for this; 1.  Hardware proxies/load-balancing or dedicated proxy software, 2. using a Back-LDAP proxy as a syncrepl provider</P>
+<P>A typical enterprise example might be:</P>
+<P><CENTER><IMG SRC="dual_dc.png" ALIGN="center"></CENTER></P>
+<P ALIGN="Center">Figure X.Y: MirrorMode in a Dual Data Center Configuration</P>
+<H4><A NAME="Normal Consumer Configuration">16.5.3.3. Normal Consumer Configuration</A></H4>
+<P>This is exactly the same as the <A HREF="#Set up the consumer slapd">Set up the consumer slapd</A> section. It can either setup in normal <A HREF="#syncrepl replication">syncrepl replication</A> mode, or in <A HREF="#delta-syncrepl replication">delta-syncrepl replication</A> mode.</P>
+<H3><A NAME="MirrorMode Summary">16.5.4. MirrorMode Summary</A></H3>
+<P>Hopefully you will now have a directory architecture that provides all of the consistency guarantees of single-master replication, whilst also providing the high availability of multi-master replication.</P>
 <P></P>
 <HR>
-<H1><A NAME="The Proxy Cache Engine">16. The Proxy Cache Engine</A></H1>
-<P>LDAP servers typically hold one or more subtrees of a DIT. Replica (or shadow) servers hold shadow copies of entries held by one or more master servers.  Changes are propagated from the master server to replica (slave) servers using LDAP Sync or <EM>slurpd</EM>(8). An LDAP cache is a special type of replica which holds entries corresponding to search filters instead of subtrees.</P>
-<H2><A NAME="Overview">16.1. Overview</A></H2>
-<P>The proxy cache extension of slapd is designed to improve the responseiveness of the ldap and meta backends. It handles a search request (query) by first determining whether it is contained in any cached search filter. Contained requests are answered from the proxy cache's local database. Other requests are passed on to the underlying ldap or meta backend and processed as usual.</P>
-<P>E.g. <TT>(shoesize&gt;=9)</TT> is contained in <TT>(shoesize&gt;=8)</TT> and <TT>(sn=Richardson)</TT> is contained in <TT>(sn=Richards*)</TT></P>
-<P>Correct matching rules and syntaxes are used while comparing assertions for query containment. To simplify the query containment problem, a list of cacheable &quot;templates&quot; (defined below) is specified at configuration time. A query is cached or answered only if it belongs to one of these templates. The entries corresponding to cached queries are stored in the proxy cache local database while its associated meta information (filter, scope, base, attributes) is stored in main memory.</P>
-<P>A template is a prototype for generating LDAP search requests. Templates are described by a prototype search filter and a list of attributes which are required in queries generated from the template. The representation for prototype filter is similar to RFC 2254, except that the assertion values are missing. Examples of prototype filters are: (sn=),(&amp;(sn=)(givenname=)) which are instantiated by search filters (sn=Doe) and (&amp;(sn=Doe)(givenname=John)) respectively.</P>
-<P>The cache replacement policy removes the least recently used (LRU) query and entries belonging to only that query. Queries are allowed a maximum time to live (TTL) in the cache thus providing weak consistency. A background task periodically checks the cache for expired queries and removes them.</P>
-<P>The Proxy Cache paper (<A HREF="http://www.openldap.org/pub/kapurva/proxycaching.pdf">http://www.openldap.org/pub/kapurva/proxycaching.pdf</A>) provides design and implementation details.</P>
-<H2><A NAME="Proxy Cache Configuration">16.2. Proxy Cache Configuration</A></H2>
-<P>The cache configuration specific directives described below must appear after a <TT>overlay proxycache</TT> directive within a <TT>&quot;database meta&quot;</TT> or <TT>database ldap</TT> section of the server's <EM>slapd.conf</EM>(5) file.</P>
-<H3><A NAME="Setting cache parameters">16.2.1. Setting cache parameters</A></H3>
+<H1><A NAME="Maintenance">17. Maintenance</A></H1>
+<P>System Administration is all about maintenance, so it is only fair that we discuss how to correctly maintain an OpenLDAP deployment.</P>
+<H2><A NAME="Directory Backups">17.1. Directory Backups</A></H2>
+<P>Backup strategies largely depend on the amount of change in the database and how much of that change an administrator might be willing to lose in a catastrophic failure. There are two basic methods that can be used:</P>
+<P>1. Backup the Berkeley database itself and periodically back up the transaction log files:</P>
+<P>Berkeley DB produces transaction logs that can be used to reconstruct changes from a given point in time. For example, if an administrator were willing to only lose one hour's worth of changes, they could take down the server in the middle of the night, copy the Berkeley database files offsite, and bring the server back online. Then, on an hourly basis, they could force a database checkpoint, capture the log files that have been generated in the past hour, and copy them offsite. The accumulated log files, in combination with the previous database backup, could be used with db_recover to reconstruct the database up to the time the last collection of log files was copied offsite. This method affords good protection, with minimal space overhead.</P>
+<P>2. Periodically run slapcat and back up the LDIF file:</P>
+<P>Slapcat can be run while slapd is active. However, one runs the risk of an inconsistent database- not from the point of slapd, but from the point of the applications using LDAP. For example, if a provisioning application performed tasks that consisted of several LDAP operations, and the slapcat took place concurrently with those operations, then there might be inconsistencies in the LDAP database from the point of view of that provisioning application and applications that depended on it. One must, therefore, be convinced something like that won't happen. One way to do that would be to put the database in read-only mode while performing the slapcat. The other disadvantage of this approach is that the generated LDIF files can be rather large and the accumulation of the day's backups could add up to a substantial amount of space.</P>
+<P>You can use <EM>slapcat</EM>(8) to generate an LDIF file for each of your <EM>slapd</EM>(8) back-bdb or back-hdb databases.</P>
 <PRE>
- proxyCache &lt;DB&gt; &lt;maxentries&gt; &lt;nattrsets&gt; &lt;entrylimit&gt; &lt;period&gt;
+    slapcat -f slapd.conf -b &quot;dc=example,dc=com&quot;
 </PRE>
-<P>This directive enables proxy caching and sets general cache parameters. The &lt;DB&gt; parameter specifies which underlying database is to be used to hold cached entries.  It should be set to <TT>bdb</TT>, <TT>hdb</TT>, or <TT>ldbm</TT>.  The &lt;maxentries&gt; parameter specifies the total number of entries which may be held in the cache.  The &lt;nattrsets&gt; parameter specifies the total number of attribute sets (as specified by the <TT>proxyAttrSet</TT> directive) that may be defined. The &lt;entrylimit&gt; parameter specifies the maximum number of entries in a cachable query.  The &lt;period&gt; specifies the consistency check period (in seconds).  In each period, queries with expired TTLs are removed.</P>
-<H3><A NAME="Defining attribute sets">16.2.2. Defining attribute sets</A></H3>
+<P>For back-bdb and back-hdb, this command may be ran while slapd(8) is running.</P>
+<P>MORE on actual Berkeley DB backups later covering db_recover etc.</P>
+<H2><A NAME="Berkeley DB Logs">17.2. Berkeley DB Logs</A></H2>
+<P>Berkeley DB log files grow, and the administrator has to deal with it. The procedure is known as log file archival or log file rotation.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>The actual log file rotation is handled by the Berkeley DB engine.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<P>Logs of current transactions need to be stored into files so that the database can be recovered in the event of an application crash. Administrators can change the size limit of a single log file (by default 10MB), and have old log files removed automatically, by setting up DB environment (see below). The reason Berkeley DB never deletes any log files by default is that the administrator may wish to backup the log files before removal to make database recovery possible even after a catastrophic failure, such as file system corruption.</P>
+<P>Log file names are <TT>log.XXXXXXXXXX</TT> (X is a digit). By default the log files are located in the BDB backend directory. The <TT>db_archive</TT> tool knows what log files are used in current transactions, and what are not. Administrators can move unused log files to a backup media, and delete them. To have them removed automatically, place set_flags <EM>DB_LOG_AUTOREMOVE</EM> directive in <TT>DB_CONFIG</TT>.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>If the log files are removed automatically, recovery after a catastrophic failure is likely to be impossible.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<P>The files with names <TT>__db.001</TT>, <TT>__db.002</TT>, etc are just shared memory regions (or whatever). These ARE NOT 'logs', they must be left alone. Don't be afraid of them, they do not grow like logs do.</P>
+<P>To understand the <TT>db_archive</TT> interface, the reader should refer to chapter 9 of the Berkeley DB guide. In particular, the following chapters are recommended:</P>
+<UL>
+<LI>Database and log file archival
+<LI>Log file removal
+<LI>Recovery procedures
+<LI>Hot failover</UL>
+<P>Advanced installations can use special environment settings to fine-tune some Berkeley DB options (change the log file limit, etc). This can be done by using the <TT>DB_CONFIG</TT> file. This magic file can be created in BDB backend directory set up by <EM>slapd.conf</EM>(5). More information on this file can be found in File naming chapter. Specific directives can be found in C Interface, look for <EM>DB_ENV-&gt;set_XXXX</EM> calls.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>options set in <TT>DB_CONFIG</TT> file override options set by OpenLDAP. Use them with extreme caution. Do not use them unless You know what You are doing.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<P>The advantages of <TT>DB_CONFIG</TT> usage can be the following:</P>
+<UL>
+<LI>to keep data files and log files on different mediums (i.e. disks) to improve performance and/or reliability;
+<LI>to fine-tune some specific options (such as shared memory region sizes);
+<LI>to set the log file limit (please read Log file limits before doing this).</UL>
+<P>To figure out the best-practice BDB backup scenario, the reader is highly recommended to read the whole Chapter 9: Berkeley DB Transactional Data Store Applications. This chapter is a set of small pages with examples in C language. Non-programming people can skip this examples without loss of knowledge.</P>
+<H2><A NAME="Checkpointing">17.3. Checkpointing</A></H2>
+<P>MORE/TIDY</P>
+<P>If you put &quot;checkpoint 1024 5&quot; in slapd.conf (to checkpoint after 1024kb or 5 minutes, for example), this does not checkpoint every 5 minutes as you may think. The explanation from Howard is:</P>
+<P>'In OpenLDAP 2.1 and 2.2 the checkpoint directive acts as follows - *when there is a write operation*, and more than &lt;check&gt; minutes have occurred since the last checkpoint, perform the checkpoint. If more than &lt;check&gt; minutes pass after a write without any other write operations occurring, no checkpoint is performed, so it's possible to lose the last write that occurred.''</P>
+<P>In other words, a write operation occurring less than &quot;check&quot; minutes after the last checkpoint will not be checkpointed until the next write occurs after &quot;check&quot; minutes have passed since the checkpoint.</P>
+<P>This has been modified in 2.3 to indeed checkpoint every so often; in the meantime a workaround is to invoke &quot;db_checkpoint&quot; from a cron script every so often, say 5 minutes.</P>
+<H2><A NAME="Migration">17.4. Migration</A></H2>
+<P>Exporting to a new system......</P>
+<P></P>
+<HR>
+<H1><A NAME="Monitoring">18. Monitoring</A></H1>
+<P><EM>slapd</EM>(8) supports an optional <TERM>LDAP</TERM> monitoring interface you can use to obtain information regarding the current state of your <EM>slapd</EM> instance.  For instance, the interface allows you to determine how many clients are connected to the server currently. The monitoring information is provided by a specialized backend, the <EM>monitor</EM> backend.  A manual page, <EM>slapd-monitor</EM>(5) is available.</P>
+<P>When the monitoring interface is enabled, LDAP clients may be used to access information provided by the <EM>monitor</EM> backend, subject to access and other controls.</P>
+<P>When enabled, the <EM>monitor</EM> backend dynamically generates and returns objects in response to search requests in the <EM>cn=Monitor</EM> subtree.  Each object contains information about a particular aspect of the server.  The information is held in a combination of user applications and operational attributes.   This information can be access with <EM>ldapsearch(1)</EM>, with any general-purpose LDAP browser, or with specialized monitoring tools.  The <A HREF="#Accessing Monitoring Information">Accessing Monitoring Information</A> section provides a brief tutorial on how to use <EM>ldapsearch</EM>(1) to access monitoring information, while the <A HREF="#Monitor information">Monitor information</A> section details monitoring information base and its organization.</P>
+<P>While support for the monitor backend is included in default builds of slapd(8), this support requires some configuration to become active.  This may be done using either <TT>cn=config</TT> or <EM>slapd.conf</EM>(5).  The former is discussed in the <A HREF="#Monitor configuration via cn=config">Monitor configuration via cn=config</A> section of this of this chapter.  The latter is discussed in the <A HREF="#Monitor configuration via slapd.conf(5)">Monitor configuration via slapd.conf(5)</A> section of this chapter.  These sections assume monitor backend is built into <EM>slapd</EM> (e.g., <TT>--enable-monitor=yes</TT>, the default).  If the monitor backend was built as a module (e.g., <TT>--enable-monitor=mod</TT>, this module must loaded.  Loading of modules is discussed in the <A HREF="#Configuring slapd">Configuring slapd</A> and <A HREF="#The slapd Configuration File">The slapd Configuration File</A> chapters.</P>
+<H2><A NAME="Monitor configuration via cn=config(5)">18.1. Monitor configuration via cn=config(5)</A></H2>
+<P><EM>This section has yet to be written.</EM></P>
+<H2><A NAME="Monitor configuration via slapd.conf(5)">18.2. Monitor configuration via slapd.conf(5)</A></H2>
+<P>Configuration of the slapd.conf(5) to support LDAP monitoring is quite simple.</P>
+<P>First, ensure <EM>core.schema</EM> schema configuration file is included by your <EM>slapd.conf</EM>(5) file.  The <EM>monitor</EM> backend requires it.</P>
+<P>Second, instantiate the <EM>monitor backend</EM> by adding a <EM>database monitor</EM> directive below your existing database sections.  For instance:</P>
 <PRE>
- proxyAttrset &lt;index&gt; &lt;attrs...&gt;
+        database monitor
 </PRE>
-<P>Used to associate a set of attributes to an index. Each attribute set is associated with an index number from 0 to &lt;numattrsets&gt;-1. These indices are used by the proxyTemplate directive to define cacheable templates.</P>
-<H3><A NAME="Specifying cacheable templates">16.2.3. Specifying cacheable templates</A></H3>
+<P>Lastly, add additional global or database directives as needed.</P>
+<P>Like most other database backends, the monitor backend does honor slapd(8) access and other administrative controls.   As some monitor information may be sensitive, it is generally recommend access to cn=monitor be restricted to directory administrators and their monitoring agents.  Adding an <EM>access</EM> directive immediately below the <EM>database monitor</EM> directive is a clear and effective approach for controlling access.  For instance, the addition of the following <EM>access</EM> directive immediately below the <EM>database monitor</EM> directive restricts access to monitoring information to the specified directory manager.</P>
 <PRE>
- proxyTemplate &lt;prototype_string&gt; &lt;attrset_index&gt; &lt;TTL&gt;
+        access to *
+                by dn.exact=&quot;cn=Manager,dc=example,dc=com
+                by * none
 </PRE>
-<P>Specifies a cacheable template and the &quot;time to live&quot; (in sec) &lt;TTL&gt; for queries belonging to the template. A template is described by its prototype filter string and set of required attributes identified by &lt;attrset_index&gt;.</P>
-<H3><A NAME="Example">16.2.4. Example</A></H3>
-<P>An example <EM>slapd.conf</EM>(5) database section for a caching server which proxies for the <TT>&quot;dc=example,dc=com&quot;</TT> subtree held at server <TT>ldap.example.com</TT>.</P>
+<P>More information on <EM>slapd</EM>(8) access controls, see <EM>The access Control Directive</EM> section of the <A HREF="#The slapd Configuration File">The slapd Configuration File</A> chapter and <EM>slapd.access</EM>(5).</P>
+<P>After restarting <EM>slapd</EM>(8), you are ready to start exploring the monitoring information provided in <TT>cn=config</TT> as discussed in the <A HREF="#Accessing Monitoring Information">Accessing Monitoring Information</A> section of this chapter.</P>
+<P>One can verify slapd(8) is properly configured to provide monitoring information by attempting to read the <TT>cn=monitor</TT> object. For instance, if the following <EM>ldapsearch</EM>(1) command returns the cn=monitor object (with, as requested, no attributes), it's working.</P>
 <PRE>
-        database        ldap
-        suffix          &quot;dc=example,dc=com&quot;
-        rootdn          &quot;dc=example,dc=com&quot;
-        uri             ldap://ldap.example.com/dc=example%2cdc=com
-        overlay proxycache
-        proxycache    bdb 100000 1 1000 100
-        proxyAttrset  0 mail postaladdress telephonenumber
-        proxyTemplate (sn=) 0 3600
-        proxyTemplate (&amp;(sn=)(givenName=)) 0 3600
-        proxyTemplate (&amp;(departmentNumber=)(secretary=*)) 0 3600
+        ldapsearch -x -D 'cn=Manager,dc=example,dc=com' -W \
+                -b 'cn=Monitor' -s base 1.1
+</PRE>
+<P>Note that unlike general purpose database backends, the database suffix is hardcoded.  It's always <TT>cn=Monitor</TT>.  So no <EM>suffix</EM> directive should be provided.  Also note that general purpose database backends, the monitor backend cannot be instantiated multiple times.  That is, there can only be one (or zero) occurrences of <TT>database monitor</TT> in the server's configuration.</P>
+<H2><A NAME="Accessing Monitoring Information">18.3. Accessing Monitoring Information</A></H2>
+<P>As previously discussed, when enabled, the <EM>monitor</EM> backend dynamically generates and returns objects in response to search requests in the <EM>cn=Monitor</EM> subtree.  Each object contains information about a particular aspect of the server.  The information is held in a combination of user applications and operational attributes.  This information can be access with <EM>ldapsearch(1)</EM>, with any general-purpose LDAP browser, or with specialized monitoring tools.</P>
+<P>This section provides a provides a brief tutorial on how to use <EM>ldapsearch</EM>(1) to access monitoring information.</P>
+<P>To inspect any particular monitor object, one performs search operation on the object with a baseObject scope and a <TT>(objectClass=*)</TT> filter.  As the monitoring information is contained in a combination of user applications and operational attributes, the return all user applications attributes (e.g., <TT>'*'</TT>) and all operational attributes (e.g., <TT>'+'</TT>) should be requested.   For instance, to read the <TT>cn=Monitor</TT> object itself, the <EM>ldapsearch</EM>(1) command (modified to fit your configuration) can be used:</P>
+<PRE>
+        ldapsearch -x -D 'cn=Manager,dc=example,dc=com' -W \
+                -b 'cn=Monitor' -s base '(objectClass=*)' '*' '+'
+</PRE>
+<P>When run against your server, this should produce output similar to:</P>
+<PRE>
+        dn: cn=Monitor
+        objectClass: monitorServer
+        structuralObjectClass: monitorServer
+        cn: Monitor
+        creatorsName:
+        modifiersName:
+        createTimestamp: 20061208223558Z
+        modifyTimestamp: 20061208223558Z
+        description: This subtree contains monitoring/managing objects.
+        description: This object contains information about this server.
+        description: Most of the information is held in operational attributes, which
+         must be explicitly requested.
+        monitoredInfo: OpenLDAP: slapd 2.4 (Dec  7 2006 17:30:29)
+        entryDN: cn=Monitor
+        subschemaSubentry: cn=Subschema
+        hasSubordinates: TRUE
+</PRE>
+<P>To reduce the number of uninteresting attributes returned, one can be more selective when requesting which attributes are to be returned.  For instance, one could request the return of all attributes allowed by the <EM>monitorServer</EM> object class (e.g., <TT>@objectClass</TT>) instead of all user and all operational attributes:</P>
+<PRE>
+        ldapsearch -x -D 'cn=Manager,dc=example,dc=com' -W \
+                -b 'cn=Monitor' -s base '(objectClass=*)' '@monitorServer'
+</PRE>
+<P>This limits the output as follows:</P>
+<PRE>
+        dn: cn=Monitor
+        objectClass: monitorServer
+        cn: Monitor
+        description: This subtree contains monitoring/managing objects.
+        description: This object contains information about this server.
+        description: Most of the information is held in operational attributes, which
+         must be explicitly requested.
+        monitoredInfo: OpenLDAP: slapd 2.X (Dec  7 2006 17:30:29)
+</PRE>
+<P>To return the names of all the monitoring objects, one performs a search of <TT>cn=Monitor</TT> with subtree scope and <TT>(objectClass=*)</TT> filter and requesting no attributes (e.g., <TT>1.1</TT>) be returned.</P>
+<PRE>
+        ldapsearch -x -D 'cn=Manager,dc=example,dc=com' -W -b 'cn=Monitor' -s sub 1.1
+</PRE>
+<P>If you run this command you will discover that there are many objects in the <EM>cn=Monitor</EM> subtree.  The following section describes some of the commonly available monitoring objects.</P>
+<H2><A NAME="Monitor Information">18.4. Monitor Information</A></H2>
+<P>The <EM>monitor</EM> backend provides a wealth of information useful for monitoring the slapd(8) contained in set of monitor objects. Each object contains information about a particular aspect of the server, such as a backends, a connection, or a thread. Some objects serve as containers for other objects and used to construct a hierarchy of objects.</P>
+<P>In this hierarchy, the most superior object is {cn=Monitor}. While this object primarily serves as a container for other objects, most of which are containers, this object provides information about this server.  In particular, it provides the slapd(8) version string.  Example:</P>
+<PRE>
+        dn: cn=Monitor
+        monitoredInfo: OpenLDAP: slapd 2.X (Dec  7 2006 17:30:29)
+</PRE>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>Examples in this section (and its subsections) have been trimmed to show only key information.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<H3><A NAME="Backends">18.4.1. Backends</A></H3>
+<P>The <TT>cn=Backends,cn=Monitor</TT> object, itself, provides a list of available backends.  The list of available backends all builtin backends, as well as backends loaded by modules.  For example:</P>
+<PRE>
+        dn: cn=Backends,cn=Monitor
+        monitoredInfo: config
+        monitoredInfo: ldif
+        monitoredInfo: monitor
+        monitoredInfo: bdb
+        monitoredInfo: hdb
+</PRE>
+<P>This indicates the <EM>config</EM>, <EM>ldif</EM>, <EM>monitor</EM>, <EM>bdb</EM>, and <EM>hdb</EM> backends are available.</P>
+<P>The <TT>cn=Backends,cn=Monitor</TT> object is also a container for available backend objects.  Each available backend object contains information about a particular backend.  For example:</P>
+<PRE>
+        dn: cn=Backend 0,cn=Backends,cn=Monitor
+        monitoredInfo: config
+        monitorRuntimeConfig: TRUE
+        supportedControl: 2.16.840.1.113730.3.4.2
+        seeAlso: cn=Database 0,cn=Databases,cn=Monitor
 
-        cachesize 20
-        directory ./testrun/db.2.a
-        index       objectClass eq
-        index       cn,sn,uid,mail  pres,eq,sub
+        dn: cn=Backend 1,cn=Backends,cn=Monitor
+        monitoredInfo: ldif
+        monitorRuntimeConfig: TRUE
+        supportedControl: 2.16.840.1.113730.3.4.2
+
+        dn: cn=Backend 2,cn=Backends,cn=Monitor
+        monitoredInfo: monitor
+        monitorRuntimeConfig: TRUE
+        supportedControl: 2.16.840.1.113730.3.4.2
+        seeAlso: cn=Database 2,cn=Databases,cn=Monitor
+
+        dn: cn=Backend 3,cn=Backends,cn=Monitor
+        monitoredInfo: bdb
+        monitorRuntimeConfig: TRUE
+        supportedControl: 1.3.6.1.1.12
+        supportedControl: 2.16.840.1.113730.3.4.2
+        supportedControl: 1.3.6.1.4.1.4203.666.5.2
+        supportedControl: 1.2.840.113556.1.4.319
+        supportedControl: 1.3.6.1.1.13.1
+        supportedControl: 1.3.6.1.1.13.2
+        supportedControl: 1.3.6.1.4.1.4203.1.10.1
+        supportedControl: 1.2.840.113556.1.4.1413
+        supportedControl: 1.3.6.1.4.1.4203.666.11.7.2
+        seeAlso: cn=Database 1,cn=Databases,cn=Monitor
+
+        dn: cn=Backend 4,cn=Backends,cn=Monitor
+        monitoredInfo: hdb
+        monitorRuntimeConfig: TRUE
+        supportedControl: 1.3.6.1.1.12
+        supportedControl: 2.16.840.1.113730.3.4.2
+        supportedControl: 1.3.6.1.4.1.4203.666.5.2
+        supportedControl: 1.2.840.113556.1.4.319
+        supportedControl: 1.3.6.1.1.13.1
+        supportedControl: 1.3.6.1.1.13.2
+        supportedControl: 1.3.6.1.4.1.4203.1.10.1
+        supportedControl: 1.2.840.113556.1.4.1413
+        supportedControl: 1.3.6.1.4.1.4203.666.11.7.2
 </PRE>
-<H4><A NAME="Cacheable Queries">16.2.4.1. Cacheable Queries</A></H4>
-<P>A LDAP search query is cacheable when its filter matches one of the templates as defined in the &quot;proxyTemplate&quot; statements and when it references only the attributes specified in the corresponding attribute set. In the example above the attribute set number 0 defines that only the attributes: <TT>mail postaladdress telephonenumber</TT> are cached for the following proxyTemplates.</P>
-<H4><A NAME="Examples:">16.2.4.2. Examples:</A></H4>
+<P>For each of these objects, monitorInfo indicates which backend the information in the object is about.  For instance, the <TT>cn=Backend 3,cn=Backends,cn=Monitor</TT> object contains (in the example) information about the <EM>bdb</EM> backend.</P>
+<TABLE CLASS="columns" BORDER>
+<TR CLASS="heading">
+<TD>
+<STRONG>Attribute</STRONG>
+</TD>
+<TD>
+<STRONG>Description</STRONG>
+</TD>
+</TR>
+<TR>
+<TD>
+monitoredInfo
+</TD>
+<TD>
+Name of backend
+</TD>
+</TR>
+<TR>
+<TD>
+supportedControl
+</TD>
+<TD>
+supported LDAP control extensions
+</TD>
+</TR>
+<TR>
+<TD>
+seeAlso
+</TD>
+<TD>
+Database objects of instances of this backend
+</TD>
+</TR>
+</TABLE>
+
+<H3><A NAME="Connections">18.4.2. Connections</A></H3>
+<P>The main entry is empty; it should contain some statistics on the number of connections.</P>
+<P>Dynamic child entries are created for each open connection, with stats on the activity on that connection (the format will be detailed later). There are two special child entries that show the number of total and current connections respectively.</P>
+<P>For example:</P>
+<P>Total Connections:</P>
 <PRE>
-        Filter: (&amp;(sn=Richard*)(givenName=jack))
-        Attrs: mail telephoneNumber
+   dn: cn=Total,cn=Connections,cn=Monitor
+   structuralObjectClass: monitorCounterObject
+   monitorCounter: 4
+   entryDN: cn=Total,cn=Connections,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
 </PRE>
-<P>is cacheable, because it matches the template <TT>(&amp;(sn=)(givenName=))</TT> and its attributes are contained in proxyAttrset 0.</P>
+<P>Current Connections:</P>
 <PRE>
-        Filter: (&amp;(sn=Richard*)(telephoneNumber))
-        Attrs: givenName
+   dn: cn=Current,cn=Connections,cn=Monitor
+   structuralObjectClass: monitorCounterObject
+   monitorCounter: 2
+   entryDN: cn=Current,cn=Connections,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
 </PRE>
-<P>is not cacheable, because the filter does not match the template, nor is the attribute givenName stored in the cache</P>
+<H3><A NAME="Databases">18.4.3. Databases</A></H3>
+<P>The main entry contains the naming context of each configured database; the child entries contain, for each database, the type and the naming context.</P>
+<P>For example:</P>
 <PRE>
-        Filter: (|(sn=Richard*)(givenName=jack))
-        Attrs: mail telephoneNumber
+   dn: cn=Database 2,cn=Databases,cn=Monitor
+   structuralObjectClass: monitoredObject
+   monitoredInfo: monitor
+   monitorIsShadow: FALSE
+   monitorContext: cn=Monitor
+   readOnly: FALSE
+   entryDN: cn=Database 2,cn=Databases,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
 </PRE>
-<P>is not cacheable, because the filter does not match the template ( logical OR &quot;|&quot; condition instead of logical AND &quot;&amp;&quot; )</P>
+<H3><A NAME="Listener">18.4.4. Listener</A></H3>
+<P>It contains the description of the devices the server is currently listening on:</P>
+<PRE>
+   dn: cn=Listener 0,cn=Listeners,cn=Monitor
+   structuralObjectClass: monitoredObject
+   monitorConnectionLocalAddress: IP=0.0.0.0:389
+   entryDN: cn=Listener 0,cn=Listeners,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
+</PRE>
+<H3><A NAME="Log">18.4.5. Log</A></H3>
+<P>It contains the currently active log items.  The <EM>Log</EM> subsystem allows user modify operations on the <EM>description</EM> attribute, whose values <EM>MUST</EM> be in the list of admittable log switches:</P>
+<PRE>
+   Trace
+   Packets
+   Args
+   Conns
+   BER
+   Filter
+   Config
+   ACL
+   Stats
+   Stats2
+   Shell
+   Parse
+   Sync
+</PRE>
+<P>These values can be added, replaced or deleted; they affect what messages are sent to the syslog device. Custom values could be added by custom modules.</P>
+<H3><A NAME="Operations">18.4.6. Operations</A></H3>
+<P>It shows some statistics on the operations performed by the server:</P>
+<PRE>
+   Initiated
+   Completed
+</PRE>
+<P>and for each operation type, i.e.:</P>
+<PRE>
+   Bind
+   Unbind
+   Add
+   Delete
+   Modrdn
+   Modify
+   Compare
+   Search
+   Abandon
+   Extended
+</PRE>
+<P>There are too many types to list example here, so please try for yourself using <A HREF="#Monitor search example">Monitor search example</A></P>
+<H3><A NAME="Overlays">18.4.7. Overlays</A></H3>
+<P>The main entry contains the type of overlays available at run-time; the child entries, for each overlay, contain the type of the overlay.</P>
+<P>It should also contain the modules that have been loaded if dynamic overlays are enabled:</P>
+<PRE>
+   # Overlays, Monitor
+   dn: cn=Overlays,cn=Monitor
+   structuralObjectClass: monitorContainer
+   monitoredInfo: syncprov
+   monitoredInfo: accesslog
+   monitoredInfo: glue
+   entryDN: cn=Overlays,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: TRUE
+</PRE>
+<H3><A NAME="SASL">18.4.8. SASL</A></H3>
+<P>Currently empty.</P>
+<H3><A NAME="Statistics">18.4.9. Statistics</A></H3>
+<P>It shows some statistics on the data sent by the server:</P>
+<PRE>
+   Bytes
+   PDU
+   Entries
+   Referrals
+</PRE>
+<P>e.g.</P>
+<PRE>
+   # Entries, Statistics, Monitor
+   dn: cn=Entries,cn=Statistics,cn=Monitor
+   structuralObjectClass: monitorCounterObject
+   monitorCounter: 612248
+   entryDN: cn=Entries,cn=Statistics,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
+</PRE>
+<H3><A NAME="Threads">18.4.10. Threads</A></H3>
+<P>It contains the maximum number of threads enabled at startup and the current backload.</P>
+<P>e.g.</P>
+<PRE>
+   # Max, Threads, Monitor
+   dn: cn=Max,cn=Threads,cn=Monitor
+   structuralObjectClass: monitoredObject
+   monitoredInfo: 16
+   entryDN: cn=Max,cn=Threads,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
+</PRE>
+<H3><A NAME="Time">18.4.11. Time</A></H3>
+<P>It contains two child entries with the start time and the current time of the server.</P>
+<P>e.g.</P>
+<P>Start time:</P>
+<PRE>
+   dn: cn=Start,cn=Time,cn=Monitor
+   structuralObjectClass: monitoredObject
+   monitorTimestamp: 20061205124040Z
+   entryDN: cn=Start,cn=Time,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
+</PRE>
+<P>Current time:</P>
+<PRE>
+   dn: cn=Current,cn=Time,cn=Monitor
+   structuralObjectClass: monitoredObject
+   monitorTimestamp: 20061207120624Z
+   entryDN: cn=Current,cn=Time,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
+</PRE>
+<H3><A NAME="TLS">18.4.12. TLS</A></H3>
+<P>Currently empty.</P>
+<H3><A NAME="Waiters">18.4.13. Waiters</A></H3>
+<P>It contains the number of current read waiters.</P>
+<P>e.g.</P>
+<P>Read waiters:</P>
+<PRE>
+   dn: cn=Read,cn=Waiters,cn=Monitor
+   structuralObjectClass: monitorCounterObject
+   monitorCounter: 7
+   entryDN: cn=Read,cn=Waiters,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
+</PRE>
+<P>Write waiters:</P>
+<PRE>
+   dn: cn=Write,cn=Waiters,cn=Monitor
+   structuralObjectClass: monitorCounterObject
+   monitorCounter: 0
+   entryDN: cn=Write,cn=Waiters,cn=Monitor
+   subschemaSubentry: cn=Subschema
+   hasSubordinates: FALSE
+</PRE>
+<P>Add new monitored things here and discuss, referencing man pages and present examples</P>
 <P></P>
 <HR>
-<H1><A NAME="Generic configure Instructions">A. Generic configure Instructions</A></H1>
+<H1><A NAME="Tuning">19. Tuning</A></H1>
+<P>This is perhaps one of the most important chapters in the guide, because if you have not tuned <EM>slapd</EM>(8) correctly or grasped how to design your directory and environment, you can expect very poor performance.</P>
+<P>Reading, understanding and experimenting using the instructions and information in the following sections, will enable you to fully understand how to tailor your directory server to your specific requirements.</P>
+<P>It should be noted that the following information has been collected over time from our community based FAQ. So obviously the benefit of this real world experience and advice should be of great value to the reader.</P>
+<H2><A NAME="Performance Factors">19.1. Performance Factors</A></H2>
+<P>Various factors can play a part in how your directory performs on your chosen hardware and environment. We will attempt to discuss these here.</P>
+<H3><A NAME="Memory">19.1.1. Memory</A></H3>
+<P>Scale your cache to use available memory and increase system memory if you can.</P>
+<P>More info here.</P>
+<H3><A NAME="Disks">19.1.2. Disks</A></H3>
+<P>Use fast subsystems. Put each database and logs on separate disks.</P>
+<P>Example showing config settings</P>
+<H3><A NAME="Network Topology">19.1.3. Network Topology</A></H3>
+<P>http://www.openldap.org/faq/data/cache/363.html</P>
+<P>Drawing here.</P>
+<H3><A NAME="Directory Layout Design">19.1.4. Directory Layout Design</A></H3>
+<P>Reference to other sections and good/bad drawing here.</P>
+<H3><A NAME="Expected Usage">19.1.5. Expected Usage</A></H3>
+<P>Discussion.</P>
+<H2><A NAME="Indexes">19.2. Indexes</A></H2>
+<H3><A NAME="Understanding how a search works">19.2.1. Understanding how a search works</A></H3>
+<P>If you're searching on a filter that has been indexed, then the search reads the index and pulls exactly the entries that are referenced by the index. If the filter term has not been indexed, then the search must read every single entry in the target scope and test to see if each entry matches the filter. Obviously indexing can save a lot of work when it's used correctly.</P>
+<H3><A NAME="What to index">19.2.2. What to index</A></H3>
+<P>You should create indices to match the actual filter terms used in search queries.</P>
 <PRE>
+        index cn,sn,givenname,mail eq
+</PRE>
+<P>Each attribute index can be tuned further by selecting the set of index types to generate. For example, substring and approximate search for organizations (o) may make little sense (and isn't like done very often). And searching for <EM>userPassword</EM> likely makes no sense what so ever.</P>
+<P>General rule: don't go overboard with indexes. Unused indexes must be maintained and hence can only slow things down.</P>
+<P>See <EM>slapd.conf</EM>(8) and <EM>slapdindex</EM>(8) for more information</P>
+<H3><A NAME="Presence indexing">19.2.3. Presence indexing</A></H3>
+<P>If your client application uses presence filters and if the target attribute exists on the majority of entries in your target scope, then all of those entries are going to be read anyway, because they are valid members of the result set. In a subtree where 100% of the entries are going to contain the same attributes, the presence index does absolutely NOTHING to benefit the search, because 100% of the entries match that presence filter.</P>
+<P>So the resource cost of generating the index is a complete waste of CPU time, disk, and memory. Don't do it unless you know that it will be used, and that the attribute in question occurs very infrequently in the target data.</P>
+<P>Almost no applications use presence filters in their search queries. Presence indexing is pointless when the target attribute exists on the majority of entries in the database. In most LDAP deployments, presence indexing should not be done, it's just wasted overhead.</P>
+<P>See the <EM>Logging</EM> section below on what to watch our for if you have a frequently searched for attribute that is unindexed.</P>
+<H2><A NAME="Logging">19.3. Logging</A></H2>
+<H3><A NAME="What log level to use">19.3.1. What log level to use</A></H3>
+<P>The default of <EM>loglevel 256</EM> is really the best bet. There's a corollary to this when problems *do* arise, don't try to trace them using syslog. Use the debug flag instead, and capture slapd's stderr output. syslog is too slow for debug tracing, and it's inherently lossy - it will throw away messages when it can't keep up.</P>
+<P>Contrary to popular belief, <EM>loglevel 0</EM> is not ideal for production as you won't be able to track when problems first arise.</P>
+<H3><A NAME="What to watch out for">19.3.2. What to watch out for</A></H3>
+<P>The most common message you'll see that you should pay attention to is:</P>
+<PRE>
+  &quot;&lt;= bdb_equality_candidates: (foo) index_param failed (18)&quot;
+</PRE>
+<P>That means that some application tried to use an equality filter (<EM>foo=&lt;somevalue&gt;</EM>) and attribute <EM>foo</EM> does not have an equality index. If you see a lot of these messages, you should add the index. If you see one every month or so, it may be acceptable to ignore it.</P>
+<P>The default syslog level is 256 which logs the basic parameters of each request; it usually produces 1-3 lines of output. On Solaris and systems that only provide synchronous syslog, you may want to turn it off completely, but usually you want to leave it enabled so that you'll be able to see index messages whenever they arise. On Linux you can configure syslogd to run asynchronously, in which case the performance hit for moderate syslog traffic pretty much disappears.</P>
+<H3><A NAME="Improving throughput">19.3.3. Improving throughput</A></H3>
+<P>You can improve logging performance on some systems by configuring syslog not to sync the file system with every write (<EM>man syslogd/syslog.conf</EM>). In Linux, you can prepend the log file name with a &quot;-&quot; in <EM>syslog.conf</EM>. For example, if you are using the default LOCAL4 logging you could try:</P>
+<PRE>
+   # LDAP logs
+   LOCAL4.*         -/var/log/ldap
+</PRE>
+<P>For syslog-ng, add or modify the following line in <EM>syslog-ng.conf</EM>:</P>
+<PRE>
+   options { sync(n); };
+</PRE>
+<P>where n is the number of lines which will be buffered before a write.</P>
+<H2><A NAME="BDB/HDB Database Caching">19.4. BDB/HDB Database Caching</A></H2>
+<P>We all know what caching is, don't we?</P>
+<P>In brief, &quot;A cache is a block of memory for temporary storage of data likely to be used again&quot; - <A HREF="http://en.wikipedia.org/wiki/Cache">http://en.wikipedia.org/wiki/Cache</A></P>
+<P>There are 3 types of caches, BerkeleyDB's own cache, <EM>slapd</EM>(8) entry cache and <TERM>IDL</TERM> (IDL) cache.</P>
+<H3><A NAME="Berkeley DB Cache">19.4.1. Berkeley DB Cache</A></H3>
+<P>BerkeleyDB's own data cache operates on page-sized blocks of raw data.</P>
+<P>Note that while the <TERM>BDB</TERM> cache is just raw chunks of memory and configured as a memory size, the <EM>slapd</EM>(8) entry cache holds parsed entries, and the size of each entry is variable.</P>
+<P>There is also an IDL cache which is used for Index Data Lookups. If you can fit all of your database into slapd's entry cache, and all of your index lookups fit in the IDL cache, that will provide the maximum throughput.</P>
+<P>If not, but you can fit the entire database into the BDB cache, then you should do that and shrink the slapd entry cache as appropriate.</P>
+<P>Failing that, you should balance the BDB cache against the entry cache.</P>
+<P>It is worth noting that it is not absolutely necessary to configure a BerkeleyDB cache equal in size to your entire database. All that you need is a cache that's large enough for your &quot;working set.&quot;</P>
+<P>That means, large enough to hold all of the most frequently accessed data, plus a few less-frequently accessed items.</P>
+<P>ORACLE LINKS HERE</P>
+<H4><A NAME="Calculating Cachesize">19.4.1.1. Calculating Cachesize</A></H4>
+<P>The back-bdb database lives in two main files, <TT>dn2id.bdb</TT> and <TT>id2entry.bdb</TT>. These are B-tree databases. We have never documented the back-bdb internal layout before, because it didn't seem like something anyone should have to worry about, nor was it necessarily cast in stone. But here's how it works today, in OpenLDAP 2.4.</P>
+<P>A B-tree is a balanced tree; it stores data in its leaf nodes and bookkeeping data in its interior nodes (If you don't know what tree data structures look like in general, Google for some references, because that's getting far too elementary for the purposes of this discussion).</P>
+<P>For decent performance, you need enough cache memory to contain all the nodes along the path from the root of the tree down to the particular data item you're accessing. That's enough cache for a single search. For the general case, you want enough cache to contain all the internal nodes in the database.</P>
+<PRE>
+   db_stat -d
+</PRE>
+<P>will tell you how many internal pages are present in a database. You should check this number for both dn2id and id2entry.</P>
+<P>Also note that <EM>id2entry</EM> always uses 16KB per &quot;page&quot;, while <EM>dn2id</EM> uses whatever the underlying filesystem uses, typically 4 or 8KB. To avoid thrashing the, your cache must be at least as large as the number of internal pages in both the <EM>dn2id</EM> and <EM>id2entry</EM> databases, plus some extra space to accommodate the actual leaf data pages.</P>
+<P>For example, in my OpenLDAP 2.4 test database, I have an input LDIF file that's about 360MB. With the back-hdb backend this creates a <EM>dn2id.bdb</EM> that's 68MB, and an <EM>id2entry</EM> that's 800MB. db_stat tells me that <EM>dn2id</EM> uses 4KB pages, has 433 internal pages, and 6378 leaf pages. The id2entry uses 16KB pages, has 52 internal pages, and 45912 leaf pages. In order to efficiently retrieve any single entry in this database, the cache should be at least</P>
+<PRE>
+   (433+1) * 4KB + (52+1) * 16KB in size: 1736KB + 848KB =~ 2.5MB.
+</PRE>
+<P>This doesn't take into account other library overhead, so this is even lower than the barest minimum. The default cache size, when nothing is configured, is only 256KB.</P>
+<P>This 2.5MB number also doesn't take indexing into account. Each indexed attribute uses another database file of its own, using a Hash structure.</P>
+<P>Unlike the B-trees, where you only need to touch one data page to find an entry of interest, doing an index lookup generally touches multiple keys, and the point of a hash structure is that the keys are evenly distributed across the data space. That means there's no convenient compact subset of the database that you can keep in the cache to insure quick operation, you can pretty much expect references to be scattered across the whole thing. My strategy here would be to provide enough cache for at least 50% of all of the hash data.</P>
+<PRE>
+   (Number of hash buckets + number of overflow pages + number of duplicate pages) * page size / 2.
+</PRE>
+<P>The objectClass index for my example database is 5.9MB and uses 3 hash buckets and 656 duplicate pages. So:</P>
+<PRE>
+   ( 3 + 656 ) * 4KB / 2 =~ 1.3MB.
+</PRE>
+<P>With only this index enabled, I'd figure at least a 4MB cache for this backend. (Of course you're using a single cache shared among all of the database files, so the cache pages will most likely get used for something other than what you accounted for, but this gives you a fighting chance.)</P>
+<P>With this 4MB cache I can slapcat this entire database on my 1.3GHz PIII in 1 minute, 40 seconds. With the cache doubled to 8MB, it still takes the same 1:40s. Once you've got enough cache to fit the B-tree internal pages, increasing it further won't have any effect until the cache really is large enough to hold 100% of the data pages. I don't have enough free RAM to hold all the 800MB id2entry data, so 4MB is good enough.</P>
+<P>With back-bdb and back-hdb you can use &quot;db_stat -m&quot; to check how well the database cache is performing.</P>
+<H3><A NAME="{{slapd}}(8) Entry Cache">19.4.2. <EM>slapd</EM>(8) Entry Cache</A></H3>
+<P>The <EM>slapd</EM>(8) entry cache operates on decoded entries. The rationale - entries in the entry cache can be used directly, giving the fastest response. If an entry isn't in the entry cache but can be extracted from the BDB page cache, that will avoid an I/O but it will still require parsing, so this will be slower.</P>
+<P>If the entry is in neither cache then BDB will have to flush some of its current cached pages and bring in the needed pages, resulting in a couple of expensive I/Os as well as parsing.</P>
+<P>As far as balancing the entry cache vs the BDB cache - parsed entries in memory are generally about twice as large as they are on disk.</P>
+<P>As we have already mentioned, not having a proper database cache size will cause performance issues. These issues are not an indication of corruption occurring in the database. It is merely the fact that the cache is thrashing itself that causes performance/response time to slowdown.</P>
+<P>MOVE BELOW AROUND:</P>
+<P>If you want to setup the cache size, please read:</P>
+<P>(Xref) How do I configure the BDB backend? (Xref) What are the DB_CONFIG configuration directives? http://www.sleepycat.com/docs/utility/db_recover.html</P>
+<P>A default config can be found in the answer:</P>
+<P>(Xref) What are the DB_CONFIG configuration directives?</P>
+<P>just change the set_lg_dir to point to your .log directory or comment that line.</P>
+<P>Quick guide:</P>
+<UL>
+<LI>Create a DB_CONFIG file in your ldap home directory (/var/lib/ldap/DB_CONFIG) with the correct &quot;set_cachesize&quot; value
+<LI>stop your ldap server and run db_recover -h /var/lib/ldap
+<LI>start your ldap server and check the new cache size with:</UL>
+<P>db_stat -h /var/lib/ldap -m | head -n 2</P>
+<UL>
+<LI>this procedure is only needed if you use OpenLDAP 2.2 with the BDB or HDB backends; In OpenLDAP 2.3 DB recovery is performed automatically whenever the DB_CONFIG file is changed or when an unclean shutdown is detected.<UL><UL>
+<LI>On Tuesday, February 22, 2005 12:15 PM -0500 Dusty Doris &lt;openldap at mail.doris.cc&gt; wrote:</UL></UL></UL>
+<P>Few questions, if you change the cachesize and idlecachesize entries, do you have to do anything special aside from restarting slapd, such as run slapindex or db_recover?</P>
+<P>Also, is there any way to tell how much memory these caches are taking up to make sure they are not set too large?  What happens if you set your cachesize too large and you don't have enough available memory to store these?  Will that cause an issue with openldap, or will it just not cache those entries that would make it exceed its available memory.  Will it just use some sort of FIFO on those caches?</P>
+<P>It will consume the memory resources of your system, and likely cause issues.</P>
+<P>Finally, what do most people try to achieve with these values?  Would the goal be to make these as big as the directory?  So, if I have 400,000 dn's in my directory, would it be safe to set these at 400000 or would something like 20,000 be good enough to get a nice performance increase?</P>
+<P>I try to cache the most actively used entries. Unless you expect all 400,000 entries of your DB to be accessed regularly, there is no need to cache that many entries. My entry cache is set to 20,000 (out of a little over 400,000 entries).</P>
+<P>The idlcache has to do with how many unique result sets of searches you want to store in memory. Setting up this cache will allow your most frequently placed searches to get results much faster, but I doubt you want to try and cache the results of every search that hits your system. ;)</P>
+<UL><UL><UL>
+<LI>Quanah</UL></UL></UL>
+<H3><A NAME="{{TERM:IDL}} Cache">19.4.3. <TERM>IDL</TERM> Cache</A></H3>
+<P>http://www.openldap.org/faq/data/cache/1076.html</P>
+<P></P>
+<HR>
+<H1><A NAME="Troubleshooting">20. Troubleshooting</A></H1>
+<P>If you're having trouble using OpenLDAP, get onto the OpenLDAP-Software mailing list, or:</P>
+<UL>
+<LI>Browse the list archives at <A HREF="http://www.openldap.org/lists/#archives">http://www.openldap.org/lists/#archives</A>
+<LI>Search the FAQ at <A HREF="http://www.openldap.org/faq/">http://www.openldap.org/faq/</A>
+<LI>Search the Issue Tracking System at <A HREF="http://www.openldap.org/its/">http://www.openldap.org/its/</A></UL>
+<P>Chances are the problem has been solved and explained in detail many times before.</P>
+<H2><A NAME="User or Software errors">20.1. User or Software errors?</A></H2>
+<P>More often than not, an error is caused by a configuration problem or a misunderstanding of what you are trying to implement and/or achieve.</P>
+<P>We will now attempt to discuss common user errors.</P>
+<H2><A NAME="Checklist">20.2. Checklist</A></H2>
+<P>The following checklist can help track down your problem. Please try to use if <B>before</B> posting to the list, or in the rare circumstances of reporting a bug.</P>
+<UL>
+&nbsp;</UL><OL>
+<LI><B>Use the <EM>slaptest</EM> tool to verify configurations before starting <EM>slapd</EM></B>
+<BR>
+&nbsp;
+<LI><B>Verify that <EM>slapd</EM> is listening to the specified port(s) (389 and 636, generally) before trying the <EM>ldapsearch</EM></B>
+<BR>
+&nbsp;
+<LI><B>Can you issue an <EM>ldapsearch</EM>?</B>
+<BR>
+&nbsp;
+<LI><B>If not, have you enabled complex ACLs without fully understanding them?</B>
+<BR>
+&nbsp;
+<LI><B>Do you have a system wide LDAP setting pointing to the wrong LDAP Directory?</B>
+<BR>
+&nbsp;
+<LI><B>Are you using TLS?</B>
+<BR>
+&nbsp;
+<LI><B>Have your certificates expired?</B></OL>
+<H2><A NAME="OpenLDAP Bugs">20.3. OpenLDAP Bugs</A></H2>
+<P>Sometimes you may encounter an actual OpenLDAP bug, in which case please visit our Issue Tracking system <A HREF="http://www.openldap.org/its/">http://www.openldap.org/its/</A> and report it. However, make sure it's not already a known bug or a common user problem.</P>
+<UL>
+<LI>bugs in historic versions of OpenLDAP will not be considered;
+<LI>bugs in released versions that are no longer present in HEAD code, either because they have been fixed or because they no longer apply, will not be considered as well;
+<LI>bugs in distributions of OpenLDAP software that are not related to the software as provided by OpenLDAP will not be considered; in those cases please refer to the distributor.</UL>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>Our Issue Tracking system is <B>NOT</B> for OpenLDAP <B>Support</B>, please join our mailing Lists: <A HREF="http://www.openldap.org/lists/">http://www.openldap.org/lists/</A> for that.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<P>The information you should provide in your bug report is discussed in our FAQ-O-MATIC at <A HREF="http://www.openldap.org/faq/data/cache/59.html">http://www.openldap.org/faq/data/cache/59.html</A></P>
+<H2><A NAME="3rd party software error">20.4. 3rd party software error</A></H2>
+<P>The OpenLDAP Project only supports OpenLDAP software.</P>
+<P>You may however seek commercial support (<A HREF="http://www.openldap.org/support/">http://www.openldap.org/support/</A>) or join the general LDAP forum for non-commercial discussions and information relating to LDAP at: <A HREF="http://www.umich.edu/~dirsvcs/ldap/mailinglist.html">http://www.umich.edu/~dirsvcs/ldap/mailinglist.html</A></P>
+<H2><A NAME="How to contact the OpenLDAP Project">20.5. How to contact the OpenLDAP Project</A></H2>
+<UL>
+<LI>Mailing Lists: <A HREF="http://www.openldap.org/lists/">http://www.openldap.org/lists/</A>
+<LI>Project: <A HREF="http://www.openldap.org/project/">http://www.openldap.org/project/</A>
+<LI>Issue Tracking: <A HREF="http://www.openldap.org/its/">http://www.openldap.org/its/</A></UL>
+<H2><A NAME="How to present your problem">20.6. How to present your problem</A></H2>
+<H2><A NAME="Debugging {{slapd}}(8)">20.7. Debugging <EM>slapd</EM>(8)</A></H2>
+<P>After reading through the above sections and before e-mailing the OpenLDAP lists, you might want to try out some of the following to track down the cause of your problems:</P>
+<UL>
+<LI>Loglevel 256 is generally a good first loglevel to try for getting information useful to list members on issues
+<LI>Running <EM>slapd -d -1</EM> can often track down fairly simple issues, such as missing schemas and incorrect file permissions for the <EM>slapd</EM> user to things like certs
+<LI>Check your logs for errors, as discussed at <A HREF="http://www.openldap.org/faq/data/cache/358.html">http://www.openldap.org/faq/data/cache/358.html</A></UL>
+<H2><A NAME="Commercial Support">20.8. Commercial Support</A></H2>
+<P>The firms listed at <A HREF="http://www.openldap.org/support/">http://www.openldap.org/support/</A> offer technical support services catering to OpenLDAP community.</P>
+<P>The listing of any given firm should not be viewed as an endorsement or recommendation of any kind, nor as otherwise indicating there exists a business relationship or an affiliation between any listed firm and the OpenLDAP Foundation or the OpenLDAP Project or its contributors.</P>
+<P></P>
+<HR>
+<H1><A NAME="Changes Since Previous Release">A. Changes Since Previous Release</A></H1>
+<P>The following sections attempt to summarize the new features and changes in OpenLDAP software since the 2.3.x release and the OpenLDAP Admin Guide.</P>
+<H2><A NAME="New Guide Sections">A.1. New Guide Sections</A></H2>
+<P>In order to make the Admin Guide more thorough and cover the majority of questions asked on the OpenLDAP mailing lists and scenarios discussed there, we have added the following new sections:</P>
+<UL>
+<LI><A HREF="#When should I use LDAP">When should I use LDAP?</A>
+<LI><A HREF="#When should I not use LDAP">When should I not use LDAP?</A>
+<LI><A HREF="#LDAP vs RDBMS">LDAP vs RDBMS</A>
+<LI><A HREF="#Backends">Backends</A>
+<LI><A HREF="#Overlays">Overlays</A>
+<LI><A HREF="#Replication">Replication</A>
+<LI><A HREF="#Maintenance">Maintenance</A>
+<LI><A HREF="#Monitoring">Monitoring</A>
+<LI><A HREF="#Tuning">Tuning</A>
+<LI><A HREF="#Troubleshooting">Troubleshooting</A>
+<LI><A HREF="#Changes Since Previous Release">Changes Since Previous Release</A>
+<LI><A HREF="#Upgrading from 2.3.x">Upgrading from 2.3.x</A>
+<LI><A HREF="#Common errors encountered when using OpenLDAP Software">Common errors encountered when using OpenLDAP Software</A>
+<LI><A HREF="#Recommended OpenLDAP Software Dependency Versions">Recommended OpenLDAP Software Dependency Versions</A>
+<LI><A HREF="#Real World OpenLDAP Deployments and Examples">Real World OpenLDAP Deployments and Examples</A>
+<LI><A HREF="#OpenLDAP Software Contributions">OpenLDAP Software Contributions</A>
+<LI><A HREF="#Configuration File Examples">Configuration File Examples</A>
+<LI><A HREF="#LDAP Result Codes">LDAP Result Codes</A>
+<LI><A HREF="#Glossary">Glossary</A></UL>
+<P>Also, the table of contents is now 3 levels deep to ease navigation.</P>
+<H2><A NAME="New Features and Enhancements in 2.4">A.2. New Features and Enhancements in 2.4</A></H2>
+<H3><A NAME="Better {{B:cn=config}} functionality">A.2.1. Better <B>cn=config</B> functionality</A></H3>
+<P>There is a new slapd-config(5) manpage for the <B>cn=config</B> backend. The original design called for auto-renaming of config entries when you insert or delete entries with ordered names, but that was not implemented in 2.3. It is now in 2.4. This means, e.g., if you have</P>
+<PRE>
+   olcDatabase={1}bdb,cn=config
+   olcSuffix: dc=example,dc=com
+</PRE>
+<P>and you want to add a new subordinate, now you can ldapadd:</P>
+<PRE>
+   olcDatabase={1}bdb,cn=config
+   olcSuffix: dc=foo,dc=example,dc=com
+</PRE>
+<P>This will insert a new BDB database in slot 1 and bump all following databases down one, so the original BDB database will now be named:</P>
+<PRE>
+   olcDatabase={2}bdb,cn=config
+   olcSuffix: dc=example,dc=com
+</PRE>
+<H3><A NAME="Better {{B:cn=schema}} functionality">A.2.2. Better <B>cn=schema</B> functionality</A></H3>
+<P>In 2.3 you were only able to add new schema elements, not delete or modify existing elements. In 2.4 you can modify schema at will. (Except for the hardcoded system schema, of course.)</P>
+<H3><A NAME="More sophisticated Syncrepl configurations">A.2.3. More sophisticated Syncrepl configurations</A></H3>
+<P>The original implementation of Syncrepl in OpenLDAP 2.2 was intended to support multiple consumers within the same database, but that feature never worked and was removed from OpenLDAP 2.3; you could only configure a single consumer in any database.</P>
+<P>In 2.4 you can configure multiple consumers in a single database. The configuration possibilities here are quite complex and numerous. You can configure consumers over arbitrary subtrees of a database (disjoint or overlapping). Any portion of the database may in turn be provided to other consumers using the Syncprov overlay. The Syncprov overlay works with any number of consumers over a single database or over arbitrarily many glued databases.</P>
+<H3><A NAME="N-Way Multimaster Replication">A.2.4. N-Way Multimaster Replication</A></H3>
+<P>As a consequence of the work to support multiple consumer contexts, the syncrepl system now supports full N-Way multimaster replication with entry-level conflict resolution. There are some important constraints, of course: In order to maintain consistent results across all servers, you must maintain tightly synchronized clocks across all participating servers (e.g., you must use NTP on all servers).</P>
+<P>The entryCSNs used for replication now record timestamps with microsecond resolution, instead of just seconds. The delta-syncrepl code has not been updated to support multimaster usage yet, that will come later in the 2.4 cycle.</P>
+<H3><A NAME="Replicating {{slapd}} Configuration (syncrepl and {{B:cn=config}})">A.2.5. Replicating <EM>slapd</EM> Configuration (syncrepl and <B>cn=config</B>)</A></H3>
+<P>Syncrepl was explicitly disabled on cn=config in 2.3. It is now fully supported in 2.4; you can use syncrepl to replicate an entire server configuration from one server to arbitrarily many other servers. It's possible to clone an entire running slapd using just a small (less than 10 lines) seed configuration, or you can just replicate the schema subtrees, etc. Tests 049 and 050 in the test suite provide working examples of these capabilities.</P>
+<H3><A NAME="Push-Mode Replication">A.2.6. Push-Mode Replication</A></H3>
+<P>In 2.3 you could configure syncrepl as a full push-mode replicator by using it in conjunction with a back-ldap pointed at the target server. But because the back-ldap database needs to have a suffix corresponding to the target's suffix, you could only configure one instance per slapd.</P>
+<P>In 2.4 you can define a database to be &quot;hidden&quot;, which means that its suffix is ignored when checking for name collisions, and the database will never be used to answer requests received by the frontend. Using this &quot;hidden&quot; database feature allows you to configure multiple databases with the same suffix, allowing you to set up multiple back-ldap instances for pushing replication of a single database to multiple targets. There may be other uses for hidden databases as well (e.g., using a syncrepl consumer to maintain a *local* mirror of a database on a separate filesystem).</P>
+<H3><A NAME="More extensive TLS configuration control">A.2.7. More extensive TLS configuration control</A></H3>
+<P>In 2.3, the TLS configuration in slapd was only used by the slapd listeners. For outbound connections used by e.g. back-ldap or syncrepl their TLS parameters came from the system's ldap.conf file.</P>
+<P>In 2.4 all of these sessions inherit their settings from the main slapd configuration, but settings can be individually overridden on a per-config-item basis. This is particularly helpful if you use certificate-based authentication and need to use a different client certificate for different destinations.</P>
+<H3><A NAME="Performance enhancements">A.2.8. Performance enhancements</A></H3>
+<P>Too many to list. Some notable changes - ldapadd used to be a couple of orders of magnitude slower than &quot;slapadd -q&quot;. It's now at worst only about half the speed of slapadd -q. Some comparisons of all the 2.x OpenLDAP releases are available at <A HREF="http://www.openldap.org/pub/hyc/scale2007.pdf">http://www.openldap.org/pub/hyc/scale2007.pdf</A></P>
+<P>That compared 2.0.27, 2.1.30, 2.2.30, 2.3.33, and HEAD). Toward the latter end of the &quot;Cached Search Performance&quot; chart it gets hard to see the difference because the run times are so small, but the new code is about 25% faster than 2.3, which was about 20% faster than 2.2, which was about 100% faster than 2.1, which was about 100% faster than 2.0, in that particular search scenario. That test basically searched a 1.3GB DB of 380836 entries (all in the slapd entry cache) in under 1 second. i.e., on a 2.4GHz CPU with DDR400 ECC/Registered RAM we can search over 500 thousand entries per second. The search was on an unindexed attribute using a filter that would not match any entry, forcing slapd to examine every entry in the DB, testing the filter for a match.</P>
+<P>Essentially the slapd entry cache in back-bdb/back-hdb is so efficient the search processing time is almost invisible; the runtime is limited only by the memory bandwidth of the machine. (The search data rate corresponds to about 3.5GB/sec; the memory bandwidth on the machine is only about 4GB/sec due to ECC and register latency.)</P>
+<H3><A NAME="New overlays">A.2.9. New overlays</A></H3>
+<UL>
+<LI>slapo-constraint (Attribute value constraints)
+<LI>slapo-dds (Dynamic Directory Services, RFC 2589)
+<LI>slapo-memberof (reverse group membership maintenance)</UL>
+<H3><A NAME="New features in existing Overlays">A.2.10. New features in existing Overlays</A></H3>
+<UL>
+<LI>slapo-pcache<UL>
+<LI>Inspection/Maintenance<UL>
+<LI>the cache database can be directly accessed via LDAP by adding a specific control to each LDAP request; a specific extended operation allows to consistently remove cached entries and entire cached queries</UL>
+<LI>Hot Restart<UL>
+<LI>cached queries are saved on disk at shutdown, and reloaded if not expired yet at subsequent restart</UL></UL>
+<LI>slapo-rwm can safely interoperate with other overlays
+<LI>Dyngroup/Dynlist merge, plus security enhancements<UL>
+<LI>added dgIdentity support (draft-haripriya-dynamicgroup)</UL></UL>
+<H3><A NAME="New features in slapd">A.2.11. New features in slapd</A></H3>
+<UL>
+<LI>monitoring of back-{b,h}db: cache fill-in, non-indexed searches,
+<LI>session tracking control (draft-wahl-ldap-session)
+<LI>subtree delete in back-sql (draft-armijo-ldap-treedelete)</UL>
+<H3><A NAME="New features in libldap">A.2.12. New features in libldap</A></H3>
+<UL>
+<LI>ldap_sync client API (LDAP Content Sync Operation, RFC 4533)</UL>
+<H3><A NAME="New clients, tools and tool enhancements">A.2.13. New clients, tools and tool enhancements</A></H3>
+<UL>
+<LI>ldapexop for arbitrary extended operations
+<LI>Complete support of controls in request/response for all clients
+<LI>LDAP Client tools now honor SRV records</UL>
+<H3><A NAME="New build options">A.2.14. New build options</A></H3>
+<UL>
+<LI>Support for building against GnuTLS</UL>
+<H2><A NAME="Obsolete Features Removed From 2.4">A.3. Obsolete Features Removed From 2.4</A></H2>
+<P>These features were strongly deprecated in 2.3 and removed in 2.4.</P>
+<H3><A NAME="Slurpd">A.3.1. Slurpd</A></H3>
+<P>Please read the <A HREF="#Replication">Replication</A> section as to why this is no longer in OpenLDAP</P>
+<H3><A NAME="back-ldbm">A.3.2. back-ldbm</A></H3>
+<P>back-ldbm was both slow and unreliable. Its byzantine indexing code was prone to spontaneous corruption, as were the underlying database libraries that were commonly used (e.g. GDBM or NDBM). back-bdb and back-hdb are superior in every aspect, with simplified indexing to avoid index corruption, fine-grained locking for greater concurrency, hierarchical caching for greater performance, streamlined on-disk format for greater efficiency and portability, and full transaction support for greater reliability.</P>
+<P></P>
+<HR>
+<H1><A NAME="Upgrading from 2.3.x">B. Upgrading from 2.3.x</A></H1>
+<P>The following sections attempt to document the steps you will need to take in order to upgrade from the latest 2.3.x OpenLDAP version.</P>
+<P>The normal upgrade procedure, as discussed in the <A HREF="#Maintenance">Maintenance</A> section, should of course still be followed prior to doing any of this.</P>
+<H2><A NAME="Monitor Backend">B.1. Monitor Backend</A></H2>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>This is a temporary requirement and is subject to change over the next 2.4.x beta release cycle
+<HR WIDTH="80%" ALIGN="Left"></P>
+<P>A monitor (<EM>slapd-monitor(5)</EM>) now needs a <EM>rootdn</EM> entry. If you do not have one, <EM>slapd</EM> will fail to start up with an error message like so:</P>
+<PRE>
+           monitor_back_register_entry_attrs(&quot;&quot;): base=&quot;cn=databases,cn=monitor&quot; scope=one
+           filter=&quot;(namingContexts:distinguishedNameMatch:=dc=example,dc=com)&quot;: unable to find entry
+           backend_startup_one: bi_db_open failed! (1)
+           slap_startup failed (test would succeed using the -u switch)
+</PRE>
+<P>Here is a complete <EM>database monitor</EM> example:</P>
+<PRE>
+           database monitor
+           rootdn cn=monitor
+           rootpw change_me
+</PRE>
+<H2><A NAME="{{B:cn=config}} olc* attributes">B.2. <B>cn=config</B> olc* attributes</A></H2>
+<P>Quite a few <EM>olc*</EM> attributes have now become obsolete, if you see in your logs entries like below, just remove them from the relevant ldif file.</P>
+<PRE>
+           olcReplicationInterval: value #0: &lt;olcReplicationInterval&gt; keyword is obsolete (ignored)
+</PRE>
+<P>ADD MORE HERE</P>
+<P></P>
+<HR>
+<H1><A NAME="Common errors encountered when using OpenLDAP Software">C. Common errors encountered when using OpenLDAP Software</A></H1>
+<P>The following sections attempt to summarize the most common causes of LDAP errors when using OpenLDAP</P>
+<H2><A NAME="Common causes of LDAP errors">C.1. Common causes of LDAP errors</A></H2>
+<H3><A NAME="ldap_*: Can\'t contact LDAP server">C.1.1. ldap_*: Can't contact LDAP server</A></H3>
+<P>The {[B:Can't contact LDAP server}} error is usually returned when the LDAP server cannot be contacted. This may occur for many reasons:</P>
+<UL>
+<LI>the LDAP server is not running; this can be checked by running, for example,</UL>
+<PRE>
+      telnet &lt;host&gt; &lt;port&gt;
+</PRE>
+<P>replacing <EM>&lt;host&gt;</EM> and <EM>&lt;port&gt;</EM> with the hostname and the port the server is supposed to listen on.</P>
+<UL>
+<LI>the client has not been instructed to contact a running server; with OpenLDAP command-line tools this is accomplished by providing the -H switch, whose argument is a valid LDAP url corresponding to the interface the server is supposed to be listening on.</UL>
+<H3><A NAME="ldap_*: No such object">C.1.2. ldap_*: No such object</A></H3>
+<P>The <B>no such object</B> error is generally returned when the target DN of the operation cannot be located. This section details reasons common to all operations. You should also look for answers specific to the operation (as indicated in the error message).</P>
+<P>The most common reason for this error is non-existence of the named object. First, check for typos.</P>
+<P>Also note that, by default, a new directory server holds no objects (except for a few system entries). So, if you are setting up a new directory server and get this message, it may simply be that you have yet to add the object you are trying to locate.</P>
+<P>The error commonly occurs because a DN was not specified and a default was not properly configured.</P>
+<P>If you have a suffix specified in slapd.conf eg.</P>
+<PRE>
+      suffix &quot;dc=example,dc=com&quot;
+</PRE>
+<P>You should use</P>
+<PRE>
+      ldapsearch -b 'dc=example,dc=com' '(cn=jane*)'
+</PRE>
+<P>to tell it where to start the search.</P>
+<P>The <TT>-b</TT> should be specified for all LDAP commands unless you have an <EM>ldap.conf</EM>(5) default configured.</P>
+<P>See <EM>ldapsearch</EM>(1), <EM>ldapmodify</EM>(1)</P>
+<P>Also, <EM>slapadd</EM>(8) and its ancillary programs are very strict about the syntax of the LDIF file.</P>
+<P>Some liberties in the LDIF file may result in an apparently successful creation of the database, but accessing some parts of it may be difficult.</P>
+<P>One known common error in database creation is putting a blank line before the first entry in the LDIF file. <B>There must be no leading blank lines in the LDIF file.</B></P>
+<P>It is generally recommended that <EM>ldapadd</EM>(1) be used instead of <EM>slapadd</EM>(8) when adding new entries your directory. <EM>slapadd</EM>(8) should be used to bulk load entries known to be valid.</P>
+<P>Another cause of this message is a referral ({SECT:Constructing a Distributed Directory Service}}) entry to an unpopulated directory.</P>
+<P>Either remove the referral, or add a single record with the referral base DN to the empty directory.</P>
+<P>This error may also occur when slapd is unable to access the contents of its database because of file permission problems. For instance, on a Red Hat Linux system, slapd runs as user 'ldap'. When slapadd is run as root to create a database from scratch, the contents of <TT>/var/lib/ldap</TT> are created with user and group root and with permission 600, making the contents inaccessible to the slapd server.</P>
+<H3><A NAME="ldap_*: Can\'t chase referral">C.1.3. ldap_*: Can't chase referral</A></H3>
+<P>This is caused by the line</P>
+<PRE>
+      referral        ldap://root.openldap.org
+</PRE>
+<P>In <TT>slapd.conf</TT>, it was provided as an example for how to use referrals in the original file. However if your machine is not permanently connected to the Internet, it will fail to find the server, and hence produce an error message.</P>
+<P>To resolve, just place a # in front of line and restart slapd or point it to an available ldap server.</P>
+<P>See also: <EM>ldapadd</EM>(1), <EM>ldapmodify</EM>(1) and <EM>slapd.conf</EM>(5)</P>
+<H3><A NAME="ldap_*: server is unwilling to perform">C.1.4. ldap_*: server is unwilling to perform</A></H3>
+<P>slapd will return an unwilling to perform error if the backend holding the target entry does not support the given operation.</P>
+<P>The password backend is only willing to perform searches. It will return an unwilling to perform error for all other operations.</P>
+<P>The shell backend is configurable and may support a limited subset of operations. Check for other errors indicating a shortage of resources required by the directory server. i.e. you may have a full disk etc</P>
+<H3><A NAME="ldap_*: Insufficient access">C.1.5. ldap_*: Insufficient access</A></H3>
+<P>This error occurs when server denies the operation due to insufficient access. This is usually caused by binding to a DN with insufficient privileges (or binding anonymously) to perform the operation.</P>
+<P>You can bind as the rootdn/rootpw specified in <EM>slapd.conf</EM>(5) to gain full access. Otherwise, you must bind to an entry which has been granted the appropriate rights through access controls.</P>
+<H3><A NAME="ldap_*: Invalid DN syntax">C.1.6. ldap_*: Invalid DN syntax</A></H3>
+<P>The target (or other) DN of the operation is invalid. This implies that either the string representation of the DN is not in the required form, one of the types in the attribute value assertions is not defined, or one of the values in the attribute value assertions does not conform to the appropriate syntax.</P>
+<H3><A NAME="ldap_*: Referral hop limit exceeded">C.1.7. ldap_*: Referral hop limit exceeded</A></H3>
+<P>This error generally occurs when the client chases a referral which refers itself back to a server it already contacted. The server responds as it did before and the client loops. This loop is detected when the hop limit is exceeded.</P>
+<P>This is most often caused through misconfiguration of the server's default referral. The default referral should not be itself:</P>
+<P>That is, on <A HREF="ldap://myldap/">ldap://myldap/</A> the default referral should not be <A HREF="ldap://myldap/">ldap://myldap/</A> (or any hostname/ip which is equivalent to myldap).</P>
+<H3><A NAME="ldap_*: operations error">C.1.8. ldap_*: operations error</A></H3>
+<P>In some versions of <EM>slapd</EM>(8), <EM>operationsError</EM> was returned instead of other.</P>
+<H3><A NAME="ldap_*: other error">C.1.9. ldap_*: other error</A></H3>
+<P>The other result code indicates an internal error has occurred. While the additional information provided with the result code might provide some hint as to the problem, often one will need to consult the server's log files.</P>
+<H3><A NAME="ldap_add/modify: Invalid syntax">C.1.10. ldap_add/modify: Invalid syntax</A></H3>
+<P>This error is reported when a value of an attribute does not conform to syntax restrictions. Additional information is commonly provided stating which value of which attribute was found to be invalid. Double check this value and other values (the server will only report the first error it finds).</P>
+<P>Common causes include:</P>
+<UL>
+<LI>extraneous white space (especially trailing white space)
+<LI>improperly encoded characters (LDAPv3 uses UTF-8 encoded Unicode)
+<LI>empty values (few syntaxes allow empty values)</UL>
+<P>For certain syntax, like OBJECT IDENTIFIER (OID), this error can indicate that the OID descriptor (a &quot;short name&quot;) provided is unrecognized. For instance, this error is returned if the <EM>objectClass</EM> value provided is unrecognized.</P>
+<H3><A NAME="ldap_add/modify: Object class violation">C.1.11. ldap_add/modify: Object class violation</A></H3>
+<P>This error is returned with the entry to be added or the entry as modified violates the object class schema rules. Normally additional information is returned the error detailing the violation. Some of these are detailed below.</P>
+<P>Violations related to the entry's attributes:</P>
+<PRE>
+      Attribute not allowed
+</PRE>
+<P>A provided attribute is not allowed by the entry's object class(es).</P>
+<PRE>
+      Missing required attribute
+</PRE>
+<P>An attribute required by the entry's object class(es) was not provided.</P>
+<P>Violations related to the entry's class(es):</P>
+<PRE>
+      Entry has no objectClass attribute
+</PRE>
+<P>The entry did not state which object classes it belonged to.</P>
+<PRE>
+      Unrecognized objectClass
+</PRE>
+<P>One (or more) of the listed objectClass values is not recognized.</P>
+<PRE>
+      No structural object class provided
+</PRE>
+<P>None of the listed objectClass values is structural.</P>
+<PRE>
+      Invalid structural object class chain
+</PRE>
+<P>Two or more structural objectClass values are not in same structural object class chain.</P>
+<PRE>
+      Structural object class modification
+</PRE>
+<P>Modify operation attempts to change the structural class of the entry.</P>
+<PRE>
+      Instanstantiation of abstract objectClass.
+</PRE>
+<P>An abstract class is not subordinate to any listed structural or auxiliary class.</P>
+<PRE>
+      Invalid structural object class
+</PRE>
+<P>Other structural object class problem.</P>
+<PRE>
+      No structuralObjectClass operational attribute
+</PRE>
+<P>This is commonly returned when a shadow server is provided an entry which does not contain the structuralObjectClass operational attribute.</P>
+<P>Note that the above error messages as well as the above answer assumes basic knowledge of LDAP/X.500 schema.</P>
+<H3><A NAME="ldap_add: No such object">C.1.12. ldap_add: No such object</A></H3>
+<P>The &quot;ldap_add: No such object&quot; error is commonly returned if parent of the entry being added does not exist. Add the parent entry first...</P>
+<P>For example, if you are adding &quot;cn=bob,dc=domain,dc=com&quot; and you get:</P>
+<PRE>
+      ldap_add: No such object
+</PRE>
+<P>The entry &quot;dc=domain,dc=com&quot; likely doesn't exist. You can use ldapsearch to see if does exist:</P>
+<PRE>
+      ldapsearch -b 'dc=domain,dc=com' -s base '(objectclass=*)'
+</PRE>
+<P>If it doesn't, add it. See <A HREF="#A Quick-Start Guide">A Quick-Start Guide</A> for assistance.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>if the entry being added is the same as database suffix, it's parent isn't required. i.e.: if your suffix is &quot;dc=domain,dc=com&quot;, &quot;dc=com&quot; doesn't need to exist to add &quot;dc=domain,dc=com&quot;.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<P>This error will also occur if you try to add any entry that the server is not configured to hold.</P>
+<P>For example, if your database suffix is &quot;dc=domain,dc=com&quot; and you attempt to add &quot;dc=domain2,dc=com&quot;, &quot;dc=com&quot;, &quot;dc=domain,dc=org&quot;, &quot;o=domain,c=us&quot;, or an other DN in the &quot;dc=domain,dc=com&quot; subtree, the server will return a &quot;No such object&quot; (or referral) error.</P>
+<P><EM>slapd</EM>(8) will generally return &quot;no global superior knowledge&quot; as additional information indicating its return noSuchObject instead of a referral as the server is not configured with knowledge of a global superior server.</P>
+<H3><A NAME="ldap add: invalid structural object class chain">C.1.13. ldap add: invalid structural object class chain</A></H3>
+<P>This particular error refers to the rule about STRUCTURAL objectclasses, which states that an object is of one STRUCTURAL class, the structural class of the object. The object is said to belong to this class, zero or more auxiliaries classes, and their super classes.</P>
+<P>While all of these classes are commonly listed in the objectClass attribute of the entry, one of these classes is the structural object class of the entry. Thus, it is OK for an objectClass attribute to contain inetOrgPerson, organizationalPerson, and person because they inherit one from another to form a single super class chain. That is, inetOrgPerson SUPs organizationPerson SUPs person. On the other hand, it is invalid for both inetOrgPerson and account to be listed in objectClass as inetOrgPerson and account are not part of the same super class chain (unless some other class is also listed with is a subclass of both).</P>
+<P>To resolve this problem, one must determine which class will better serve structural object class for the entry, adding this class to the objectClass attribute (if not already present), and remove any other structural class from the entry's objectClass attribute which is not a super class of the structural object class.</P>
+<P>Which object class is better depends on the particulars of the situation. One generally should consult the documentation for the applications one is using for help in making the determination.</P>
+<H3><A NAME="ldap_add: no structuralObjectClass operational attribute">C.1.14. ldap_add: no structuralObjectClass operational attribute</A></H3>
+<P>ldapadd(1) may error:</P>
+<PRE>
+      adding new entry &quot;uid=XXX,ou=People,o=campus,c=ru&quot;
+        ldap_add: Internal (implementation specific) error (80)
+           additional info: no structuralObjectClass operational attribute
+</PRE>
+<P>when slapd(8) cannot determine, based upon the contents of the objectClass attribute, what the structural class of the object should be.</P>
+<H3><A NAME="ldap_add/modify/rename: Naming violation">C.1.15. ldap_add/modify/rename: Naming violation</A></H3>
+<P>OpenLDAP's slapd checks for naming attributes and distinguished values consistency, according to RFC 4512.</P>
+<P>Naming attributes are those attributeTypes that appear in an entry's RDN; distinguished values are the values of the naming attributes that appear in an entry's RDN, e.g, in</P>
+<PRE>
+      cn=Someone+mail=someone at example.com,dc=example,dc=com
+</PRE>
+<P>the naming attributes are cn and mail, and the distinguished values are Someone and someone at example.com.</P>
+<P>OpenLDAP's slapd checks for consistency when:</P>
+<UL>
+<LI>adding an entry
+<LI>modifying an entry, if the values of the naming attributes are changed
+<LI>renaming an entry, if the RDN of the entry changes</UL>
+<P>Possible causes of error are:</P>
+<UL>
+<LI>the naming attributes are not present in the entry; for example:</UL>
+<PRE>
+                dn: dc=example,dc=com
+                objectClass: organization
+                o: Example
+                # note: &quot;dc: example&quot; is missing
+</PRE>
+<UL>
+<LI>the naming attributes are present in the entry, but in the attributeType definition they are marked as:<UL>
+<LI>collective
+<LI>operational
+<LI>obsolete</UL>
+<LI>the naming attributes are present in the entry, but the distinguished values are not; for example:</UL>
+<PRE>
+                dn: dc=example,dc=com
+                objectClass: domain
+                dc: foobar
+                # note: &quot;dc&quot; is present, but the value is not &quot;example&quot;
+</PRE>
+<UL>
+<LI>the naming attributes are present in the entry, with the distinguished values, but the naming attributes:<UL>
+<LI>do not have an equality field, so equality cannot be asserted
+<LI>the matching rule is not supported (yet)
+<LI>the matching rule is not appropriate</UL>
+<LI>the given distinguished values do not comply with their syntax
+<LI>other errors occurred during the validation/normalization/match process; this is a catchall: look at previous logs for details in case none of the above apply to your case.</UL>
+<P>In any case, make sure that the attributeType definition for the naming attributes contains an appropriate EQUALITY field; or that of the superior, if they are defined based on a superior attributeType (look at the SUP field). See RFC 4512 for details.</P>
+<H3><A NAME="ldap_add/delete/modify/rename: no global superior knowledge">C.1.16. ldap_add/delete/modify/rename: no global superior knowledge</A></H3>
+<P>If the target entry name places is not within any of the databases the server is configured to hold and the server has no knowledge of a global superior, the server will indicate it is unwilling to perform the operation and provide the text &quot;no global superior knowledge&quot; as additional text.</P>
+<P>Likely the entry name is incorrect, or the server is not properly configured to hold the named entry, or, in distributed directory environments, a default referral was not configured.</P>
+<H3><A NAME="ldap_bind: Insufficient access">C.1.17. ldap_bind: Insufficient access</A></H3>
+<P>Current versions of slapd(8) requires that clients have authentication permission to attribute types used for authentication purposes before accessing them to perform the bind operation. As all bind operations are done anonymously (regardless of previous bind success), the auth access must be granted to anonymous.</P>
+<P>In the example ACL below grants the following access:</P>
+<UL>
+<LI>to anonymous users:<UL>
+<LI>permission to authenticate using values of userPassword</UL>
+<LI>to authenticated users:<UL>
+<LI>permission to update (but not read) their userPassword
+<LI>permission to read any object excepting values of userPassword</UL></UL>
+<P>All other access is denied.</P>
+<PRE>
+        access to attr=userPassword
+          by self =w
+          by anonymous auth
+        access *
+          by self write
+          by users read
+</PRE>
+<H3><A NAME="ldap_bind: Invalid credentials">C.1.18. ldap_bind: Invalid credentials</A></H3>
+<P>The error usually occurs when the credentials (password) provided does not match the userPassword held in entry you are binding to.</P>
+<P>The error can also occur when the bind DN specified is not known to the server.</P>
+<P>Check both! In addition to the cases mentioned above you should check if the server denied access to userPassword on selected parts of the directory. In fact, slapd always returns &quot;Invalid credentials&quot; in case of failed bind, regardless of the failure reason, since other return codes could reveal the validity of the user's name.</P>
+<P>To debug access rules defined in slapd.conf, add &quot;ACL&quot; to log level.</P>
+<H3><A NAME="ldap_bind: Protocol error">C.1.19. ldap_bind: Protocol error</A></H3>
+<P>There error is generally occurs when the LDAP version requested by the client is not supported by the server.</P>
+<P>The OpenLDAP Software 2.x server, by default, only accepts version 3 LDAP Bind requests but can be configured to accept a version 2 LDAP Bind request.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>The 2.x server expects LDAPv3 [RFC4510] to be used when the client requests version 3 and expects a limited LDAPv3 variant (basically, LDAPv3 syntax and semantics in an LDAPv2 PDUs) to be used when version 2 is expected.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<P>This variant is also sometimes referred to as LDAPv2+, but differs from the U-Mich LDAP variant in a number of ways.</P>
+<H3><A NAME="ldap_modify: cannot modify object class">C.1.20. ldap_modify: cannot modify object class</A></H3>
+<P>This message is commonly returned when attempting to modify the objectClass attribute in a manner inconsistent with the LDAP/X.500 information model. In particular, it commonly occurs when one tries to change the structure of the object from one class to another, for instance, trying to change an 'apple' into a 'pear' or a 'fruit' into a 'pear'.</P>
+<P>Such changes are disallowed by the slapd(8) in accordance with LDAP and X.500 restrictions.</P>
+<H3><A NAME="ldap_sasl_interactive_bind_s: ..">C.1.21. ldap_sasl_interactive_bind_s: ...</A></H3>
+<P>If you intended to bind using a DN and password and get an error from ldap_sasl_interactive_bind_s, you likely forgot to provide a '-x' option to the command. By default, SASL authentication is used. '-x' is necessary to select &quot;simple&quot; authentication.</P>
+<H3><A NAME="ldap_sasl_interactive_bind_s: No such Object">C.1.22. ldap_sasl_interactive_bind_s: No such Object</A></H3>
+<P>This indicates that LDAP SASL authentication function could not read the Root DSE. The error will occur when the server doesn't provide a root DSE. This may be due to access controls.</P>
+<H3><A NAME="ldap_sasl_interactive_bind_s: No such attribute">C.1.23. ldap_sasl_interactive_bind_s: No such attribute</A></H3>
+<P>This indicates that LDAP SASL authentication function could read the Root DSE but it contained no supportedSASLMechanism attribute.</P>
+<P>The supportedSASLmechanism attribute lists mechanisms currently available. The list may be empty because none of the supported mechanisms are currently available. For example, EXTERNAL is listed only if the client has established its identity by authenticating at a lower level (e.g. TLS).</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>the attribute may not be visible due to access controls
+<HR WIDTH="80%" ALIGN="Left"></P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>SASL bind is the default for all OpenLDAP tools, e.g. ldapsearch(1), ldapmodify(1). To force use of &quot;simple&quot; bind, use the &quot;-x&quot; option. Use of &quot;simple&quot; bind is not recommended unless one has adequate confidentiality protection in place (e.g. TLS/SSL, IPSEC).
+<HR WIDTH="80%" ALIGN="Left"></P>
+<H3><A NAME="ldap_sasl_interactive_bind_s: Unknown authentication method">C.1.24. ldap_sasl_interactive_bind_s: Unknown authentication method</A></H3>
+<P>This indicates that none of the SASL authentication supported by the server are supported by the client, or that they are too weak or otherwise inappropriate for use by the client. Note that the default security options disallows the use of certain mechanisms such as ANONYMOUS and PLAIN (without TLS).</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>SASL bind is the default for all OpenLDAP tools. To force use of &quot;simple&quot; bind, use the &quot;-x&quot; option. Use of &quot;simple&quot; bind is not recommended unless one has adequate confidentiality protection in place (e.g. TLS/SSL, IPSEC).
+<HR WIDTH="80%" ALIGN="Left"></P>
+<H3><A NAME="ldap_sasl_interactive_bind_s: Local error (82)">C.1.25. ldap_sasl_interactive_bind_s: Local error (82)</A></H3>
+<P>Apparently not having forward and reverse DNS entries for the LDAP server can result in this error.</P>
+<H3><A NAME="ldap_search: Partial results and referral received">C.1.26. ldap_search: Partial results and referral received</A></H3>
+<P>This error is returned with the server responses to an LDAPv2 search query with both results (zero or more matched entries) and references (referrals to other servers). See also: ldapsearch(1).</P>
+<P>If the updatedn on the replica does not exist, a referral will be returned. It may do this as well if the ACL needs tweaking.</P>
+<H3><A NAME="ldap_start_tls: Operations error">C.1.27. ldap_start_tls: Operations error</A></H3>
+<P>ldapsearch(1) and other tools will return</P>
+<PRE>
+        ldap_start_tls: Operations error (1)
+              additional info: TLS already started
+</PRE>
+<P>When the user (though command line options and/or ldap.conf(5)) has requested TLS (SSL) be started twice. For instance, when specifying both &quot;-H ldaps://server.do.main&quot; and &quot;-ZZ&quot;.</P>
+<H2><A NAME="Other Errors">C.2. Other Errors</A></H2>
+<H3><A NAME="ber_get_next on fd X failed errno=34 (Numerical result out of range)">C.2.1. ber_get_next on fd X failed errno=34 (Numerical result out of range)</A></H3>
+<P>This slapd error generally indicates that the client sent a message that exceeded an administrative limit. See sockbuf_max_incoming and sockbuf_max_incoming_auth configuration directives in slapd.conf(5).</P>
+<H3><A NAME="ber_get_next on fd X failed errno=11 (Resource temporarily unavailable)">C.2.2. ber_get_next on fd X failed errno=11 (Resource temporarily unavailable)</A></H3>
+<P>This message is not indicative of abnormal behavior or error. It simply means that expected data is not yet available from the resource, in this context, a network socket. slapd(8) will process the data once it does becomes available.</P>
+<H3><A NAME="daemon: socket() failed errno=97 (Address family not supported)">C.2.3. daemon: socket() failed errno=97 (Address family not supported)</A></H3>
+<P>This message indicates that the operating system does not support one of the (protocol) address families which slapd(8) was configured to support. Most commonly, this occurs when slapd(8) was configured to support IPv6 yet the operating system kernel wasn't. In such cases, the message can be ignored.</P>
+<H3><A NAME="GSSAPI: gss_acquire_cred: Miscellaneous failure; Permission denied;">C.2.4. GSSAPI: gss_acquire_cred: Miscellaneous failure; Permission denied;</A></H3>
+<P>This message means that slapd is not running as root and, thus, it cannot get its Kerberos 5 key from the keytab, usually file /etc/krb5.keytab.</P>
+<P>A keytab file is used to store keys that are to be used by services or daemons that are started at boot time. It is very important that these secrets are kept beyond reach of intruders.</P>
+<P>That's why the default keytab file is owned by root and protected from being read by others. Do not mess with these permissions, build a different keytab file for slapd instead.</P>
+<P>To do this, start kadmin, and enter the following commands:</P>
+<PRE>
+     addprinc -randkey ldap/ldap.example.com at EXAMPLE.COM
+     ktadd -k /etc/openldap/ldap.keytab ldap/ldap.example.com at EXAMPLE.COM
+</PRE>
+<P>Then, on the shell, do:</P>
+<PRE>
+     chown ldap.ldap /etc/openldap/ldap.keytab
+     chmod 600 /etc/openldap/ldap.keytab
+</PRE>
+<P>Now you have to tell slapd (well, actually tell the gssapi library in Kerberos 5 that is invoked by Cyrus SASL) where to find the new keytab. You do this by setting the environment variable KRB5_KTNAME like this:</P>
+<PRE>
+     export KRB5_KTNAME=&quot;FILE:/etc/openldap/ldap.keytab&quot;
+</PRE>
+<P>Set that environment variable on the slapd start script (Red Hat users might find /etc/sysconfig/ldap a perfect place).</P>
+<P>This only works if you are using MIT kerberos. It doesn't work with Heimdal, for instance.</P>
+<P>In Heimdal there is a function gsskrb5_register_acceptor_identity() that sets the path of the keytab file you want to use. In Cyrus SASL 2 you can add</P>
+<PRE>
+    keytab: /path/to/file
+</PRE>
+<P>to your application's SASL config file to use this feature. This only works with Heimdal.</P>
+<H3><A NAME="access from unknown denied">C.2.5. access from unknown denied</A></H3>
+<P>This related to TCP wrappers. See hosts_access(5) for more information. in the log file: &quot;access from unknown denied&quot; This related to TCP wrappers. See hosts_access(5) for more information. for example: add the line &quot;slapd: .hosts.you.want.to.allow&quot; in /etc/hosts.allow to get rid of the error.</P>
+<H3><A NAME="ldap_read: want=# error=Resource temporarily unavailable">C.2.6. ldap_read: want=# error=Resource temporarily unavailable</A></H3>
+<P>This message occurs normally. It means that pending data is not yet available from the resource, a network socket. slapd(8) will process the data once it becomes available.</P>
+<H3><A NAME="`make test\' fails">C.2.7. `make test' fails</A></H3>
+<P>Some times, `make test' fails at the very first test with an obscure message like</P>
+<PRE>
+    make test
+    make[1]: Entering directory `/ldap_files/openldap-2.4.6/tests'
+    make[2]: Entering directory `/ldap_files/openldap-2.4.6/tests'
+    Initiating LDAP tests for BDB...
+    Cleaning up test run directory leftover from previous run.
+     Running ./scripts/all...
+    &gt;&gt;&gt;&gt;&gt; Executing all LDAP tests for bdb
+    &gt;&gt;&gt;&gt;&gt; Starting test000-rootdse ...
+    running defines.sh
+    Starting slapd on TCP/IP port 9011...
+    Using ldapsearch to retrieve the root DSE...
+    Waiting 5 seconds for slapd to start...
+    ./scripts/test000-rootdse: line 40: 10607 Segmentation fault $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING &gt;$LOG1 2&gt;&amp;1
+    Waiting 5 seconds for slapd to start...
+    Waiting 5 seconds for slapd to start...
+    Waiting 5 seconds for slapd to start...
+    Waiting 5 seconds for slapd to start...
+    Waiting 5 seconds for slapd to start...
+    ./scripts/test000-rootdse: kill: (10607) - No such pid
+    ldap_sasl_bind_s: Can't contact LDAP server (-1)
+    &gt;&gt;&gt;&gt;&gt; Test failed
+    &gt;&gt;&gt;&gt;&gt; ./scripts/test000-rootdse failed (exit 1)
+    make[2]: *** [bdb-yes] Error 1
+    make[2]: Leaving directory `/ldap_files/openldap-2.4.6/tests'
+    make[1]: *** [test] Error 2
+    make[1]: Leaving directory `/ldap_files/openldap-2.4.6/tests'
+    make: *** [test] Error 2
+</PRE>
+<P>or so. Usually, the five lines</P>
+<P>Waiting 5 seconds for slapd to start...</P>
+<P>indicate that slapd didn't start at all.</P>
+<P>In tests/testrun/slapd.1.log there is a full log of what slapd wrote while trying to start. The log level can be increased by setting the environment variable SLAPD_DEBUG to the corresponding value; see loglevel in slapd.conf(5) for the meaning of log levels.</P>
+<P>A typical reason for this behavior is a runtime link problem, i.e. slapd cannot find some dynamic libraries it was linked against. Try running ldd(1) on slapd (for those architectures that support runtime linking).</P>
+<P>There might well be other reasons; the contents of the log file should help clarifying them.</P>
+<P>Tests that fire up multiple instances of slapd typically log to tests/testrun/slapd.&lt;n&gt;.log, with a distinct &lt;n&gt; for each instance of slapd; list tests/testrun/ for possible values of &lt;n&gt;.</P>
+<H3><A NAME="ldap_*: Internal (implementation specific) error (80) - additional info: entry index delete failed">C.2.8. ldap_*: Internal (implementation specific) error (80) - additional info: entry index delete failed</A></H3>
+<P>This seems to be related with wrong ownership of the BDB's dir (/var/lib/ldap) and files.</P>
+<PRE>
+    chmod -R openldap:openldap /var/lib/ldap
+</PRE>
+<P>fixes it in Debian</P>
+<H3><A NAME="ldap_sasl_interactive_bind_s: Can\'t contact LDAP server (-1)">C.2.9. ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1)</A></H3>
+<P>Using SASL, when a client contacts LDAP server, the slapd service dies immediately and client gets an error :</P>
+<PRE>
+     SASL/GSSAPI authentication started ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1)
+</PRE>
+<P>Then check the slapd service, it stopped.</P>
+<P>This may come from incompatible of using different versions of BerkeleyDB for installing of SASL and installing of OpenLDAP. The problem arises in case of using multiple version of BerkeleyDB. Solution: - Check which version of BerkeleyDB when install Cyrus SASL.</P>
+<P>Reinstall OpenLDAP with the version of BerkeleyDB above.</P>
+<P></P>
+<HR>
+<H1><A NAME="Recommended OpenLDAP Software Dependency Versions">D. Recommended OpenLDAP Software Dependency Versions</A></H1>
+<P>This appendix details the recommended versions of the software that OpenLDAP depends on.</P>
+<P>Please read the <A HREF="#Prerequisite software">Prerequisite software</A> section for more information on the following software dependencies.</P>
+<H2><A NAME="Dependency Versions">D.1. Dependency Versions</A></H2>
+<TABLE CLASS="columns" BORDER ALIGN='Center'>
+<CAPTION ALIGN=top>Table 8.5: OpenLDAP Software Dependency Versions</CAPTION>
+<TR CLASS="heading">
+<TD>
+<STRONG>Feature</STRONG>
+</TD>
+<TD>
+<STRONG>Software</STRONG>
+</TD>
+<TD>
+<STRONG>Version</STRONG>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;<TERM>Transport Layer Security</TERM>:
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>&nbsp;<A HREF="http://www.openssl.org/">OpenSSL</A></TT>
+</TD>
+<TD>
+<TT>0.9.7+</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>&nbsp;<A HREF="http://www.gnu.org/software/gnutls/">GnuTLS</A></TT>
+</TD>
+<TD>
+<TT>2.0.1</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;<TERM>Simple Authentication and Security Layer</TERM>
+</TD>
+<TD>
+<TT>&nbsp;<A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">Cyrus SASL</A></TT>
+</TD>
+<TD>
+<TT>2.1.21+</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;<TERM>Kerberos Authentication Service</TERM>:
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>&nbsp;<A HREF="http://www.pdc.kth.se/heimdal/">Heimdal</A></TT>
+</TD>
+<TD>
+<TT>Version</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>&nbsp;<A HREF="http://web.mit.edu/kerberos/www/">MIT Kerberos</A></TT>
+</TD>
+<TD>
+<TT>Version</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+Database Software
+</TD>
+<TD>
+<TT>&nbsp;<A HREF="http://www.oracle.com/database/berkeley-db/db/index.html">Berkeley DB</A>:</TT>
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+<TD>
+<TT>4.2</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+<TD>
+<TT>4.4</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+<TD>
+<TT>4.5</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+<TD>
+<TT>4.6</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+<TD>
+<TT>Note: It is highly recommended to apply the patches from for a given release.</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+Threads:
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+<TD>
+<TT>&nbsp;</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>POSIX <EM>pthreads</EM></TT>
+</TD>
+<TD>
+<TT>Version</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+&nbsp;
+</TD>
+<TD>
+<TT>Mach <EM>CThreads</EM></TT>
+</TD>
+<TD>
+<TT>Version</TT>
+</TD>
+</TR>
+<TR>
+<TD>
+TCP Wrappers
+</TD>
+<TD>
+<TT>Name</TT>
+</TD>
+<TD>
+<TT>Version</TT>
+</TD>
+</TR>
+</TABLE>
+
+<P></P>
+<HR>
+<H1><A NAME="Real World OpenLDAP Deployments and Examples">E. Real World OpenLDAP Deployments and Examples</A></H1>
+<P>Examples and discussions</P>
+<P></P>
+<HR>
+<H1><A NAME="OpenLDAP Software Contributions">F. OpenLDAP Software Contributions</A></H1>
+<P>The following sections attempt to summarize the various contributions in OpenLDAP software, as found in <TT>openldap_src/contrib</TT></P>
+<H2><A NAME="Client APIs">F.1. Client APIs</A></H2>
+<P>Intro and discuss</P>
+<H3><A NAME="ldapc++">F.1.1. ldapc++</A></H3>
+<P>Intro and discuss</P>
+<H3><A NAME="ldaptcl">F.1.2. ldaptcl</A></H3>
+<P>Intro and discuss</P>
+<H2><A NAME="Overlays">F.2. Overlays</A></H2>
+<P>Intro and complete/expand correct names for below:</P>
+<H3><A NAME="acl">F.2.1. acl</A></H3>
+<H3><A NAME="addpartial">F.2.2. addpartial</A></H3>
+<H3><A NAME="allop">F.2.3. allop</A></H3>
+<H3><A NAME="comp_match">F.2.4. comp_match</A></H3>
+<H3><A NAME="denyop">F.2.5. denyop</A></H3>
+<H3><A NAME="dsaschema">F.2.6. dsaschema</A></H3>
+<H3><A NAME="lastmod">F.2.7. lastmod</A></H3>
+<H3><A NAME="passwd">F.2.8. passwd</A></H3>
+<H3><A NAME="proxyOld">F.2.9. proxyOld</A></H3>
+<H3><A NAME="smbk5pwd">F.2.10. smbk5pwd</A></H3>
+<H3><A NAME="trace">F.2.11. trace</A></H3>
+<H2><A NAME="Tools">F.3. Tools</A></H2>
+<P>Intro and discuss</P>
+<H3><A NAME="Statistic Logging">F.3.1. Statistic Logging</A></H3>
+<P>statslog</P>
+<H2><A NAME="SLAPI Plugins">F.4. SLAPI Plugins</A></H2>
+<P>Intro and discuss</P>
+<H3><A NAME="addrdnvalues">F.4.1. addrdnvalues</A></H3>
+<P>More</P>
+<P></P>
+<HR>
+<H1><A NAME="Configuration File Examples">G. Configuration File Examples</A></H1>
+<H2><A NAME="slapd.conf">G.1. slapd.conf</A></H2>
+<H2><A NAME="ldap.conf">G.2. ldap.conf</A></H2>
+<H2><A NAME="a-n-other.conf">G.3. a-n-other.conf</A></H2>
+<P></P>
+<HR>
+<H1><A NAME="LDAP Result Codes">H. LDAP Result Codes</A></H1>
+<P>For the purposes of this guide, we have incorporated the standard LDAP result codes from <EM>Appendix A.  LDAP Result Codes</EM> of rfc4511. A copy of which can be found in <TT>doc/rfc</TT> of the OpenLDAP source code.</P>
+<P>We have expanded the description of each error in relation to the OpenLDAP toolsets.</P>
+<H2><A NAME="Non-Error Result Codes">H.1. Non-Error Result Codes</A></H2>
+<P>These result codes (called &quot;non-error&quot; result codes) do not indicate an error condition:</P>
+<PRE>
+        success (0),
+        compareFalse (5),
+        compareTrue (6),
+        referral (10), and
+        saslBindInProgress (14).
+</PRE>
+<P>The <EM>success</EM>, <EM>compareTrue</EM>, and <EM>compareFalse</EM> result codes indicate successful completion (and, hence, are referred to as &quot;successful&quot; result codes).</P>
+<P>The <EM>referral</EM> and <EM>saslBindInProgress</EM> result codes indicate the client needs to take additional action to complete the operation.</P>
+<H2><A NAME="Result Codes">H.2. Result Codes</A></H2>
+<P>Existing LDAP result codes are described as follows:</P>
+<H2><A NAME="{{success (0)}}">H.3. <EM>success (0)</EM></A></H2>
+<P>Indicates the successful completion of an operation.</P>
+<P><HR WIDTH="80%" ALIGN="Left">
+<STRONG>Note: </STRONG>this code is not used with the Compare operation.  See <A HREF="#compareFalse (5)">compareFalse (5)</A> and <A HREF="#compareTrue (6)">compareTrue (6)</A>.
+<HR WIDTH="80%" ALIGN="Left"></P>
+<H2><A NAME="{{operationsError (1)}}">H.4. <EM>operationsError (1)</EM></A></H2>
+<P>Indicates that the operation is not properly sequenced with relation to other operations (of same or different type).</P>
+<P>For example, this code is returned if the client attempts to StartTLS [RFC4346] while there are other uncompleted operations or if a TLS layer was already installed.</P>
+<H2><A NAME="{{protocolError (2)}}">H.5. <EM>protocolError (2)</EM></A></H2>
+<P>Indicates the server received data that is not well-formed.</P>
+<P>For Bind operation only, this code is also used to indicate that the server does not support the requested protocol version.</P>
+<P>For Extended operations only, this code is also used to indicate that the server does not support (by design or configuration) the Extended operation associated with the <EM>requestName</EM>.</P>
+<P>For request operations specifying multiple controls, this may be used to indicate that the server cannot ignore the order of the controls as specified, or that the combination of the specified controls is invalid or unspecified.</P>
+<H2><A NAME="{{timeLimitExceeded (3)}}">H.6. <EM>timeLimitExceeded (3)</EM></A></H2>
+<P>Indicates that the time limit specified by the client was exceeded before the operation could be completed.</P>
+<H2><A NAME="{{sizeLimitExceeded (4)}}">H.7. <EM>sizeLimitExceeded (4)</EM></A></H2>
+<P>Indicates that the size limit specified by the client was exceeded before the operation could be completed.</P>
+<H2><A NAME="{{compareFalse (5)}}">H.8. <EM>compareFalse (5)</EM></A></H2>
+<P>Indicates that the Compare operation has successfully completed and the assertion has evaluated to FALSE or Undefined.</P>
+<H2><A NAME="{{compareTrue (6)}}">H.9. <EM>compareTrue (6)</EM></A></H2>
+<P>Indicates that the Compare operation has successfully completed and the assertion has evaluated to TRUE.</P>
+<H2><A NAME="{{authMethodNotSupported (7)}}">H.10. <EM>authMethodNotSupported (7)</EM></A></H2>
+<P>Indicates that the authentication method or mechanism is not supported.</P>
+<H2><A NAME="{{strongerAuthRequired (8)}}">H.11. <EM>strongerAuthRequired (8)</EM></A></H2>
+<P>Indicates the server requires strong(er) authentication in order to complete the operation.</P>
+<P>When used with the Notice of Disconnection operation, this code indicates that the server has detected that an established security association between the client and server has unexpectedly failed or been compromised.</P>
+<H2><A NAME="{{referral (10)}}">H.12. <EM>referral (10)</EM></A></H2>
+<P>Indicates that a referral needs to be chased to complete the operation (see Section 4.1.10).</P>
+<H2><A NAME="{{adminLimitExceeded (11)}}">H.13. <EM>adminLimitExceeded (11)</EM></A></H2>
+<P>Indicates that an administrative limit has been exceeded.</P>
+<H2><A NAME="{{unavailableCriticalExtension (12)}}">H.14. <EM>unavailableCriticalExtension (12)</EM></A></H2>
+<P>Indicates a critical control is unrecognized (see Section 4.1.11).</P>
+<H2><A NAME="{{confidentialityRequired (13)}}">H.15. <EM>confidentialityRequired (13)</EM></A></H2>
+<P>Indicates that data confidentiality protections are required.</P>
+<H2><A NAME="{{saslBindInProgress (14)}}">H.16. <EM>saslBindInProgress (14)</EM></A></H2>
+<P>Indicates the server requires the client to send a new bind request, with the same SASL mechanism, to continue the authentication process (see Section 4.2).</P>
+<H2><A NAME="{{noSuchAttribute (16)}}">H.17. <EM>noSuchAttribute (16)</EM></A></H2>
+<P>Indicates that the named entry does not contain the specified attribute or attribute value.</P>
+<H2><A NAME="{{undefinedAttributeType (17)}}">H.18. <EM>undefinedAttributeType (17)</EM></A></H2>
+<P>Indicates that a request field contains an unrecognized attribute description.</P>
+<H2><A NAME="{{inappropriateMatching (18)}}">H.19. <EM>inappropriateMatching (18)</EM></A></H2>
+<P>Indicates that an attempt was made (e.g., in an assertion) to use a matching rule not defined for the attribute type concerned.</P>
+<H2><A NAME="{{constraintViolation (19)}}">H.20. <EM>constraintViolation (19)</EM></A></H2>
+<P>Indicates that the client supplied an attribute value that does not conform to the constraints placed upon it by the data model.</P>
+<P>For example, this code is returned when multiple values are supplied to an attribute that has a SINGLE-VALUE constraint.</P>
+<H2><A NAME="{{attributeOrValueExists (20)}}">H.21. <EM>attributeOrValueExists (20)</EM></A></H2>
+<P>Indicates that the client supplied an attribute or value to be added to an entry, but the attribute or value already exists.</P>
+<H2><A NAME="{{invalidAttributeSyntax (21)}}">H.22. <EM>invalidAttributeSyntax (21)</EM></A></H2>
+<P>Indicates that a purported attribute value does not conform to the syntax of the attribute.</P>
+<H2><A NAME="{{noSuchObject (32)}}">H.23. <EM>noSuchObject (32)</EM></A></H2>
+<P>Indicates that the object does not exist in the DIT.</P>
+<H2><A NAME="{{aliasProblem (33)}}">H.24. <EM>aliasProblem (33)</EM></A></H2>
+<P>Indicates that an alias problem has occurred.  For example, the code may used to indicate an alias has been dereferenced that names no object.</P>
+<H2><A NAME="{{invalidDNSyntax (34)}}">H.25. <EM>invalidDNSyntax (34)</EM></A></H2>
+<P>Indicates that an LDAPDN or RelativeLDAPDN field (e.g., search base, target entry, ModifyDN newrdn, etc.) of a request does not conform to the required syntax or contains attribute values that do not conform to the syntax of the attribute's type.</P>
+<H2><A NAME="{{aliasDereferencingProblem (36)}}">H.26. <EM>aliasDereferencingProblem (36)</EM></A></H2>
+<P>Indicates that a problem occurred while dereferencing an alias.  Typically, an alias was encountered in a situation where it was not allowed or where access was denied.</P>
+<H2><A NAME="{{inappropriateAuthentication (48)}}">H.27. <EM>inappropriateAuthentication (48)</EM></A></H2>
+<P>Indicates the server requires the client that had attempted to bind anonymously or without supplying credentials to provide some form of credentials.</P>
+<H2><A NAME="{{invalidCredentials (49)}}">H.28. <EM>invalidCredentials (49)</EM></A></H2>
+<P>Indicates that the provided credentials (e.g., the user's name and password) are invalid.</P>
+<H2><A NAME="{{insufficientAccessRights (50)}}">H.29. <EM>insufficientAccessRights (50)</EM></A></H2>
+<P>Indicates that the client does not have sufficient access rights to perform the operation.</P>
+<H2><A NAME="{{busy (51)}}">H.30. <EM>busy (51)</EM></A></H2>
+<P>Indicates that the server is too busy to service the operation.</P>
+<H2><A NAME="{{unavailable (52)}}">H.31. <EM>unavailable (52)</EM></A></H2>
+<P>Indicates that the server is shutting down or a subsystem necessary to complete the operation is offline.</P>
+<H2><A NAME="{{unwillingToPerform (53)}}">H.32. <EM>unwillingToPerform (53)</EM></A></H2>
+<P>Indicates that the server is unwilling to perform the operation.</P>
+<H2><A NAME="{{loopDetect (54)}}">H.33. <EM>loopDetect (54)</EM></A></H2>
+<P>Indicates that the server has detected an internal loop (e.g., while dereferencing aliases or chaining an operation).</P>
+<H2><A NAME="{{namingViolation (64)}}">H.34. <EM>namingViolation (64)</EM></A></H2>
+<P>Indicates that the entry's name violates naming restrictions.</P>
+<H2><A NAME="{{objectClassViolation (65)}}">H.35. <EM>objectClassViolation (65)</EM></A></H2>
+<P>Indicates that the entry violates object class restrictions.</P>
+<H2><A NAME="{{notAllowedOnNonLeaf (66)}}">H.36. <EM>notAllowedOnNonLeaf (66)</EM></A></H2>
+<P>Indicates that the operation is inappropriately acting upon a non-leaf entry.</P>
+<H2><A NAME="{{notAllowedOnRDN (67)}}">H.37. <EM>notAllowedOnRDN (67)</EM></A></H2>
+<P>Indicates that the operation is inappropriately attempting to remove a value that forms the entry's relative distinguished name.</P>
+<H2><A NAME="{{entryAlreadyExists (68)}}">H.38. <EM>entryAlreadyExists (68)</EM></A></H2>
+<P>Indicates that the request cannot be fulfilled (added, moved, or renamed) as the target entry already exists.</P>
+<H2><A NAME="{{objectClassModsProhibited (69)}}">H.39. <EM>objectClassModsProhibited (69)</EM></A></H2>
+<P>Indicates that an attempt to modify the object class(es) of an entry's 'objectClass' attribute is prohibited.</P>
+<P>For example, this code is returned when a client attempts to modify the structural object class of an entry.</P>
+<H2><A NAME="{{affectsMultipleDSAs (71)}}">H.40. <EM>affectsMultipleDSAs (71)</EM></A></H2>
+<P>Indicates that the operation cannot be performed as it would affect multiple servers (DSAs).</P>
+<H2><A NAME="{{other (80)}}">H.41. <EM>other (80)</EM></A></H2>
+<P>Indicates the server has encountered an internal error.</P>
+<P></P>
+<HR>
+<H1><A NAME="Glossary">I. Glossary</A></H1>
+<H2><A NAME="Terms">I.1. Terms</A></H2>
+<TABLE CLASS="plain">
+<TR CLASS="heading">
+<TD>
+<STRONG>Term</STRONG>
+</TD>
+<TD>
+<STRONG>Definition</STRONG>
+</TD>
+</TR>
+<TR>
+<TD>
+3DES
+</TD>
+<TD>
+Triple DES
+</TD>
+</TR>
+<TR>
+<TD>
+ABNF
+</TD>
+<TD>
+Augmented Backus-Naur Form
+</TD>
+</TR>
+<TR>
+<TD>
+ACDF
+</TD>
+<TD>
+Access Control Decision Function
+</TD>
+</TR>
+<TR>
+<TD>
+ACE
+</TD>
+<TD>
+ASCII Compatible Encoding
+</TD>
+</TR>
+<TR>
+<TD>
+ASCII
+</TD>
+<TD>
+American Standard Code for Information Interchange
+</TD>
+</TR>
+<TR>
+<TD>
+ACID
+</TD>
+<TD>
+Atomicity, Consistency, Isolation, and Durability
+</TD>
+</TR>
+<TR>
+<TD>
+ACI
+</TD>
+<TD>
+Access Control Information
+</TD>
+</TR>
+<TR>
+<TD>
+ACL
+</TD>
+<TD>
+Access Control List
+</TD>
+</TR>
+<TR>
+<TD>
+AES
+</TD>
+<TD>
+Advance Encryption Standard
+</TD>
+</TR>
+<TR>
+<TD>
+ABI
+</TD>
+<TD>
+Application Binary Interface
+</TD>
+</TR>
+<TR>
+<TD>
+API
+</TD>
+<TD>
+Application Program Interface
+</TD>
+</TR>
+<TR>
+<TD>
+ASN.1
+</TD>
+<TD>
+Abstract Syntax Notation - One
+</TD>
+</TR>
+<TR>
+<TD>
+AVA
+</TD>
+<TD>
+Attribute Value Assertion
+</TD>
+</TR>
+<TR>
+<TD>
+AuthcDN
+</TD>
+<TD>
+Authentication DN
+</TD>
+</TR>
+<TR>
+<TD>
+AuthcId
+</TD>
+<TD>
+Authentication Identity
+</TD>
+</TR>
+<TR>
+<TD>
+AuthzDN
+</TD>
+<TD>
+Authorizaiton DN
+</TD>
+</TR>
+<TR>
+<TD>
+AuthzId
+</TD>
+<TD>
+Authorization Identity
+</TD>
+</TR>
+<TR>
+<TD>
+BCP
+</TD>
+<TD>
+Best Current Practice
+</TD>
+</TR>
+<TR>
+<TD>
+BDB
+</TD>
+<TD>
+Berkeley DB (Backend)
+</TD>
+</TR>
+<TR>
+<TD>
+BER
+</TD>
+<TD>
+Basic Encoding Rules
+</TD>
+</TR>
+<TR>
+<TD>
+BNF
+</TD>
+<TD>
+Backus-Naur Form
+</TD>
+</TR>
+<TR>
+<TD>
+C
+</TD>
+<TD>
+The C Programming Language
+</TD>
+</TR>
+<TR>
+<TD>
+CA
+</TD>
+<TD>
+Certificate Authority
+</TD>
+</TR>
+<TR>
+<TD>
+CER
+</TD>
+<TD>
+Canonical Encoding Rules
+</TD>
+</TR>
+<TR>
+<TD>
+CLDAP
+</TD>
+<TD>
+Connection-less LDAP
+</TD>
+</TR>
+<TR>
+<TD>
+CN
+</TD>
+<TD>
+Common Name
+</TD>
+</TR>
+<TR>
+<TD>
+CRAM-MD5
+</TD>
+<TD>
+SASL MD5 Challedge/Response Authentication Mechanism
+</TD>
+</TR>
+<TR>
+<TD>
+CRL
+</TD>
+<TD>
+Certificate Revocation List
+</TD>
+</TR>
+<TR>
+<TD>
+DAP
+</TD>
+<TD>
+Directory Access Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+DC
+</TD>
+<TD>
+Domain Component
+</TD>
+</TR>
+<TR>
+<TD>
+DER
+</TD>
+<TD>
+Distinguished Encoding Rules
+</TD>
+</TR>
+<TR>
+<TD>
+DES
+</TD>
+<TD>
+Data Encryption Standard
+</TD>
+</TR>
+<TR>
+<TD>
+DIB
+</TD>
+<TD>
+Directory Information Base
+</TD>
+</TR>
+<TR>
+<TD>
+DIGEST-MD5
+</TD>
+<TD>
+SASL Digest MD5 Authentication Mechanism
+</TD>
+</TR>
+<TR>
+<TD>
+DISP
+</TD>
+<TD>
+Directory Information Shadowing Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+DIT
+</TD>
+<TD>
+Directory Information Tree
+</TD>
+</TR>
+<TR>
+<TD>
+DNS
+</TD>
+<TD>
+Domain Name System
+</TD>
+</TR>
+<TR>
+<TD>
+DN
+</TD>
+<TD>
+Distinguished Name
+</TD>
+</TR>
+<TR>
+<TD>
+DOP
+</TD>
+<TD>
+Directory Operational Binding Management Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+DSAIT
+</TD>
+<TD>
+DSA Information Tree
+</TD>
+</TR>
+<TR>
+<TD>
+DSA
+</TD>
+<TD>
+Directory System Agent
+</TD>
+</TR>
+<TR>
+<TD>
+DSE
+</TD>
+<TD>
+DSA-specific Entry
+</TD>
+</TR>
+<TR>
+<TD>
+DSP
+</TD>
+<TD>
+Directory System Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+DS
+</TD>
+<TD>
+Draft Standard
+</TD>
+</TR>
+<TR>
+<TD>
+DUA
+</TD>
+<TD>
+Directory User Agent
+</TD>
+</TR>
+<TR>
+<TD>
+EXTERNAL
+</TD>
+<TD>
+SASL External Authentication Mechanism
+</TD>
+</TR>
+<TR>
+<TD>
+FAQ
+</TD>
+<TD>
+Frequently Asked Questions
+</TD>
+</TR>
+<TR>
+<TD>
+FTP
+</TD>
+<TD>
+File Transfer Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+FYI
+</TD>
+<TD>
+For Your Information
+</TD>
+</TR>
+<TR>
+<TD>
+GSER
+</TD>
+<TD>
+Generic String Encoding Rules
+</TD>
+</TR>
+<TR>
+<TD>
+GSS-API
+</TD>
+<TD>
+Generic Security Service Application Program Interface
+</TD>
+</TR>
+<TR>
+<TD>
+GSSAPI
+</TD>
+<TD>
+SASL Kerberos V GSS-API Authentication Mechanism
+</TD>
+</TR>
+<TR>
+<TD>
+HDB
+</TD>
+<TD>
+Hierarchical Database (Backend)
+</TD>
+</TR>
+<TR>
+<TD>
+I-D
+</TD>
+<TD>
+Internet-Draft
+</TD>
+</TR>
+<TR>
+<TD>
+IA5
+</TD>
+<TD>
+International Alphabet 5
+</TD>
+</TR>
+<TR>
+<TD>
+IDNA
+</TD>
+<TD>
+Internationalized Domain Names in Applications
+</TD>
+</TR>
+<TR>
+<TD>
+IDN
+</TD>
+<TD>
+Internationalized Domain Name
+</TD>
+</TR>
+<TR>
+<TD>
+ID
+</TD>
+<TD>
+Identifier
+</TD>
+</TR>
+<TR>
+<TD>
+IDL
+</TD>
+<TD>
+Index Data Lookups
+</TD>
+</TR>
+<TR>
+<TD>
+IP
+</TD>
+<TD>
+Internet Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+IPC
+</TD>
+<TD>
+Inter-process communication
+</TD>
+</TR>
+<TR>
+<TD>
+IPsec
+</TD>
+<TD>
+Internet Protocol Security
+</TD>
+</TR>
+<TR>
+<TD>
+IPv4
+</TD>
+<TD>
+Internet Protocol, version 4
+</TD>
+</TR>
+<TR>
+<TD>
+IPv6
+</TD>
+<TD>
+Internet Protocol, version 6
+</TD>
+</TR>
+<TR>
+<TD>
+ITS
+</TD>
+<TD>
+Issue Tracking System
+</TD>
+</TR>
+<TR>
+<TD>
+JPEG
+</TD>
+<TD>
+Joint Photographic Experts Group
+</TD>
+</TR>
+<TR>
+<TD>
+Kerberos
+</TD>
+<TD>
+Kerberos Authentication Service
+</TD>
+</TR>
+<TR>
+<TD>
+LBER
+</TD>
+<TD>
+Lightweight BER
+</TD>
+</TR>
+<TR>
+<TD>
+LDAP
+</TD>
+<TD>
+Lightweight Directory Access Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+LDAP Sync
+</TD>
+<TD>
+LDAP Content Sychronization
+</TD>
+</TR>
+<TR>
+<TD>
+LDAPv3
+</TD>
+<TD>
+LDAP, version 3
+</TD>
+</TR>
+<TR>
+<TD>
+LDIF
+</TD>
+<TD>
+LDAP Data Interchange Format
+</TD>
+</TR>
+<TR>
+<TD>
+MD5
+</TD>
+<TD>
+Message Digest 5
+</TD>
+</TR>
+<TR>
+<TD>
+MIB
+</TD>
+<TD>
+Management Information Base
+</TD>
+</TR>
+<TR>
+<TD>
+MODDN
+</TD>
+<TD>
+Modify DN
+</TD>
+</TR>
+<TR>
+<TD>
+MODRDN
+</TD>
+<TD>
+Modify RDN
+</TD>
+</TR>
+<TR>
+<TD>
+NSSR
+</TD>
+<TD>
+Non-specific Subordinate Reference
+</TD>
+</TR>
+<TR>
+<TD>
+OID
+</TD>
+<TD>
+Object Identifier
+</TD>
+</TR>
+<TR>
+<TD>
+OSI
+</TD>
+<TD>
+Open Systems Interconnect
+</TD>
+</TR>
+<TR>
+<TD>
+OTP
+</TD>
+<TD>
+One Time Password
+</TD>
+</TR>
+<TR>
+<TD>
+PDU
+</TD>
+<TD>
+Protocol Data Unit
+</TD>
+</TR>
+<TR>
+<TD>
+PEM
+</TD>
+<TD>
+Privacy Enhanced eMail
+</TD>
+</TR>
+<TR>
+<TD>
+PEN
+</TD>
+<TD>
+Private Enterprise Number
+</TD>
+</TR>
+<TR>
+<TD>
+PKCS
+</TD>
+<TD>
+Public Key Cryptosystem
+</TD>
+</TR>
+<TR>
+<TD>
+PKI
+</TD>
+<TD>
+Public Key Infrastructure
+</TD>
+</TR>
+<TR>
+<TD>
+PKIX
+</TD>
+<TD>
+Public Key Infrastructure (X.509)
+</TD>
+</TR>
+<TR>
+<TD>
+PLAIN
+</TD>
+<TD>
+SASL Plaintext Password Authentication Mechanism
+</TD>
+</TR>
+<TR>
+<TD>
+POSIX
+</TD>
+<TD>
+Portable Operating System Interface
+</TD>
+</TR>
+<TR>
+<TD>
+PS
+</TD>
+<TD>
+Proposed Standard
+</TD>
+</TR>
+<TR>
+<TD>
+RDN
+</TD>
+<TD>
+Relative Distinguished Name
+</TD>
+</TR>
+<TR>
+<TD>
+RFC
+</TD>
+<TD>
+Request for Comments
+</TD>
+</TR>
+<TR>
+<TD>
+RPC
+</TD>
+<TD>
+Remote Procedure Call
+</TD>
+</TR>
+<TR>
+<TD>
+RXER
+</TD>
+<TD>
+Robust XML Encoding Rules
+</TD>
+</TR>
+<TR>
+<TD>
+SASL
+</TD>
+<TD>
+Simple Authentication and Security Layer
+</TD>
+</TR>
+<TR>
+<TD>
+SDF
+</TD>
+<TD>
+Simple Document Format
+</TD>
+</TR>
+<TR>
+<TD>
+SDSE
+</TD>
+<TD>
+Shadowed DSE
+</TD>
+</TR>
+<TR>
+<TD>
+SHA1
+</TD>
+<TD>
+Secure Hash Algorithm 1
+</TD>
+</TR>
+<TR>
+<TD>
+SLAPD
+</TD>
+<TD>
+Standalone LDAP Daemon
+</TD>
+</TR>
+<TR>
+<TD>
+SLURPD
+</TD>
+<TD>
+Standalone LDAP Update Replication Daemon
+</TD>
+</TR>
+<TR>
+<TD>
+SMTP
+</TD>
+<TD>
+Simple Mail Transfer Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+SNMP
+</TD>
+<TD>
+Simple Network Management Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+SQL
+</TD>
+<TD>
+Structured Query Language
+</TD>
+</TR>
+<TR>
+<TD>
+SRP
+</TD>
+<TD>
+Secure Remote Password
+</TD>
+</TR>
+<TR>
+<TD>
+SSF
+</TD>
+<TD>
+Security Strength Factor
+</TD>
+</TR>
+<TR>
+<TD>
+SSL
+</TD>
+<TD>
+Secure Socket Layer
+</TD>
+</TR>
+<TR>
+<TD>
+STD
+</TD>
+<TD>
+Internet Standard
+</TD>
+</TR>
+<TR>
+<TD>
+TCP
+</TD>
+<TD>
+Transmission Control Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+TLS
+</TD>
+<TD>
+Transport Layer Security
+</TD>
+</TR>
+<TR>
+<TD>
+UCS
+</TD>
+<TD>
+Universal Multiple-Octet Coded Character Set
+</TD>
+</TR>
+<TR>
+<TD>
+UDP
+</TD>
+<TD>
+User Datagram Protocol
+</TD>
+</TR>
+<TR>
+<TD>
+UID
+</TD>
+<TD>
+User Identifier
+</TD>
+</TR>
+<TR>
+<TD>
+Unicode
+</TD>
+<TD>
+The Unicode Standard
+</TD>
+</TR>
+<TR>
+<TD>
+UNIX
+</TD>
+<TD>
+Unix
+</TD>
+</TR>
+<TR>
+<TD>
+URI
+</TD>
+<TD>
+Uniform Resource Identifier
+</TD>
+</TR>
+<TR>
+<TD>
+URL
+</TD>
+<TD>
+Uniform Resource Locator
+</TD>
+</TR>
+<TR>
+<TD>
+URN
+</TD>
+<TD>
+Uniform Resource Name
+</TD>
+</TR>
+<TR>
+<TD>
+UTF-8
+</TD>
+<TD>
+8-bit UCS/Unicode Transformation Format
+</TD>
+</TR>
+<TR>
+<TD>
+UTR
+</TD>
+<TD>
+Unicode Technical Report
+</TD>
+</TR>
+<TR>
+<TD>
+UUID
+</TD>
+<TD>
+Universally Unique Identifier
+</TD>
+</TR>
+<TR>
+<TD>
+WWW
+</TD>
+<TD>
+World Wide Web
+</TD>
+</TR>
+<TR>
+<TD>
+X.500
+</TD>
+<TD>
+X.500 Directory Services
+</TD>
+</TR>
+<TR>
+<TD>
+X.509
+</TD>
+<TD>
+X.509 Public Key and Attribute Certificate Frameworks
+</TD>
+</TR>
+<TR>
+<TD>
+XED
+</TD>
+<TD>
+XML Enabled Directory
+</TD>
+</TR>
+<TR>
+<TD>
+XER
+</TD>
+<TD>
+XML Encoding Rules
+</TD>
+</TR>
+<TR>
+<TD>
+XML
+</TD>
+<TD>
+Extensible Markup Language
+</TD>
+</TR>
+<TR>
+<TD>
+syncrepl
+</TD>
+<TD>
+LDAP Sync-based Replication
+</TD>
+</TR>
+</TABLE>
+
+<H2><A NAME="Related Organizations">I.2. Related Organizations</A></H2>
+<TABLE CLASS="plain">
+<TR CLASS="heading">
+<TD>
+<STRONG>Name</STRONG>
+</TD>
+<TD>
+<STRONG>Long</STRONG>
+</TD>
+<TD>
+<STRONG>Jump</STRONG>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.ansi.org/">ANSI</A>
+</TD>
+<TD>
+American National Standards Institute
+</TD>
+<TD>
+<A HREF="http://www.ansi.org/">http://www.ansi.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.bsi-global.com/">BSI</A>
+</TD>
+<TD>
+British Standards Institute
+</TD>
+<TD>
+<A HREF="http://www.bsi-global.com/">http://www.bsi-global.com/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<ORG>COSINE</ORG>
+</TD>
+<TD>
+Co-operation and Open Systems Interconnection in Europe
+</TD>
+<TD>
+<JUMP>&nbsp;</JUMP>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://cpan.org/">CPAN</A>
+</TD>
+<TD>
+Comprehensive Perl Archive Network
+</TD>
+<TD>
+<A HREF="http://cpan.org/">http://cpan.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://cyrusimap.web.cmu.edu/">Cyrus</A>
+</TD>
+<TD>
+Project Cyrus
+</TD>
+<TD>
+<A HREF="http://cyrusimap.web.cmu.edu/">http://cyrusimap.web.cmu.edu/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.fsf.org/">FSF</A>
+</TD>
+<TD>
+Free Software Foundation
+</TD>
+<TD>
+<A HREF="http://www.fsf.org/">http://www.fsf.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.gnu.org/">GNU</A>
+</TD>
+<TD>
+GNU Not Unix Project
+</TD>
+<TD>
+<A HREF="http://www.gnu.org/">http://www.gnu.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.iab.org/">IAB</A>
+</TD>
+<TD>
+Internet Architecture Board
+</TD>
+<TD>
+<A HREF="http://www.iab.org/">http://www.iab.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.iana.org/">IANA</A>
+</TD>
+<TD>
+Internet Assigned Numbers Authority
+</TD>
+<TD>
+<A HREF="http://www.iana.org/">http://www.iana.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.ieee.org">IEEE</A>
+</TD>
+<TD>
+Institute of Electrical and Electronics Engineers
+</TD>
+<TD>
+<A HREF="http://www.ieee.org">http://www.ieee.org</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.ietf.org/iesg/">IESG</A>
+</TD>
+<TD>
+Internet Engineering Steering Group
+</TD>
+<TD>
+<A HREF="http://www.ietf.org/iesg/">http://www.ietf.org/iesg/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.ietf.org/">IETF</A>
+</TD>
+<TD>
+Internet Engineering Task Force
+</TD>
+<TD>
+<A HREF="http://www.ietf.org/">http://www.ietf.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.irtf.org/">IRTF</A>
+</TD>
+<TD>
+Internet Research Task Force
+</TD>
+<TD>
+<A HREF="http://www.irtf.org/">http://www.irtf.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.iso.org/">ISO</A>
+</TD>
+<TD>
+International Standards Organisation
+</TD>
+<TD>
+<A HREF="http://www.iso.org/">http://www.iso.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.isoc.org/">ISOC</A>
+</TD>
+<TD>
+Internet Society
+</TD>
+<TD>
+<A HREF="http://www.isoc.org/">http://www.isoc.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.itu.int/">ITU</A>
+</TD>
+<TD>
+International Telephone Union
+</TD>
+<TD>
+<A HREF="http://www.itu.int/">http://www.itu.int/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.openldap.org/foundation/">OLF</A>
+</TD>
+<TD>
+OpenLDAP Foundation
+</TD>
+<TD>
+<A HREF="http://www.openldap.org/foundation/">http://www.openldap.org/foundation/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.openldap.org/project/">OLP</A>
+</TD>
+<TD>
+OpenLDAP Project
+</TD>
+<TD>
+<A HREF="http://www.openldap.org/project/">http://www.openldap.org/project/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.openssl.org/">OpenSSL</A>
+</TD>
+<TD>
+OpenSSL Project
+</TD>
+<TD>
+<A HREF="http://www.openssl.org/">http://www.openssl.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/">RFC Editor</A>
+</TD>
+<TD>
+RFC Editor
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/">http://www.rfc-editor.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.oracle.com/">Oracle</A>
+</TD>
+<TD>
+Oracle Corporation
+</TD>
+<TD>
+<A HREF="http://www.oracle.com/">http://www.oracle.com/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.umich.edu/">UM</A>
+</TD>
+<TD>
+University of Michigan
+</TD>
+<TD>
+<A HREF="http://www.umich.edu/">http://www.umich.edu/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.umich.edu/~dirsvcs/ldap/ldap.html">UMLDAP</A>
+</TD>
+<TD>
+University of Michigan LDAP Team
+</TD>
+<TD>
+<A HREF="http://www.umich.edu/~dirsvcs/ldap/ldap.html">http://www.umich.edu/~dirsvcs/ldap/ldap.html</A>
+</TD>
+</TR>
+</TABLE>
+
+<H2><A NAME="Related Products">I.3. Related Products</A></H2>
+<TABLE CLASS="plain">
+<TR CLASS="heading">
+<TD>
+<STRONG>Name</STRONG>
+</TD>
+<TD>
+<STRONG>Jump</STRONG>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://search.cpan.org/src/IANC/sdf-2.001/doc/catalog.html">SDF</A>
+</TD>
+<TD>
+<A HREF="http://search.cpan.org/src/IANC/sdf-2.001/doc/catalog.html">http://search.cpan.org/src/IANC/sdf-2.001/doc/catalog.html</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.oracle.com/database/berkeley-db/db/index.html">Berkeley DB</A>
+</TD>
+<TD>
+<A HREF="http://www.oracle.com/database/berkeley-db/db/index.html">http://www.oracle.com/database/berkeley-db/db/index.html</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.cvshome.org/">CVS</A>
+</TD>
+<TD>
+<A HREF="http://www.cvshome.org/">http://www.cvshome.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://cyrusimap.web.cmu.edu/generalinfo.html">Cyrus</A>
+</TD>
+<TD>
+<A HREF="http://cyrusimap.web.cmu.edu/generalinfo.html">http://cyrusimap.web.cmu.edu/generalinfo.html</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">Cyrus SASL</A>
+</TD>
+<TD>
+<A HREF="http://asg.web.cmu.edu/sasl/sasl-library.html">http://asg.web.cmu.edu/sasl/sasl-library.html</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.gnu.org/software/">GNU</A>
+</TD>
+<TD>
+<A HREF="http://www.gnu.org/software/">http://www.gnu.org/software/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.gnu.org/software/gnutls/">GnuTLS</A>
+</TD>
+<TD>
+<A HREF="http://www.gnu.org/software/gnutls/">http://www.gnu.org/software/gnutls/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.pdc.kth.se/heimdal/">Heimdal</A>
+</TD>
+<TD>
+<A HREF="http://www.pdc.kth.se/heimdal/">http://www.pdc.kth.se/heimdal/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.openldap.org/jldap/">JLDAP</A>
+</TD>
+<TD>
+<A HREF="http://www.openldap.org/jldap/">http://www.openldap.org/jldap/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://web.mit.edu/kerberos/www/">MIT Kerberos</A>
+</TD>
+<TD>
+<A HREF="http://web.mit.edu/kerberos/www/">http://web.mit.edu/kerberos/www/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.openldap.org/">OpenLDAP</A>
+</TD>
+<TD>
+<A HREF="http://www.openldap.org/">http://www.openldap.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.openldap.org/faq/">OpenLDAP FAQ</A>
+</TD>
+<TD>
+<A HREF="http://www.openldap.org/faq/">http://www.openldap.org/faq/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.openldap.org/its/">OpenLDAP ITS</A>
+</TD>
+<TD>
+<A HREF="http://www.openldap.org/its/">http://www.openldap.org/its/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.openldap.org/software/">OpenLDAP Software</A>
+</TD>
+<TD>
+<A HREF="http://www.openldap.org/software/">http://www.openldap.org/software/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.openssl.org/">OpenSSL</A>
+</TD>
+<TD>
+<A HREF="http://www.openssl.org/">http://www.openssl.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.perl.org/">Perl</A>
+</TD>
+<TD>
+<A HREF="http://www.perl.org/">http://www.perl.org/</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.umich.edu/~dirsvcs/ldap/ldap.html">UMLDAP</A>
+</TD>
+<TD>
+<A HREF="http://www.umich.edu/~dirsvcs/ldap/ldap.html">http://www.umich.edu/~dirsvcs/ldap/ldap.html</A>
+</TD>
+</TR>
+</TABLE>
+
+<H2><A NAME="References">I.4. References</A></H2>
+<TABLE CLASS="plain">
+<TR CLASS="heading">
+<TD>
+<STRONG>Reference</STRONG>
+</TD>
+<TD>
+<STRONG>Document</STRONG>
+</TD>
+<TD>
+<STRONG>Status</STRONG>
+</TD>
+<TD>
+<STRONG>Jump</STRONG>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/guide.pdf">UM-GUIDE</A>
+</TD>
+<TD>
+The SLAPD and SLURPD Administrators Guide
+</TD>
+<TD>
+O
+</TD>
+<TD>
+<A HREF="http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/guide.pdf">http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/guide.pdf</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2079.txt">RFC2079</A>
+</TD>
+<TD>
+Definition of an X.500 Attribute Type and an Object Class to Hold Uniform Resource Identifers
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2079.txt">http://www.rfc-editor.org/rfc/rfc2079.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2296.txt">RFC2296</A>
+</TD>
+<TD>
+Use of Language Codes in LDAP
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2296.txt">http://www.rfc-editor.org/rfc/rfc2296.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2307.txt">RFC2307</A>
+</TD>
+<TD>
+An Approach for Using LDAP as a Network Information Service
+</TD>
+<TD>
+X
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2307.txt">http://www.rfc-editor.org/rfc/rfc2307.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2798.txt">RFC2798</A>
+</TD>
+<TD>
+Definition of the inetOrgPerson LDAP Object Class
+</TD>
+<TD>
+I
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2798.txt">http://www.rfc-editor.org/rfc/rfc2798.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2831.txt">RFC2831</A>
+</TD>
+<TD>
+Using Digest Authentication as a SASL Mechanism
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2831.txt">http://www.rfc-editor.org/rfc/rfc2831.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2849.txt">RFC2849</A>
+</TD>
+<TD>
+The LDAP Data Interchange Format
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc2849.txt">http://www.rfc-editor.org/rfc/rfc2849.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc3088.txt">RFC3088</A>
+</TD>
+<TD>
+OpenLDAP Root Service
+</TD>
+<TD>
+X
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc3088.txt">http://www.rfc-editor.org/rfc/rfc3088.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc3296.txt">RFC3296</A>
+</TD>
+<TD>
+Named Subordinate References in LDAP
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc3296.txt">http://www.rfc-editor.org/rfc/rfc3296.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc3384.txt">RFC3384</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (version 3) Replication Requirements
+</TD>
+<TD>
+I
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc3384.txt">http://www.rfc-editor.org/rfc/rfc3384.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc3494.txt">RFC3494</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol version 2 (LDAPv2) to Historic Status
+</TD>
+<TD>
+I
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc3494.txt">http://www.rfc-editor.org/rfc/rfc3494.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4013.txt">RFC4013</A>
+</TD>
+<TD>
+SASLprep: Stringprep Profile for User Names and Passwords
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4013.txt">http://www.rfc-editor.org/rfc/rfc4013.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4346.txt">RFC4346</A>
+</TD>
+<TD>
+The Transport Layer Security (TLS) Protocol, Version 1.1
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4346.txt">http://www.rfc-editor.org/rfc/rfc4346.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4422.txt">RFC4422</A>
+</TD>
+<TD>
+Simple Authentication and Security Layer (SASL)
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4422.txt">http://www.rfc-editor.org/rfc/rfc4422.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4510.txt">RFC4510</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP) Technical Specification Roadmap
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4510.txt">http://www.rfc-editor.org/rfc/rfc4510.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4511</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP): The Protocol
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">http://www.rfc-editor.org/rfc/rfc4512.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">RFC4512</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP): Directory Information Models
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4512.txt">http://www.rfc-editor.org/rfc/rfc4512.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4513.txt">RFC4513</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4513.txt">http://www.rfc-editor.org/rfc/rfc4513.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4514.txt">RFC4514</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4514.txt">http://www.rfc-editor.org/rfc/rfc4514.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4515.txt">RFC4515</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP): String Representation of Search Filters
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4515.txt">http://www.rfc-editor.org/rfc/rfc4515.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4516.txt">RFC4516</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP): Uniform Resource Locator
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4516.txt">http://www.rfc-editor.org/rfc/rfc4516.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4517.txt">RFC4517</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4517.txt">http://www.rfc-editor.org/rfc/rfc4517.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4518.txt">RFC4518</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP): Internationalized String Preparation
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4518.txt">http://www.rfc-editor.org/rfc/rfc4518.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4519.txt">RFC4519</A>
+</TD>
+<TD>
+Lightweight Directory Access Protocol (LDAP): Schema for User Applications
+</TD>
+<TD>
+PS
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4519.txt">http://www.rfc-editor.org/rfc/rfc4519.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4520.txt">RFC4520</A>
+</TD>
+<TD>
+IANA Considerations for LDAP
+</TD>
+<TD>
+BCP
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4520.txt">http://www.rfc-editor.org/rfc/rfc4520.txt</A>
+</TD>
+</TR>
+<TR>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4533.txt">RFC4533</A>
+</TD>
+<TD>
+The Lightweight Directory Access Protocol (LDAP) Content Synchronization Operation
+</TD>
+<TD>
+X
+</TD>
+<TD>
+<A HREF="http://www.rfc-editor.org/rfc/rfc4533.txt">http://www.rfc-editor.org/rfc/rfc4533.txt</A>
+</TD>
+</TR>
+</TABLE>
+
+<P></P>
+<HR>
+<H1><A NAME="Generic configure Instructions">J. Generic configure Instructions</A></H1>
+<PRE>
 Basic Installation
 ==================
 
@@ -4579,8 +8807,8 @@
 </PRE>
 <P></P>
 <HR>
-<H1><A NAME="OpenLDAP Software Copyright Notices">B. OpenLDAP Software Copyright Notices</A></H1>
-<H2><A NAME="OpenLDAP Copyright Notice">B.1. OpenLDAP Copyright Notice</A></H2>
+<H1><A NAME="OpenLDAP Software Copyright Notices">K. OpenLDAP Software Copyright Notices</A></H1>
+<H2><A NAME="OpenLDAP Copyright Notice">K.1. OpenLDAP Copyright Notice</A></H2>
 <P>Copyright 1998-2007 The OpenLDAP Foundation.<BR><EM>All rights reserved.</EM></P>
 <P>Redistribution and use in source and binary forms, with or without modification, are permitted <EM>only as authorized</EM> by the <A HREF="#OpenLDAP Public License">OpenLDAP Public License</A>.</P>
 <P>A copy of this license is available in file <TT>LICENSE</TT> in the top-level directory of the distribution or, alternatively, at &lt;<A HREF="http://www.OpenLDAP.org/license.html">http://www.OpenLDAP.org/license.html</A>&gt;.</P>
@@ -4589,17 +8817,17 @@
 <P>This work is derived from the University of Michigan LDAP v3.3 distribution.  Information concerning this software is available at &lt;<A HREF="http://www.umich.edu/~dirsvcs/ldap/ldap.html">http://www.umich.edu/~dirsvcs/ldap/ldap.html</A>&gt;.</P>
 <P>This work also contains materials derived from public sources.</P>
 <P>Additional information about OpenLDAP software can be obtained at &lt;<A HREF="http://www.OpenLDAP.org/">http://www.OpenLDAP.org/</A>&gt;.</P>
-<H2><A NAME="Additional Copyright Notice">B.2. Additional Copyright Notice</A></H2>
+<H2><A NAME="Additional Copyright Notice">K.2. Additional Copyright Notice</A></H2>
 <P>Portions Copyright 1998-2006 Kurt D. Zeilenga.<BR>Portions Copyright 1998-2006 Net Boolean Incorporated.<BR>Portions Copyright 2001-2006 IBM Corporation.<BR><EM>All rights reserved.</EM></P>
 <P>Redistribution and use in source and binary forms, with or without modification, are permitted only as authorized by the <A HREF="#OpenLDAP Public License">OpenLDAP Public License</A>.</P>
-<P>Portions Copyright 1999-2005 Howard Y.H. Chu.<BR>Portions Copyright 1999-2005 Symas Corporation.<BR>Portions Copyright 1998-2003 Hallvard B. Furuseth.<BR><EM>All rights reserved.</EM></P>
+<P>Portions Copyright 1999-2007 Howard Y.H. Chu.<BR>Portions Copyright 1999-2007 Symas Corporation.<BR>Portions Copyright 1998-2003 Hallvard B. Furuseth.<BR>Portions Copyright 2007 Gavin Henry<BR>Portions Copyright 2007 Suretec Systems<BR><EM>All rights reserved.</EM></P>
 <P>Redistribution and use in source and binary forms, with or without modification, are permitted provided that this notice is preserved. The names of the copyright holders may not be used to endorse or promote products derived from this software without their specific prior written permission.  This software is provided ``as is'' without express or implied warranty.</P>
-<H2><A NAME="University of Michigan Copyright Notice">B.3. University of Michigan Copyright Notice</A></H2>
+<H2><A NAME="University of Michigan Copyright Notice">K.3. University of Michigan Copyright Notice</A></H2>
 <P>Portions Copyright 1992-1996 Regents of the University of Michigan.<BR><EM>All rights reserved.</EM></P>
 <P>Redistribution and use in source and binary forms are permitted provided that this notice is preserved and that due credit is given to the University of Michigan at Ann Arbor. The name of the University may not be used to endorse or promote products derived from this software without specific prior written permission. This software is provided ``as is'' without express or implied warranty.</P>
 <P></P>
 <HR>
-<H1><A NAME="OpenLDAP Public License">C. OpenLDAP Public License</A></H1>
+<H1><A NAME="OpenLDAP Public License">L. OpenLDAP Public License</A></H1>
 <PRE>
 The OpenLDAP Public License
   Version 2.8, 17 August 2003
@@ -4658,7 +8886,7 @@
 <P>
 <FONT COLOR="#808080" FACE="Arial,Verdana,Helvetica" SIZE="1"><B>
 ________________<BR>
-<SMALL>&copy; Copyright 2006, <A HREF="http://www.OpenLDAP.org/foundation/">OpenLDAP Foundation</A>, <A HREF="mailto:info at OpenLDAP.org">info at OpenLDAP.org</A></SMALL></B></FONT>
+<SMALL>&copy; Copyright 2007, <A HREF="http://www.OpenLDAP.org/foundation/">OpenLDAP Foundation</A>, <A HREF="mailto:info at OpenLDAP.org">info at OpenLDAP.org</A></SMALL></B></FONT>
 
 </DIV>
 

Modified: openldap/trunk/doc/guide/admin/guide.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/guide.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/guide.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/admin/guide.sdf,v 1.6.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/guide.sdf,v 1.7.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 #

Modified: openldap/trunk/doc/guide/admin/index.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/index.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/index.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/admin/index.sdf,v 1.6.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/index.sdf,v 1.7.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 #

Modified: openldap/trunk/doc/guide/admin/install.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/install.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/install.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,16 +1,15 @@
-# $OpenLDAP: pkg/openldap-guide/admin/install.sdf,v 1.34.2.5 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/install.sdf,v 1.38.2.5 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
 H1: Building and Installing OpenLDAP Software
 
-This chapter details how to build and install the {{ORG:OpenLDAP}}
-Software package including {{slapd}}(8), the stand-alone LDAP daemon
-and {{slurpd}}(8), the stand-alone update replication daemon.
-Building and installing OpenLDAP Software requires several steps:
-installing prerequisite software, configuring OpenLDAP Software
-itself, making, and finally installing.  The following sections
-describe this process in detail.
+This chapter details how to build and install the {{PRD:OpenLDAP}}
+Software package including {{slapd}}(8), the Standalone {{TERM:LDAP}}
+Daemon.  Building and installing OpenLDAP Software requires several
+steps: installing prerequisite software, configuring OpenLDAP
+Software itself, making, and finally installing.  The following
+sections describe this process in detail.
 
 
 H2: Obtaining and Extracting the Software
@@ -22,7 +21,7 @@
 
 The project makes available two series of packages for {{general
 use}}.  The project makes {{releases}} as new features and bug fixes
-come available.  Though the project takes steps to improve stablity
+come available.  Though the project takes steps to improve stability
 of these releases, it is common for problems to arise only after
 {{release}}.  The {{stable}} release is the latest {{release}} which
 has demonstrated stability through general use.
@@ -64,39 +63,24 @@
 
 H3: {{TERM[expand]TLS}}
 
-OpenLDAP clients and servers require installation of {{PRD:OpenSSL}}
+OpenLDAP clients and servers require installation of either {{PRD:OpenSSL}}
+or {{PRD:GnuTLS}}
 {{TERM:TLS}} libraries to provide {{TERM[expand]TLS}} services.  Though
 some operating systems may provide these libraries as part of the
-base system or as an optional software component, OpenSSL often
-requires separate installation.
+base system or as an optional software component, OpenSSL and GnuTLS often
+require separate installation.
 
 OpenSSL is available from {{URL: http://www.openssl.org/}}.
+GnuTLS is available from {{URL: http://www.gnu.org/software/gnutls/}}.
 
 OpenLDAP Software will not be fully LDAPv3 compliant unless OpenLDAP's
-{{EX:configure}} detects a usable OpenSSL installation.
+{{EX:configure}} detects a usable TLS library.
 
 
-H3: Kerberos Authentication Services
-
-OpenLDAP clients and servers support Kerberos-based authentication
-services.
-In particular, OpenLDAP supports the {{TERM:SASL}}/{{TERM:GSSAPI}}
-authentication mechanism using either {{PRD:Heimdal}} or
-{{PRD:MIT Kerberos}} V packages.
-If you desire to use Kerberos-based SASL/GSSAPI authentication,
-you should install either Heimdal or MIT Kerberos V.
-
-Heimdal Kerberos is available from {{URL:http://www.pdc.kth.se/heimdal/}}.
-MIT Kerberos is available from {{URL:http://web.mit.edu/kerberos/www/}}.
-
-Use of strong authentication services, such as those provided by
-Kerberos, is highly recommended.
-
-
 H3: {{TERM[expand]SASL}}
 
-OpenLDAP clients and servers require installation of {{PRD:Cyrus}}'s
-{{PRD:SASL}} libraries to provide {{TERM[expand]SASL}} services.  Though
+OpenLDAP clients and servers require installation of {{PRD:Cyrus SASL}} 
+libraries to provide {{TERM[expand]SASL}} services.  Though
 some operating systems may provide this library as part of the
 base system or as an optional software component, Cyrus SASL
 often requires separate installation.
@@ -110,10 +94,27 @@
 configure detects a usable Cyrus SASL installation.
 
 
+H3: {{TERM[expand]Kerberos}}
+
+OpenLDAP clients and servers support {{TERM:Kerberos}} authentication
+services.  In particular, OpenLDAP supports the Kerberos V
+{{TERM:GSS-API}} {{TERM:SASL}} authentication mechanism known as
+the {{TERM:GSSAPI}} mechanism.  This feature requires, in addition to
+Cyrus SASL libraries, either {{PRD:Heimdal}} or {{PRD:MIT Kerberos}}
+V libraries.
+
+Heimdal Kerberos is available from {{URL:http://www.pdc.kth.se/heimdal/}}.
+MIT Kerberos is available from {{URL:http://web.mit.edu/kerberos/www/}}.
+
+Use of strong authentication services, such as those provided by
+Kerberos, is highly recommended.
+
+
+
 H3: Database Software
 
 OpenLDAP's {{slapd}}(8) {{TERM:BDB}} and {{TERM:HDB}} primary database backends
-require {{ORG[expand]Sleepycat}} {{PRD:Berkeley DB}}.
+require {{ORG[expand]Oracle}} {{PRD:Berkeley DB}}.
 If not available at configure time, you will not be able build
 {{slapd}}(8) with these primary database backends.
 
@@ -122,16 +123,16 @@
 software component.  If not, you'll have to obtain and
 install it yourself.
 
-{{PRD:Berkeley DB}} is available from {{ORG[expand]Sleepycat}}'s
-download page {{URL: http://www.sleepycat.com/download/}}.  There
-are several versions available.  Generally, the most recent release
-(with published patches) is recommended.  This package is required
+{{PRD:Berkeley DB}} is available from {{ORG[expand]Oracle}}'s Berkeley DB
+download page
+{{URL: http://www.oracle.com/technology/software/products/berkeley-db/index.html}}.  
+
+There are several versions available. Generally, the most recent
+release (with published patches) is recommended. This package is required
 if you wish to use the {{TERM:BDB}} or {{TERM:HDB}} database backends.
 
-OpenLDAP's {{slapd}}(8) LDBM backend supports a variety of data
-base managers including {{PRD:Berkeley DB}} and {{PRD:GDBM}}.
-{{PRD:GDBM}} is available from {{ORG:FSF}}'s download site {{URL:
-ftp://ftp.gnu.org/pub/gnu/gdbm/}}.
+Note: Please see {{SECT:Recommended OpenLDAP Software Dependency Versions}} for
+more information.
 
 
 H3: Threads
@@ -224,8 +225,8 @@
 >	make
 
 You should examine the output of this command carefully to make sure
-everything is built correctly. Note that this command builds the LDAP
-libraries and associated clients as well as {{slapd}}(8) and {{slurpd}}(8).
+everything is built correctly.  Note that this command builds the LDAP
+libraries and associated clients as well as {{slapd}}(8).
 
 
 H2: Testing the Software

Modified: openldap/trunk/doc/guide/admin/intro.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/intro.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/intro.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,34 +1,41 @@
-# $OpenLDAP: pkg/openldap-guide/admin/intro.sdf,v 1.40.2.4 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/intro.sdf,v 1.45.2.5 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 H1: Introduction to OpenLDAP Directory Services
 
-This document describes how to build, configure, and operate OpenLDAP
-software to provide directory services.  This includes details on
-how to configure and run the stand-alone {{TERM:LDAP}} daemon,
-{{slapd}}(8) and the stand-alone LDAP update replication daemon,
-{{slurpd}}(8). It is intended for newcomers and experienced
-administrators alike.  This section provides a basic introduction
-to directory services and, in particular, the directory services
-provided by {{slapd}}(8).
+This document describes how to build, configure, and operate
+{{PRD:OpenLDAP}} Software to provide directory services.  This
+includes details on how to configure and run the Standalone
+{{TERM:LDAP}} Daemon, {{slapd}}(8).  It is intended for new and
+experienced administrators alike.  This section provides a basic
+introduction to directory services and, in particular, the directory
+services provided by {{slapd}}(8).  This introduction is only
+intended to provide enough information so one might get started
+learning about {{TERM:LDAP}}, {{TERM:X.500}}, and directory services.
 
 
 H2: What is a directory service?
 
-A directory is a specialized database optimized for reading, browsing
-and searching.  Directories tend to contain descriptive, attribute-based
-information and support sophisticated filtering capabilities.
-Directories generally do not support complicated transaction or
-roll-back schemes found in database management systems designed
-for handling high-volume complex updates.  Directory updates are
-typically simple all-or-nothing changes, if they are allowed at
-all.  Directories are tuned to give quick response to high-volume
-lookup or search operations. They may have the ability to replicate
-information widely in order to increase availability and reliability,
-while reducing response time.  When directory information is
-replicated, temporary inconsistencies between the replicas may be
-okay, as long as they get in sync eventually.
+A directory is a specialized database specifically designed for
+searching and browsing, in additional to supporting basic lookup
+and update functions.
 
+Note: A directory is defined by some as merely a database optimized
+for read access.  This definition, at best, is overly simplistic.
+
+Directories tend to contain descriptive, attribute-based information
+and support sophisticated filtering capabilities.  Directories
+generally do not support complicated transaction or roll-back schemes
+found in database management systems designed for handling high-volume
+complex updates.  Directory updates are typically simple all-or-nothing
+changes, if they are allowed at all.  Directories are generally
+tuned to give quick response to high-volume lookup or search
+operations. They may have the ability to replicate information
+widely in order to increase availability and reliability, while
+reducing response time.  When directory information is replicated,
+temporary inconsistencies between the replicas may be okay, as long
+as inconsistencies are resolved in a timely manner.
+
 There are many different ways to provide a directory service.
 Different methods allow different kinds of information to be stored
 in the directory, place different requirements on how that information
@@ -41,23 +48,31 @@
 contain is spread across many machines, all of which cooperate to
 provide the directory service. Typically a global service defines
 a uniform {{namespace}} which gives the same view of the data no
-matter where you are in relation to the data itself.  The Internet
-{{TERM[expand]DNS}} (DNS) is an example of a globally distributed
-directory service.
+matter where you are in relation to the data itself.
 
+A web directory, such as provided by the {{Open Directory Project}}
+<{{URL:http://dmoz.org}}>, is a good example of a directory service.
+These services catalog web pages and are specifically designed to
+support browsing and searching.
 
+While some consider the Internet {{TERM[expand]DNS}} (DNS) is an
+example of a globally distributed directory service, DNS is not
+browseable nor searchable.  It is more properly described as a
+globally distributed {{lookup}} service.
+
+
 H2: What is LDAP?
 
 {{TERM:LDAP}} stands for {{TERM[expand]LDAP}}.  As the name suggests,
 it is a lightweight protocol for accessing directory services,
 specifically {{TERM:X.500}}-based directory services.  LDAP runs
 over {{TERM:TCP}}/{{TERM:IP}} or other connection oriented transfer
-services.  The nitty-gritty details of LDAP are defined in
-{{REF:RFC2251}} "The Lightweight Directory Access Protocol (v3)"
-and other documents comprising the technical specification
-{{REF:RFC3377}}.  This section gives an overview of LDAP from a
-user's perspective.
+services.  LDAP is an {{ORG:IETF}} Standard Track protocol and is
+specified in "Lightweight Directory Access Protocol (LDAP) Technical
+Specification Road Map" {{REF:RFC4510}}.
 
+This section gives an overview of LDAP from a user's perspective.
+
 {{What kind of information can be stored in the directory?}} The
 LDAP information model is based on {{entries}}. An entry is a
 collection of attributes that has a globally-unique {{TERM[expand]DN}}
@@ -68,8 +83,8 @@
 values depend on the attribute type.  For example, a {{EX:cn}}
 attribute might contain the value {{EX:Babs Jensen}}.  A {{EX:mail}}
 attribute might contain the value "{{EX:babs at example.com}}". A
-{{EX:jpegPhoto}} attribute would contain a photograph in the JPEG
-(binary) format.
+{{EX:jpegPhoto}} attribute would contain a photograph in the
+{{TERM:JPEG}} (binary) format.
 
 {{How is the information arranged?}} In LDAP, directory entries
 are arranged in a hierarchical tree-like structure.  Traditionally,
@@ -81,7 +96,7 @@
 you can think of.  Figure 1.1 shows an example LDAP directory tree
 using traditional naming.
 
-!import "intro_tree.gif"; align="center"; \
+!import "intro_tree.png"; align="center"; \
 	title="LDAP directory tree (traditional naming)"
 FT[align="Center"] Figure 1.1: LDAP directory tree (traditional naming)
 
@@ -91,7 +106,7 @@
 Figure 1.2 shows an example LDAP directory tree using domain-based
 naming.
 
-!import "intro_dctree.gif"; align="center"; \
+!import "intro_dctree.png"; align="center"; \
 	title="LDAP directory tree (Internet naming)"
 FT[align="Center"] Figure 1.2: LDAP directory tree (Internet naming)
 
@@ -106,9 +121,9 @@
 concatenating the names of its ancestor entries. For example, the
 entry for Barbara Jensen in the Internet naming example above has
 an RDN of {{EX:uid=babs}} and a DN of
-{{EX:uid=babs,ou=People,dc=example,dc=com}}. The full DN format
-is described in {{REF:RFC2253}}, "Lightweight Directory Access
-Protocol (v3):  UTF-8 String Representation of Distinguished Names."
+{{EX:uid=babs,ou=People,dc=example,dc=com}}. The full DN format is
+described in {{REF:RFC4514}}, "LDAP: String Representation of
+Distinguished Names."
 
 {{How is the information accessed?}} LDAP defines operations for
 interrogating and updating the directory.  Operations are provided
@@ -139,18 +154,58 @@
 services.
 
 
+H2: When should I use LDAP?
+
+This is a very good question. In general, you should use a Directory
+server when you require data to be centrally managed, stored and accessible via
+standards based methods. 
+
+Some common examples found throughout the industry are, but not limited to:
+
+* Machine Authentication
+* User Authentication
+* User/System Groups
+* Address book
+* Organization Representation
+* Asset Tracking
+* Telephony Information Store
+* User resource management
+* E-mail address lookups
+* Application Configuration store
+* PBX Configuration store
+* etc.....
+
+There are various {{SECT:Distributed Schema Files}} that are standards based, but
+you can always create your own {{SECT:Schema Specification}}.
+
+There are always new ways to use a Directory and apply LDAP principles to address
+certain problems, therefore there is no simple answer to this question.
+
+If in doubt, join the general LDAP forum for non-commercial discussions and 
+information relating to LDAP at: 
+{{URL:http://www.umich.edu/~dirsvcs/ldap/mailinglist.html}} and ask
+
+H2: When should I not use LDAP?
+
+When you start finding yourself bending the directory to do what you require,
+maybe a redesign is needed. Or if you only require one application to use and 
+manipulate your data (for discussion of LDAP vs RDBMS, please read the 
+{{SECT:LDAP vs RDBMS}} section).
+
+It will become obvious when LDAP is the right tool for the job.
+
+
 H2: How does LDAP work?
 
-LDAP directory service is based on a {{client-server}} model. One
-or more LDAP servers contain the data making up the directory
-information tree (DIT).  The client connects to servers and
-asks it a question.  The server responds with an answer and/or 
-with a pointer to where the client can get additional information
-(typically, another LDAP server).  No matter which LDAP server a
-client connects to, it sees the same view of the directory; a name
-presented to one LDAP server references the same entry it would at
-another LDAP server. This is an important feature of a global
-directory service, like LDAP.
+LDAP utilizes a {{client-server model}}. One or more LDAP servers
+contain the data making up the directory information tree ({{TERM:DIT}}).
+The client connects to servers and asks it a question.  The server
+responds with an answer and/or with a pointer to where the client
+can get additional information (typically, another LDAP server).
+No matter which LDAP server a client connects to, it sees the same
+view of the directory; a name presented to one LDAP server references
+the same entry it would at another LDAP server.  This is an important
+feature of a global directory service.
 
 
 H2: What about X.500?
@@ -170,7 +225,7 @@
 gateways, LDAP is now more commonly directly implemented in X.500
 servers. 
 
-The stand-alone LDAP daemon, or {{slapd}}(8), can be viewed as a
+The Standalone LDAP Daemon, or {{slapd}}(8), can be viewed as a
 {{lightweight}} X.500 directory server.  That is, it does not
 implement the X.500's DAP nor does it support the complete X.500
 models.
@@ -183,10 +238,7 @@
 
 It is possible to replicate data from an LDAP directory server to
 a X.500 DAP {{TERM:DSA}}.  This requires an LDAP/DAP gateway.
-OpenLDAP does not provide such a gateway, but our replication daemon
-can be used to replicate to such a gateway.  See the {{SECT:Replication
-with slurpd}} chapter of this document for information regarding
-replication.
+OpenLDAP Software does not include such a gateway.
 
 
 H2: What is the difference between LDAPv2 and LDAPv3?
@@ -194,22 +246,122 @@
 LDAPv3 was developed in the late 1990's to replace LDAPv2.
 LDAPv3 adds the following features to LDAP:
 
- - Strong authentication and data security services via {{TERM:SASL}}
- - Certificate authentication and data security services via {{TERM:TLS}} (SSL)
- - Internationalization through the use of Unicode
- - Referrals and Continuations
- - Schema Discovery
- - Extensibility (controls, extended operations, and more)
+ * Strong authentication and data security services via {{TERM:SASL}}
+ * Certificate authentication and data security services via {{TERM:TLS}} (SSL)
+ * Internationalization through the use of Unicode
+ * Referrals and Continuations
+ * Schema Discovery
+ * Extensibility (controls, extended operations, and more)
 
 LDAPv2 is historic ({{REF:RFC3494}}).  As most {{so-called}} LDAPv2
 implementations (including {{slapd}}(8)) do not conform to the
-LDAPv2 technical specification, interoperatibility amongst
+LDAPv2 technical specification, interoperability amongst
 implementations claiming LDAPv2 support is limited.  As LDAPv2
 differs significantly from LDAPv3, deploying both LDAPv2 and LDAPv3
 simultaneously is quite problematic.  LDAPv2 should be avoided.
 LDAPv2 is disabled by default.
 
 
+H2: LDAP vs RDBMS
+
+This question is raised many times, in different forms. The most common, 
+however, is: {{Why doesn't OpenLDAP drop Berkeley DB and use a relational 
+database management system (RDBMS) instead?}} In general, expecting that the 
+sophisticated algorithms implemented by commercial-grade RDBMS would make 
+{{OpenLDAP}} be faster or somehow better and, at the same time, permitting 
+sharing of data with other applications.
+
+The short answer is that use of an embedded database and custom indexing system 
+allows OpenLDAP to provide greater performance and scalability without loss of 
+reliability. OpenLDAP uses Berkeley DB concurrent / transactional 
+database software. This is the same software used by leading commercial 
+directory software.
+
+Now for the long answer. We are all confronted all the time with the choice 
+RDBMSes vs. directories. It is a hard choice and no simple answer exists.
+
+It is tempting to think that having a RDBMS backend to the directory solves all 
+problems. However, it is a pig. This is because the data models are very 
+different. Representing directory data with a relational database is going to 
+require splitting data into multiple tables.
+
+Think for a moment about the person objectclass. Its definition requires 
+attribute types objectclass, sn and cn and allows attribute types userPassword, 
+telephoneNumber, seeAlso and description. All of these attributes are multivalued, 
+so a normalization requires putting each attribute type in a separate table.
+
+Now you have to decide on appropriate keys for those tables. The primary key 
+might be a combination of the DN, but this becomes rather inefficient on most 
+database implementations.
+
+The big problem now is that accessing data from one entry requires seeking on 
+different disk areas. On some applications this may be OK but in many 
+applications performance suffers.
+
+The only attribute types that can be put in the main table entry are those that 
+are mandatory and single-value. You may add also the optional single-valued 
+attributes and set them to NULL or something if not present.
+
+But wait, the entry can have multiple objectclasses and they are organized in 
+an inheritance hierarchy. An entry of objectclass organizationalPerson now has 
+the attributes from person plus a few others and some formerly optional attribute 
+types are now mandatory.
+
+What to do? Should we have different tables for the different objectclasses? 
+This way the person would have an entry on the person table, another on 
+organizationalPerson, etc. Or should we get rid of person and put everything on 
+the second table?
+
+But what do we do with a filter like (cn=*) where cn is an attribute type that 
+appears in many, many objectclasses. Should we search all possible tables for 
+matching entries? Not very attractive.
+
+Once this point is reached, three approaches come to mind. One is to do full 
+normalization so that each attribute type, no matter what, has its own separate 
+table. The simplistic approach where the DN is part of the primary key is 
+extremely wasteful, and calls for an approach where the entry has a unique 
+numeric id that is used instead for the keys and a main table that maps DNs to 
+ids. The approach, anyway, is very inefficient when several attribute types from 
+one or more entries are requested. Such a database, though cumbersomely, 
+can be managed from SQL applications.
+
+The second approach is to put the whole entry as a blob in a table shared by all 
+entries regardless of the objectclass and have additional tables that act as 
+indices for the first table. Index tables are not database indices, but are 
+fully managed by the LDAP server-side implementation. However, the database 
+becomes unusable from SQL. And, thus, a fully fledged database system provides 
+little or no advantage. The full generality of the database is unneeded. 
+Much better to use something light and fast, like Berkeley DB. 
+
+A completely different way to see this is to give up any hopes of implementing 
+the directory data model. In this case, LDAP is used as an access protocol to 
+data that provides only superficially the directory data model. For instance, 
+it may be read only or, where updates are allowed, restrictions are applied, 
+such as making single-value attribute types that would allow for multiple values. 
+Or the impossibility to add new objectclasses to an existing entry or remove 
+one of those present. The restrictions span the range from allowed restrictions 
+(that might be elsewhere the result of access control) to outright violations of 
+the data model. It can be, however, a method to provide LDAP access to preexisting 
+data that is used by other applications. But in the understanding that we don't
+really have a "directory".
+
+Existing commercial LDAP server implementations that use a relational database 
+are either from the first kind or the third. I don't know of any implementation 
+that uses a relational database to do inefficiently what BDB does efficiently.
+For those who are interested in "third way" (exposing EXISTING data from RDBMS 
+as LDAP tree, having some limitations compared to classic LDAP model, but making 
+it possible to interoperate between LDAP and SQL applications):
+
+OpenLDAP includes back-sql - the backend that makes it possible. It uses ODBC + 
+additional metainformation about translating LDAP queries to SQL queries in your 
+RDBMS schema, providing different levels of access - from read-only to full 
+access depending on RDBMS you use, and your schema.
+
+For more information on concept and limitations, see {{slapd-sql}}(5) man page, 
+or the {{SECT: Backends}} section. There are also several examples for several 
+RDBMSes in {{F:back-sql/rdbms_depend/*}} subdirectories. 
+
+
 H2: What is slapd and what can it do?
 
 {{slapd}}(8) is an LDAP directory server that runs on many different
@@ -220,18 +372,19 @@
 interesting features and capabilities include:
 
 {{B:LDAPv3}}: {{slapd}} implements version 3 of {{TERM[expand]LDAP}}.
-{{slapd}} supports LDAP over both IPv4 and IPv6 and Unix IPC.
+{{slapd}} supports LDAP over both {{TERM:IPv4}} and {{TERM:IPv6}}
+and Unix {{TERM:IPC}}.
 
 {{B:{{TERM[expand]SASL}}}}: {{slapd}} supports strong authentication
 and data security (integrity and confidentiality) services through
-the use of SASL.  {{slapd}}'s SASL implementation utilizes {{PRD:Cyrus}}
-{{PRD:SASL}} software which supports a number of mechanisms including
-DIGEST-MD5, EXTERNAL, and GSSAPI.
+the use of SASL.  {{slapd}}'s SASL implementation utilizes {{PRD:Cyrus
+SASL}} software which supports a number of mechanisms including
+{{TERM:DIGEST-MD5}}, {{TERM:EXTERNAL}}, and {{TERM:GSSAPI}}.
 
 {{B:{{TERM[expand]TLS}}}}: {{slapd}} supports certificate-based
 authentication and data security (integrity and confidentiality)
 services through the use of TLS (or SSL).  {{slapd}}'s TLS
-implementation utilizes {{PRD:OpenSSL}} software.
+implementation can utilize either {{PRD:OpenSSL}} or {{PRD:GnuTLS}} software.
 
 {{B:Topology control}}: {{slapd}} can be configured to restrict
 access at the socket layer based upon network topology information.
@@ -250,12 +403,11 @@
 {{B:Choice of database backends}}: {{slapd}} comes with a variety
 of different database backends you can choose from. They include
 {{TERM:BDB}}, a high-performance transactional database backend;
-{{TERM:HDB}}, a hierarchical high-performance transactional backend;
-{{TERM:LDBM}}, a lightweight DBM based backend; {{SHELL}}, a backend
-interface to arbitrary shell scripts; and PASSWD, a simple backend
-interface to the {{passwd}}(5) file.  The BDB and HDB backends
-utilize {{ORG:Sleepycat}} {{PRD:Berkeley DB}}.  The LDBM utilizes
-either {{PRD:Berkeley DB}} or {{PRD:GDBM}}.
+{{TERM:HDB}}, a hierarchical high-performance transactional
+backend; {{SHELL}}, a backend interface to arbitrary shell scripts;
+and PASSWD, a simple backend interface to the {{passwd}}(5) file.
+The BDB and HDB backends utilize {{ORG:Oracle}} {{PRD:Berkeley
+DB}}.
 
 {{B:Multiple database instances}}: {{slapd}} can be configured to
 serve multiple databases at the same time. This means that a single
@@ -272,8 +424,7 @@
 customized modules which extend {{slapd}} in numerous ways.  Also,
 a number of {{programmable database}} modules are provided.  These
 allow you to expose external data sources to {{slapd}} using popular
-programming languages ({{PRD:Perl}}, {{shell}}, {{PRD:SQL}}, and
-{{PRD:TCL}}).
+programming languages ({{PRD:Perl}}, {{shell}}, and {{TERM:SQL}}.
 
 {{B:Threads}}: {{slapd}} is threaded for high performance.  A single
 multi-threaded {{slapd}} process handles all incoming requests using
@@ -283,9 +434,11 @@
 {{B:Replication}}: {{slapd}} can be configured to maintain shadow
 copies of directory information.  This {{single-master/multiple-slave}}
 replication scheme is vital in high-volume environments where a
-single {{slapd}} just doesn't provide the necessary availability
-or reliability. {{slapd}} supports two replication methods: {{LDAP
-Sync}}-based and {{slurpd}}(8)-based replication.
+single {{slapd}} installation just doesn't provide the necessary availability
+or reliability.  For extremely demanding environments where a
+single point of failure is not acceptable, {{multi-master}} replication
+is also available.  {{slapd}} includes support for {{LDAP Sync}}-based
+replication.
 
 {{B:Proxy Cache}}: {{slapd}} can be configured as a caching
 LDAP proxy service.
@@ -293,24 +446,7 @@
 {{B:Configuration}}: {{slapd}} is highly configurable through a
 single configuration file which allows you to change just about
 everything you'd ever want to change.  Configuration options have
-reasonable defaults, making your job much easier.
+reasonable defaults, making your job much easier. Configuration can
+also be performed dynamically using LDAP itself, which greatly
+improves manageability.
 
-
-H2: What is slurpd and what can it do?
-
-{{slurpd}}(8) is a daemon that, with {{slapd}} help, provides
-replicated service.  It is responsible for distributing changes
-made to the master {{slapd}} database out to the various {{slapd}}
-replicas.  It frees {{slapd}} from having to worry that some replicas
-might be down or unreachable when a change comes through; {{slurpd}}
-handles retrying failed requests automatically.  {{slapd}} and
-{{slurpd}} communicate through a simple text file that is used to
-log changes.
-
-See the {{SECT:Replication with slurpd}} chapter for information
-about how to configure and run {{slurpd}}(8).
-
-Alternatively, {{LDAP-Sync}}-based replication may be used to provide
-a replicated service.  See the {{SECT:LDAP Sync Replication}} chapter
-for details.
-

Deleted: openldap/trunk/doc/guide/admin/intro_dctree.gif
===================================================================
(Binary files differ)

Copied: openldap/trunk/doc/guide/admin/intro_dctree.png (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/intro_dctree.png)
===================================================================
(Binary files differ)

Deleted: openldap/trunk/doc/guide/admin/intro_tree.gif
===================================================================
(Binary files differ)

Copied: openldap/trunk/doc/guide/admin/intro_tree.png (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/intro_tree.png)
===================================================================
(Binary files differ)

Copied: openldap/trunk/doc/guide/admin/maintenance.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/maintenance.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/maintenance.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/maintenance.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,142 @@
+# $OpenLDAP: pkg/openldap-guide/admin/maintenance.sdf,v 1.7.2.3 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Maintenance
+
+System Administration is all about maintenance, so it is only fair that we 
+discuss how to correctly maintain an OpenLDAP deployment.
+
+
+H2: Directory Backups
+
+Backup strategies largely depend on the amount of change in the database
+and how much of that change an administrator might be willing to lose in a 
+catastrophic failure. There are two basic methods that can be used:
+
+1. Backup the Berkeley database itself and periodically back up the transaction 
+log files:
+
+Berkeley DB produces transaction logs that can be used to reconstruct
+changes from a given point in time. For example, if an administrator were willing to only
+lose one hour's worth of changes, they could take down the server in
+the middle of the night, copy the Berkeley database files offsite, and bring
+the server back online. Then, on an hourly basis, they could force a
+database checkpoint, capture the log files that have been generated in the
+past hour, and copy them offsite. The accumulated log files, in combination
+with the previous database backup, could be used with db_recover to
+reconstruct the database up to the time the last collection of log files was
+copied offsite. This method affords good protection, with minimal space
+overhead.
+
+
+2. Periodically run slapcat and back up the LDIF file:
+
+Slapcat can be run while slapd is active. However, one runs the risk of an
+inconsistent database- not from the point of slapd, but from the point of
+the applications using LDAP. For example, if a provisioning application
+performed tasks that consisted of several LDAP operations, and the slapcat
+took place concurrently with those operations, then there might be
+inconsistencies in the LDAP database from the point of view of that
+provisioning application and applications that depended on it. One must,
+therefore, be convinced something like that won't happen. One way to do that
+would be to put the database in read-only mode while performing the
+slapcat. The other disadvantage of this approach is that the generated LDIF
+files can be rather large and the accumulation of the day's backups could
+add up to a substantial amount of space.
+
+You can use {{slapcat}}(8) to generate an LDIF file for each of your {{slapd}}(8) 
+back-bdb or back-hdb databases.
+
+>    slapcat -f slapd.conf -b "dc=example,dc=com"
+
+For back-bdb and back-hdb, this command may be ran while slapd(8) is running.
+
+MORE on actual Berkeley DB backups later covering db_recover etc.
+
+H2: Berkeley DB Logs
+
+Berkeley DB log files grow, and the administrator has to deal with it. The 
+procedure is known as log file archival or log file rotation. 
+
+Note: The actual log file rotation is handled by the Berkeley DB engine.
+
+Logs of current transactions need to be stored into files so that the database 
+can be recovered in the event of an application crash. Administrators can change 
+the size limit of a single log file (by default 10MB), and have old log files 
+removed automatically, by setting up DB environment (see below). The reason 
+Berkeley DB never deletes any log files by default is that the administrator 
+may wish to backup the log files before removal to make database recovery 
+possible even after a catastrophic failure, such as file system corruption.
+
+Log file names are {{F:log.XXXXXXXXXX}} (X is a digit). By default the log files 
+are located in the BDB backend directory. The {{F:db_archive}} tool knows what 
+log files are used in current transactions, and what are not. Administrators can 
+move unused log files to a backup media, and delete them. To have them removed 
+automatically, place set_flags {{DB_LOG_AUTOREMOVE}} directive in {{F:DB_CONFIG}}. 
+
+Note: If the log files are removed automatically, recovery after a catastrophic 
+failure is likely to be impossible.
+
+The files with names {{F:__db.001}}, {{F:__db.002}}, etc are just shared memory 
+regions (or whatever). These ARE NOT 'logs', they must be left alone. Don't be 
+afraid of them, they do not grow like logs do.
+
+To understand the {{F:db_archive}} interface, the reader should refer to 
+chapter 9 of the Berkeley DB guide. In particular, the following chapters are 
+recommended:
+
+* Database and log file archival
+* Log file removal
+* Recovery procedures
+* Hot failover
+
+Advanced installations can use special environment settings to fine-tune some 
+Berkeley DB options (change the log file limit, etc). This can be done by using 
+the {{F:DB_CONFIG}} file. This magic file can be created in BDB backend directory 
+set up by {{slapd.conf}}(5). More information on this file can be found in File 
+naming chapter. Specific directives can be found in C Interface, look for 
+{{DB_ENV->set_XXXX}} calls.
+
+Note: options set in {{F:DB_CONFIG}} file override options set by OpenLDAP. 
+Use them with extreme caution. Do not use them unless You know what You are doing.
+
+The advantages of {{F:DB_CONFIG}} usage can be the following:
+
+* to keep data files and log files on different mediums (i.e. disks) to improve 
+  performance and/or reliability;
+* to fine-tune some specific options (such as shared memory region sizes);
+* to set the log file limit (please read Log file limits before doing this).
+
+To figure out the best-practice BDB backup scenario, the reader is highly 
+recommended to read the whole Chapter 9: Berkeley DB Transactional Data Store Applications. 
+This chapter is a set of small pages with examples in C language. Non-programming 
+people can skip this examples without loss of knowledge.
+
+
+H2: Checkpointing
+
+MORE/TIDY
+
+If you put "checkpoint 1024 5" in slapd.conf (to checkpoint after 1024kb or 5 minutes, 
+for example), this does not checkpoint every 5 minutes as you may think. 
+The explanation from Howard is:
+
+'In OpenLDAP 2.1 and 2.2 the checkpoint directive acts as follows - *when there 
+is a write operation*, and more than <check> minutes have occurred since the 
+last checkpoint, perform the checkpoint. If more than <check> minutes pass after 
+a write without any other write operations occurring, no checkpoint is performed, 
+so it's possible to lose the last write that occurred.''
+
+In other words, a write operation occurring less than "check" minutes after the 
+last checkpoint will not be checkpointed until the next write occurs after "check" 
+minutes have passed since the checkpoint.
+
+This has been modified in 2.3 to indeed checkpoint every so often; in the meantime 
+a workaround is to invoke "db_checkpoint" from a cron script every so often, say 5 minutes. 
+
+H2: Migration
+
+Exporting to a new system......
+
+

Modified: openldap/trunk/doc/guide/admin/master.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/master.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/master.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/admin/master.sdf,v 1.16.2.3 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/master.sdf,v 1.18.2.5 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 #
@@ -48,6 +48,12 @@
 !include "dbtools.sdf"; chapter
 PB:
 
+!include "backends.sdf"; chapter
+PB:
+
+!include "overlays.sdf"; chapter
+PB:
+
 !include "schema.sdf"; chapter
 PB:
 
@@ -60,25 +66,62 @@
 !include "tls.sdf"; chapter
 PB:
 
-#!include "monitoringslapd.sdf"; chapter
-#PB:
-
-#!include "tuning.sdf"; chapter
-#PB:
-
 !include "referrals.sdf"; chapter
 PB:
 
 !include "replication.sdf"; chapter
 PB:
 
-!include "syncrepl.sdf"; chapter
+!include "maintenance.sdf"; chapter
 PB:
 
-!include "proxycache.sdf"; chapter
+!include "monitoringslapd.sdf"; chapter
 PB:
 
+!include "tuning.sdf"; chapter
+PB:
+
+!include "troubleshooting.sdf"; chapter
+PB:
+
 # Appendices 
+!include "appendix-changes.sdf"; appendix
+PB:
+
+# Upgrade from 2.3.x
+!include "appendix-upgrading.sdf"; appendix
+PB:
+
+# Common Errors
+!include "appendix-common-errors.sdf"; appendix
+PB:
+
+# What versions we recommend 
+!include "appendix-recommended-versions.sdf"; appendix
+PB:
+
+# Real Deployments
+!include "appendix-deployments.sdf"; appendix
+PB:
+
+# Contributions
+!include "appendix-contrib.sdf"; appendix
+PB:
+
+# Config file examples
+!include "appendix-configs.sdf"; appendix
+PB:
+
+# LDAP Result Codes
+!include "appendix-ldap-result-codes.sdf"; appendix
+PB:
+
+
+# Terms
+!include "glossary.sdf"; appendix
+PB:
+
+# Autoconf 
 !include "../release/autoconf.sdf"; appendix
 PB:
 

Modified: openldap/trunk/doc/guide/admin/monitoringslapd.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/monitoringslapd.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/monitoringslapd.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,111 +1,505 @@
-# $OpenLDAP: pkg/openldap-guide/admin/monitoringslapd.sdf,v 1.8.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/monitoringslapd.sdf,v 1.9.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
-H1: Monitoring Slapd
+H1: Monitoring
 
-Slapd supports a monitoring interface you can use to find out
-many useful bits of information about what slapd is currently
-doing, how many connections it has, how many threads are
-working, etc. You can access the monitor feature by doing a
-base object search of the SLAPD_MONITOR_DN from
-include/ldapconfig.h with any kind of valid filter (e.g.,
-"(objectclass=*)"). By default, this DN is set to "cn=monitor".
-You will get one entry returned to you, with the following
+{{slapd}}(8) supports an optional {{TERM:LDAP}} monitoring interface
+you can use to obtain information regarding the current state of
+your {{slapd}} instance.  For instance, the interface allows you
+to determine how many clients are connected to the server currently.
+The monitoring information is provided by a specialized backend,
+the {{monitor}} backend.  A manual page, {{slapd-monitor}}(5) is
+available.
+
+When the monitoring interface is enabled, LDAP clients may be used
+to access information provided by the {{monitor}} backend, subject
+to access and other controls.
+
+When enabled, the {{monitor}} backend dynamically generates and
+returns objects in response to search requests in the {{cn=Monitor}}
+subtree.  Each object contains information about a particular aspect
+of the server.  The information is held in a combination of user
+applications and operational attributes.   This information can be
+access with {{ldapsearch(1)}}, with any general-purpose LDAP browser,
+or with specialized monitoring tools.  The {{SECT:Accessing Monitoring
+Information}} section provides a brief tutorial on how to use
+{{ldapsearch}}(1) to access monitoring information, while the
+{{SECT:Monitor information}} section details monitoring information
+base and its organization.
+
+While support for the monitor backend is included in default builds
+of slapd(8), this support requires some configuration to become
+active.  This may be done using either {{EX:cn=config}} or
+{{slapd.conf}}(5).  The former is discussed in the {{SECT:Monitor
+configuration via cn=config}} section of this of this chapter.  The
+latter is discussed in the {{SECT:Monitor configuration via
+slapd.conf(5)}} section of this chapter.  These sections assume
+monitor backend is built into {{slapd}} (e.g., {{EX:--enable-monitor=yes}},
+the default).  If the monitor backend was built as a module (e.g.,
+{{EX:--enable-monitor=mod}}, this module must loaded.  Loading of
+modules is discussed in the {{SECT:Configuring slapd}} and {{SECT:The
+slapd Configuration File}} chapters.
+
+
+H2: Monitor configuration via cn=config(5)
+
+{{This section has yet to be written.}}
+
+
+H2: Monitor configuration via slapd.conf(5)
+
+Configuration of the slapd.conf(5) to support LDAP monitoring
+is quite simple.
+
+First, ensure {{core.schema}} schema configuration file is included
+by your {{slapd.conf}}(5) file.  The {{monitor}} backend requires
+it.
+
+Second, instantiate the {{monitor backend}} by adding a
+{{database monitor}} directive below your existing database
+sections.  For instance:
+
+>	database monitor
+
+Lastly, add additional global or database directives as needed.
+
+Like most other database backends, the monitor backend does honor
+slapd(8) access and other administrative controls.   As some monitor
+information may be sensitive, it is generally recommend access to
+cn=monitor be restricted to directory administrators and their
+monitoring agents.  Adding an {{access}} directive immediately below
+the {{database monitor}} directive is a clear and effective approach
+for controlling access.  For instance, the addition of the following
+{{access}} directive immediately below the {{database monitor}}
+directive restricts access to monitoring information to the specified
+directory manager.
+
+>	access to *
+>		by dn.exact="cn=Manager,dc=example,dc=com
+>		by * none
+
+More information on {{slapd}}(8) access controls, see {{The access
+Control Directive}} section of the {{SECT:The slapd Configuration
+File}} chapter and {{slapd.access}}(5).
+
+After restarting {{slapd}}(8), you are ready to start exploring the
+monitoring information provided in {{EX:cn=config}} as discussed
+in the {{SECT:Accessing Monitoring Information}} section of this
+chapter.
+
+One can verify slapd(8) is properly configured to provide monitoring
+information by attempting to read the {{EX:cn=monitor}} object.
+For instance, if the following {{ldapsearch}}(1) command returns the
+cn=monitor object (with, as requested, no attributes), it's working.
+
+>	ldapsearch -x -D 'cn=Manager,dc=example,dc=com' -W \
+>		-b 'cn=Monitor' -s base 1.1
+
+Note that unlike general purpose database backends, the database
+suffix is hardcoded.  It's always {{EX:cn=Monitor}}.  So no {{suffix}}
+directive should be provided.  Also note that general purpose
+database backends, the monitor backend cannot be instantiated
+multiple times.  That is, there can only be one (or zero) occurrences
+of {{EX:database monitor}} in the server's configuration.
+
+
+H2: Accessing Monitoring Information
+
+As previously discussed, when enabled, the {{monitor}} backend
+dynamically generates and returns objects in response to search
+requests in the {{cn=Monitor}} subtree.  Each object contains
+information about a particular aspect of the server.  The information
+is held in a combination of user applications and operational
+attributes.  This information can be access with {{ldapsearch(1)}},
+with any general-purpose LDAP browser, or with specialized monitoring
+tools.
+
+This section provides a provides a brief tutorial on how to use
+{{ldapsearch}}(1) to access monitoring information.
+
+To inspect any particular monitor object, one performs search
+operation on the object with a baseObject scope and a
+{{EX:(objectClass=*)}} filter.  As the monitoring information is
+contained in a combination of user applications and operational
+attributes, the return all user applications attributes (e.g.,
+{{EX:'*'}}) and all operational attributes (e.g., {{EX:'+'}}) should
+be requested.   For instance, to read the {{EX:cn=Monitor}} object
+itself, the {{ldapsearch}}(1) command (modified to fit your configuration)
+can be used:
+
+>	ldapsearch -x -D 'cn=Manager,dc=example,dc=com' -W \
+>		-b 'cn=Monitor' -s base '(objectClass=*)' '*' '+'
+
+When run against your server, this should produce output
+similar to:
+
+>	dn: cn=Monitor
+>	objectClass: monitorServer
+>	structuralObjectClass: monitorServer
+>	cn: Monitor
+>	creatorsName:
+>	modifiersName:
+>	createTimestamp: 20061208223558Z
+>	modifyTimestamp: 20061208223558Z
+>	description: This subtree contains monitoring/managing objects.
+>	description: This object contains information about this server.
+>	description: Most of the information is held in operational attributes, which 
+>	 must be explicitly requested.
+>	monitoredInfo: OpenLDAP: slapd 2.4 (Dec  7 2006 17:30:29)
+>	entryDN: cn=Monitor
+>	subschemaSubentry: cn=Subschema
+>	hasSubordinates: TRUE
+
+To reduce the number of uninteresting attributes returned, one
+can be more selective when requesting which attributes are to be
+returned.  For instance, one could request the return of all
+attributes allowed by the {{monitorServer}} object class (e.g.,
+{{EX:@objectClass}}) instead of all user and all operational
 attributes:
 
-E: version: slapd <version> (<date>)
+>	ldapsearch -x -D 'cn=Manager,dc=example,dc=com' -W \
+>		-b 'cn=Monitor' -s base '(objectClass=*)' '@monitorServer'
 
-This attribute identifies the slapd server software by name,
-version, and build date, e.g., {{EX: slapd 3.3 (Thu May 21 14:19:03
-EDT 1996)}}
+This limits the output as follows:
 
-E: threads: <integer>
+>	dn: cn=Monitor
+>	objectClass: monitorServer
+>	cn: Monitor
+>	description: This subtree contains monitoring/managing objects.
+>	description: This object contains information about this server.
+>	description: Most of the information is held in operational attributes, which 
+>	 must be explicitly requested.
+>	monitoredInfo: OpenLDAP: slapd 2.X (Dec  7 2006 17:30:29)
 
-This attribute indicates the number of threads (operations)
-currently outstanding in slapd.
+To return the names of all the monitoring objects, one performs a
+search of {{EX:cn=Monitor}} with subtree scope and {{EX:(objectClass=*)}}
+filter and requesting no attributes (e.g., {{EX:1.1}}) be returned.
 
-E: connection: <fd> : <opentime> : <opsinitiated> :
-E: 	<opscompleted> : <binddn> : [ <rw> ]
+>	ldapsearch -x -D 'cn=Manager,dc=example,dc=com' -W -b 'cn=Monitor' -s sub 1.1
 
-This multi-valued attribute summarizes information for each
-open connection. The information given is {{EX: <fd>}}, the file
-descriptor; {{EX: <opentime>}}, the time the connection was opened
-in UTC format; {{EX: <opsinitiated>}}, the number of operations
-initiated over the connection; {{EX: <opscompleted>}}, the number
-of operations completed over the connection; {{EX: <binddn>}}, the
-DN currently bound to the connection; and optionally {{EX: <rw>}},
-indicating whether the connection is currently blocked for
-read or write..
+If you run this command you will discover that there are many objects
+in the {{cn=Monitor}} subtree.  The following section describes
+some of the commonly available monitoring objects.
 
-E: currentconnections: <integer>
 
-The current number of connections.
+H2: Monitor Information
 
-E: totalconnections: <integer>
+The {{monitor}} backend provides a wealth of information useful
+for monitoring the slapd(8) contained in set of monitor objects.
+Each object contains information about a particular aspect of
+the server, such as a backends, a connection, or a thread.
+Some objects serve as containers for other objects and used
+to construct a hierarchy of objects.
 
-The total number of connections handled by slapd since it
-started.
+In this hierarchy, the most superior object is {cn=Monitor}.
+While this object primarily serves as a container for other
+objects, most of which are containers, this object provides
+information about this server.  In particular, it provides the
+slapd(8) version string.  Example:
 
-E: dtablesize: <integer>
+>	dn: cn=Monitor
+>	monitoredInfo: OpenLDAP: slapd 2.X (Dec  7 2006 17:30:29)
 
-The size of slapd's file descriptor table.
+Note: Examples in this section (and its subsections) have been
+trimmed to show only key information.
 
-E: writewaiters: <integer>
 
-The number of threads blocked waiting to write data to a
-client.
+H3: Backends
 
-E: readwaiters: <integer>
+The {{EX:cn=Backends,cn=Monitor}} object, itself, provides a list
+of available backends.  The list of available backends all builtin
+backends, as well as backends loaded by modules.  For example:
 
-The number of threads blocked waiting to read data from a
-client.
+>	dn: cn=Backends,cn=Monitor          
+>	monitoredInfo: config                 
+>	monitoredInfo: ldif     
+>	monitoredInfo: monitor
+>	monitoredInfo: bdb        
+>	monitoredInfo: hdb
 
-E: opsinitiated: <integer>
+This indicates the {{config}}, {{ldif}}, {{monitor}}, {{bdb}},
+and {{hdb}} backends are available.
 
-The total number of operations initiated by slapd since it
-started.
+The {{EX:cn=Backends,cn=Monitor}} object is also a container
+for available backend objects.  Each available backend object
+contains information about a particular backend.  For example:
 
-E: opscompleted: <integer>
+>	dn: cn=Backend 0,cn=Backends,cn=Monitor 
+>	monitoredInfo: config
+>	monitorRuntimeConfig: TRUE
+>	supportedControl: 2.16.840.1.113730.3.4.2  
+>	seeAlso: cn=Database 0,cn=Databases,cn=Monitor
+>	
+>	dn: cn=Backend 1,cn=Backends,cn=Monitor  
+>	monitoredInfo: ldif          
+>	monitorRuntimeConfig: TRUE     
+>	supportedControl: 2.16.840.1.113730.3.4.2
+>	
+>	dn: cn=Backend 2,cn=Backends,cn=Monitor
+>	monitoredInfo: monitor
+>	monitorRuntimeConfig: TRUE
+>	supportedControl: 2.16.840.1.113730.3.4.2
+>	seeAlso: cn=Database 2,cn=Databases,cn=Monitor
+>	
+>	dn: cn=Backend 3,cn=Backends,cn=Monitor
+>	monitoredInfo: bdb
+>	monitorRuntimeConfig: TRUE
+>	supportedControl: 1.3.6.1.1.12
+>	supportedControl: 2.16.840.1.113730.3.4.2
+>	supportedControl: 1.3.6.1.4.1.4203.666.5.2
+>	supportedControl: 1.2.840.113556.1.4.319
+>	supportedControl: 1.3.6.1.1.13.1
+>	supportedControl: 1.3.6.1.1.13.2
+>	supportedControl: 1.3.6.1.4.1.4203.1.10.1
+>	supportedControl: 1.2.840.113556.1.4.1413
+>	supportedControl: 1.3.6.1.4.1.4203.666.11.7.2
+>	seeAlso: cn=Database 1,cn=Databases,cn=Monitor
+>	
+>	dn: cn=Backend 4,cn=Backends,cn=Monitor
+>	monitoredInfo: hdb
+>	monitorRuntimeConfig: TRUE
+>	supportedControl: 1.3.6.1.1.12
+>	supportedControl: 2.16.840.1.113730.3.4.2
+>	supportedControl: 1.3.6.1.4.1.4203.666.5.2
+>	supportedControl: 1.2.840.113556.1.4.319
+>	supportedControl: 1.3.6.1.1.13.1
+>	supportedControl: 1.3.6.1.1.13.2
+>	supportedControl: 1.3.6.1.4.1.4203.1.10.1
+>	supportedControl: 1.2.840.113556.1.4.1413
+>	supportedControl: 1.3.6.1.4.1.4203.666.11.7.2
 
-The total number of operations completed by slapd since it
-started.
+For each of these objects, monitorInfo indicates which backend the
+information in the object is about.  For instance, the {{EX:cn=Backend
+3,cn=Backends,cn=Monitor}} object contains (in the example) information
+about the {{bdb}} backend. 
 
-E: entriessent: <integer>
+!block table
+Attribute|Description
+monitoredInfo|Name of backend
+supportedControl|supported LDAP control extensions
+seeAlso|Database objects of instances of this backend
+!endblock
 
-The total number of entries sent to clients by slapd since it
-started.
+H3: Connections
 
-E: bytessent: <integer>
+The main entry is empty; it should contain some statistics on the number 
+of connections.
 
-The total number of bytes sent to clients by slapd since it
-started.
+Dynamic child entries are created for each open connection, with stats on
+the activity on that connection (the format will be detailed later).
+There are two special child entries that show the number of total and
+current connections respectively.
 
-E: currenttime: <UTC time>
+For example:
 
-Slapd's idea of the current time.
+Total Connections:
 
-E: starttime: <integer>
+>   dn: cn=Total,cn=Connections,cn=Monitor
+>   structuralObjectClass: monitorCounterObject
+>   monitorCounter: 4
+>   entryDN: cn=Total,cn=Connections,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
 
-The time slapd was started.
+Current Connections:
 
-E: nbackends: <integer>
+>   dn: cn=Current,cn=Connections,cn=Monitor
+>   structuralObjectClass: monitorCounterObject
+>   monitorCounter: 2
+>   entryDN: cn=Current,cn=Connections,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
 
-The number of backends currently being served by slapd.
 
-E: concurrency: <integer>
+H3: Databases
 
-Under Solaris 2.x only, an indication of the current level of
-thread concurrency.
+The main entry contains the naming context of each configured database; 
+the child entries contain, for each database, the type and the naming
+context.
 
-Note that slapd takes a snapshot of this information and
-returns it to you. No attempt is made to ensure that the
-information is consistent (i.e., if an operation thread is
-modifying one of these things when the monitor thread is
-reading it, strange results could be returned).
+For example:
 
-You should be able to use any LDAP client to retrieve this
-information. Here's how you might do it using the
-{{I: ldapsearch}}(1) client:
+>   dn: cn=Database 2,cn=Databases,cn=Monitor
+>   structuralObjectClass: monitoredObject
+>   monitoredInfo: monitor
+>   monitorIsShadow: FALSE
+>   monitorContext: cn=Monitor
+>   readOnly: FALSE
+>   entryDN: cn=Database 2,cn=Databases,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
 
-E: ldapsearch -x -s base -b cn=monitor 'objectclass=*'
+H3: Listener
 
+It contains the description of the devices the server is currently 
+listening on:
+
+>   dn: cn=Listener 0,cn=Listeners,cn=Monitor
+>   structuralObjectClass: monitoredObject
+>   monitorConnectionLocalAddress: IP=0.0.0.0:389
+>   entryDN: cn=Listener 0,cn=Listeners,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
+
+
+H3: Log
+
+It contains the currently active log items.  The {{Log}} subsystem allows 
+user modify operations on the {{description}} attribute, whose values {{MUST}} 
+be in the list of admittable log switches:
+
+>   Trace
+>   Packets
+>   Args
+>   Conns
+>   BER
+>   Filter
+>   Config
+>   ACL
+>   Stats
+>   Stats2
+>   Shell
+>   Parse
+>   Sync
+
+These values can be added, replaced or deleted; they affect what 
+messages are sent to the syslog device.
+Custom values could be added by custom modules.
+
+H3: Operations
+
+It shows some statistics on the operations performed by the server:
+
+>   Initiated
+>   Completed
+
+and for each operation type, i.e.:
+
+>   Bind
+>   Unbind
+>   Add
+>   Delete
+>   Modrdn
+>   Modify
+>   Compare
+>   Search
+>   Abandon
+>   Extended
+
+There are too many types to list example here, so please try for yourself 
+using {{SECT: Monitor search example}}
+
+H3: Overlays
+
+The main entry contains the type of overlays available at run-time;
+the child entries, for each overlay, contain the type of the overlay.
+
+It should also contain the modules that have been loaded if dynamic 
+overlays are enabled:
+
+>   # Overlays, Monitor
+>   dn: cn=Overlays,cn=Monitor
+>   structuralObjectClass: monitorContainer
+>   monitoredInfo: syncprov
+>   monitoredInfo: accesslog
+>   monitoredInfo: glue
+>   entryDN: cn=Overlays,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: TRUE
+
+H3: SASL
+
+Currently empty.
+
+H3: Statistics
+
+It shows some statistics on the data sent by the server:
+
+>   Bytes
+>   PDU
+>   Entries
+>   Referrals
+
+e.g.
+
+>   # Entries, Statistics, Monitor
+>   dn: cn=Entries,cn=Statistics,cn=Monitor
+>   structuralObjectClass: monitorCounterObject
+>   monitorCounter: 612248
+>   entryDN: cn=Entries,cn=Statistics,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
+
+H3: Threads
+
+It contains the maximum number of threads enabled at startup and the 
+current backload.
+
+e.g.
+
+>   # Max, Threads, Monitor
+>   dn: cn=Max,cn=Threads,cn=Monitor
+>   structuralObjectClass: monitoredObject
+>   monitoredInfo: 16
+>   entryDN: cn=Max,cn=Threads,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
+
+
+H3: Time
+
+It contains two child entries with the start time and the current time 
+of the server.
+
+e.g.
+
+Start time:
+
+>   dn: cn=Start,cn=Time,cn=Monitor
+>   structuralObjectClass: monitoredObject
+>   monitorTimestamp: 20061205124040Z
+>   entryDN: cn=Start,cn=Time,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
+
+Current time:
+
+>   dn: cn=Current,cn=Time,cn=Monitor
+>   structuralObjectClass: monitoredObject
+>   monitorTimestamp: 20061207120624Z
+>   entryDN: cn=Current,cn=Time,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
+
+H3: TLS
+
+Currently empty.
+
+H3: Waiters
+
+It contains the number of current read waiters.
+
+e.g.
+
+Read waiters:
+
+>   dn: cn=Read,cn=Waiters,cn=Monitor
+>   structuralObjectClass: monitorCounterObject
+>   monitorCounter: 7
+>   entryDN: cn=Read,cn=Waiters,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
+
+Write waiters:
+
+>   dn: cn=Write,cn=Waiters,cn=Monitor
+>   structuralObjectClass: monitorCounterObject
+>   monitorCounter: 0
+>   entryDN: cn=Write,cn=Waiters,cn=Monitor
+>   subschemaSubentry: cn=Subschema
+>   hasSubordinates: FALSE
+
+Add new monitored things here and discuss, referencing man pages and present
+examples
+
+

Copied: openldap/trunk/doc/guide/admin/overlays.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/overlays.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/overlays.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/overlays.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,685 @@
+# $OpenLDAP: pkg/openldap-guide/admin/overlays.sdf,v 1.8.2.5 2007/11/27 19:06:07 quanah Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Overlays
+
+Overlays are software components that provide hooks to functions analogous to 
+those provided by backends, which can be stacked on top of the backend calls 
+and as callbacks on top of backend responses to alter their behavior. 
+
+Overlays may be compiled statically into slapd, or when module support
+is enabled, they may be dynamically loaded. Most of the overlays
+are only allowed to be configured on individual databases, but some
+may also be configured globally.
+
+Essentially they represent a means to:
+
+    * customize the behavior of existing backends without changing the backend 
+      code and without requiring one to write a new custom backend with 
+      complete functionality
+    * write functionality of general usefulness that can be applied to 
+      different backend types
+
+Overlays are usually documented by separate specific man pages in section 5; 
+the naming convention is
+
+>        slapo-<overlay name>
+
+Not all distributed overlays have a man page yet. Feel free to contribute one, 
+if you think you well understood the behavior of the component and the 
+implications of all the related configuration directives.
+
+Official overlays are located in
+
+>        servers/slapd/overlays/
+
+That directory also contains the file slapover.txt, which describes the 
+rationale of the overlay implementation, and may serve as guideline for the 
+development of custom overlays.
+
+Contribware overlays are located in
+
+>        contrib/slapd-modules/<overlay name>/
+
+along with other types of run-time loadable components; they are officially 
+distributed, but not maintained by the project.
+
+They can be stacked on the frontend as well; this means that they can be 
+executed after a request is parsed and validated, but right before the 
+appropriate database is selected. The main purpose is to affect operations 
+regardless of the database they will be handled by, and, in some cases, 
+to influence the selection of the database by massaging the request DN. 
+
+All the current overlays in 2.4 are listed and described in detail in the 
+following sections.
+
+
+H2: Access Logging
+
+
+H3: Overview
+
+This overlay can record accesses to a given backend database on another
+database.
+
+
+H3: Access Logging Configuration
+
+
+H2: Audit Logging
+
+This overlay records changes on a given backend database to an LDIF log
+file.
+   
+   
+H3: Overview
+
+
+H3: Audit Logging Configuration
+
+
+H2: Chaining
+
+
+H3: Overview
+
+The chain overlay provides basic chaining capability to the underlying 
+database.
+
+What is chaining? It indicates the capability of a DSA to follow referrals on 
+behalf of the client, so that distributed systems are viewed as a single 
+virtual DSA by clients that are otherwise unable to "chase" (i.e. follow) 
+referrals by themselves.
+
+The chain overlay is built on top of the ldap backend; it is compiled by 
+default when --enable-ldap.
+
+
+H3: Chaining Configuration
+
+In order to demonstrate how this overlay works, we shall discuss a typical 
+scenario which might be one master server and three Syncrepl slaves. 
+
+On each replica, add this near the top of the file (global), before any database 
+definitions:
+
+>        overlay                    chain
+>        chain-uri                  "ldap://ldapmaster.example.com"
+>        chain-idassert-bind        bindmethod="simple"
+>                                   binddn="cn=Manager,dc=example,dc=com"
+>                                   credentials="<secret>" 
+>                                   mode="self"
+>        chain-tls                  start
+>        chain-return-error         TRUE 
+
+Add this below your {{syncrepl}} statement:
+
+>        updateref                  "ldap://ldapmaster.example.com/"
+
+The {{B:chain-tls}} statement enables TLS from the slave to the ldap master. 
+The DITs are exactly the same between these machines, therefore whatever user 
+bound to the slave will also exist on the master. If that DN does not have 
+update privileges on the master, nothing will happen.
+
+You will need to restart the slave after these changes. Then, if you are using 
+{{loglevel 256}}, you can monitor an {{ldapmodify}} on the slave and the master.
+
+Now start an {{ldapmodify}} on the slave and watch the logs. You should expect 
+something like:
+
+>        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 fd=31 ACCEPT from IP=143.199.102.216:45181 (IP=143.199.102.216:389)
+>        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 op=0 STARTTLS
+>        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 op=0 RESULT oid= err=0 text=
+>        Sep  6 09:27:25 slave1 slapd[29274]: conn=11 fd=31 TLS established tls_ssf=256 ssf=256
+>        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=1 BIND dn="uid=user1,ou=people,dc=example,dc=com" method=128
+>        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=1 BIND dn="uid=user1,ou=People,dc=example,dc=com" mech=SIMPLE ssf=0
+>        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=1 RESULT tag=97 err=0 text=
+>        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=2 MOD dn="uid=user1,ou=People,dc=example,dc=com"
+>        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=2 MOD attr=mail
+>        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=2 RESULT tag=103 err=0 text=
+>        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 op=3 UNBIND
+>        Sep  6 09:27:28 slave1 slapd[29274]: conn=11 fd=31 closed
+>        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: LDAP_RES_SEARCH_ENTRY(LDAP_SYNC_MODIFY)
+>        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: be_search (0)
+>        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: uid=user1,ou=People,dc=example,dc=com
+>        Sep  6 09:27:28 slave1 slapd[29274]: syncrepl_entry: be_modify (0)
+
+And on the master you will see this:
+
+>        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 PROXYAUTHZ dn="uid=user1,ou=people,dc=example,dc=com"
+>        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 MOD dn="uid=user1,ou=People,dc=example,dc=com"
+>        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 MOD attr=mail
+>        Sep  6 09:23:57 ldapmaster slapd[2961]: conn=55902 op=3 RESULT tag=103 err=0 text=
+
+Note: You can clearly see the PROXYAUTHZ line on the master, indicating the 
+proper identity assertion for the update on the master. Also note the slave 
+immediately receiving the Syncrepl update from the master.
+
+H3: Handling Chaining Errors
+
+By default, if chaining fails, the original referral is returned to the client
+under the assumption that the client might want to try and follow the referral.
+
+With the following directive however, if the chaining fails at the provider 
+side, the actual error is returned to the client.
+
+>        chain-return-error TRUE
+
+
+H2: Constraints
+
+
+H3: Overview
+
+This overlay enforces a regular expression constraint on all values
+of specified attributes. It is used to enforce a more rigorous
+syntax when the underlying attribute syntax is too general.
+
+
+H3: Constraint Configuration
+   
+   
+H2: Dynamic Directory Services
+
+
+H3: Overview
+
+This overlay supports dynamic objects, which have a limited life after
+which they expire and are automatically deleted.
+   
+   
+H3: Dynamic Directory Service Configuration
+
+
+H2: Dynamic Groups
+
+
+H3: Overview
+
+This overlay extends the Compare operation to detect
+members of a dynamic group. This overlay is now deprecated
+as all of its functions are available using the
+{{SECT:Dynamic Lists}} overlay.
+
+
+H3: Dynamic Group Configuration
+
+
+H2: Dynamic Lists
+   
+   
+H3: Overview
+
+This overlay allows expansion of dynamic groups and lists. Instead of having the
+group members or list attributes hard coded, this overlay allows us to define
+an LDAP search whose results will make up the group or list.
+
+H3: Dynamic List Configuration
+
+This module can behave both as a dynamic list and dynamic group, depending on
+the configuration. The syntax is as follows:
+
+>       overlay dynlist
+>       dynlist-attrset <group-oc> <URL-ad> [member-ad]
+
+The parameters to the {{F:dynlist-attrset}} directive have the following meaning:
+* {{F:<group-oc>}}: specifies which object class triggers the subsequent LDAP search.
+Whenever an entry with this object class is retrieved, the search is performed.
+* {{F:<URL-ad>}}: is the name of the attribute which holds the search URI. It
+has to be a subtype of {{F:labeledURI}}. The attributes and values present in
+the search result are added to the entry unless {{F:member-ad}} is used (see
+below).
+* {{F:member-ad}}: if present, changes the overlay behaviour into a dynamic group.
+Instead of inserting the results of the search in the entry, the distinguished name
+of the results are added as values of this attribute.
+
+Here is an example which will allow us to have an email alias which automatically
+expands to all user's emails according to our LDAP filter:
+
+In {{slapd.conf}}(5):
+>       overlay dynlist
+>       dynlist-attrset nisMailAlias labeledURI
+
+This means that whenever an entry which has the {{F:nisMailAlias}} object class is
+retrieved, the search specified in the {{F:labeledURI}} attribute is performed.
+
+Let's say we have this entry in our directory:
+>       cn=all,ou=aliases,dc=example,dc=com
+>       cn: all
+>       objectClass: nisMailAlias
+>       labeledURI: ldap:///ou=People,dc=example,dc=com?mail?one?(objectClass=inetOrgPerson)
+
+If this entry is retrieved, the search specified in {{F:labeledURI}} will be
+performed and the results will be added to the entry just as if they have always
+been there. In this case, the search filter selects all entries directly
+under {{F:ou=People}} that have the {{F:inetOrgPerson}} object class and retrieves
+the {{F:mail}} attribute, if it exists.
+
+This is what gets added to the entry when we have two users under {{F:ou=People}}
+that match the filter:
+!import "allmail-en.png"; align="center"; title="Dynamic list for email aliases"
+FT[align="Center"] Figure X.Y: Dynamic List for all emails
+
+The configuration for a dynamic group is similar. Let's see an example which would
+automatically populate an {{F:allusers}} group with all the user accounts in the
+directory.
+
+In {{F:slapd.conf}}(5):
+>       overlay dynlist
+>       dynlist-attrset groupOfNames labeledURI member
+
+Let's apply it to the following entry:
+>       cn=allusers,ou=group,dc=example,dc=com
+>       cn: all
+>       objectClass: groupOfNames
+>       labeledURI: ldap:///ou=people,dc=example,dc=com??one?(objectClass=inetOrgPerson)
+
+The behaviour is similar to the dynamic list configuration we had before:
+whenever an entry with the {{F:groupOfNames}} object class is retrieved, the
+search specified in the {{F:labeledURI}} attribute is performed. But this time,
+only the distinguished names of the results are added, and as values of the
+{{F:member}} attribute.
+
+This is what we get:
+!import "allusersgroup-en.png"; align="center"; title="Dynamic group for all users"
+FT[align="Center"] Figure X.Y: Dynamic Group for all users
+
+Note that a side effect of this scheme of dymamic groups is that the members
+need to be specified as full DNs. So, if you are planning in using this for
+{{F:posixGroup}}s, be sure to use RFC2307bis and some attribute which can hold
+distinguished names. The {{F:memberUid}} attribute used in the {{F:posixGroup}}
+object class can hold only names, not DNs, and is therefore not suitable for
+dynamic groups.
+
+H2: Reverse Group Membership Maintenance
+
+H3: Overview
+
+In some scenarios, it may be desirable for a client to be able to determine
+which groups an entry is a member of, without performing an additional search.
+Examples of this are applications using the {{TERM:DIT}} for access control
+based on group authorization.
+
+The {{B:memberof}} overlay updates an attribute (by default {{B:memberOf}}) whenever
+changes occur to the membership attribute (by default {{B:member}}) of entries of the
+objectclass (by default {{B:groupOfNames}}) configured to trigger updates.
+
+Thus, it provides maintenance of the list of groups an entry is a member of,
+when usual maintenance of groups is done by modifying the members on the group
+entry.
+
+H3: Member Of Configuration
+
+The typical use of this overlay requires just enabling the overlay for a
+specific database. For example, with the following minimal slapd.conf:
+
+>        include /usr/share/openldap/schema/core.schema
+>        include /usr/share/openldap/schema/cosine.schema
+>        modulepath      /usr/lib/openldap
+>        moduleload      memberof.la
+>        authz-regexp "gidNumber=0\\\+uidNumber=0,cn=peercred,cn=external,cn=auth"
+>                "cn=Manager,dc=example,dc=com"
+>        database        bdb
+>        suffix          "dc=example,dc=com"
+>        rootdn          "cn=Manager,dc=example,dc=com"
+>        rootpw          secret
+>        directory       /var/lib/ldap2.4
+>        checkpoint 256 5
+>        index   objectClass   eq
+>        index   uid           eq,sub
+>        
+>        overlay memberof
+
+adding the following ldif:
+
+>        cat memberof.ldif
+>        dn: dc=example,dc=com
+>        objectclass: domain
+>        dc: example
+>        
+>        dn: ou=Group,dc=example,dc=com
+>        objectclass: organizationalUnit
+>        ou: Group
+>        
+>        dn: ou=People,dc=example,dc=com
+>        objectclass: organizationalUnit
+>        ou: People
+>        
+>        dn: uid=test1,ou=People,dc=example,dc=com
+>        objectclass: account
+>        uid: test1
+>        
+>        dn: cn=testgroup,ou=Group,dc=example,dc=com
+>        objectclass: groupOfNames
+>        cn: testgroup
+>        member: uid=test1,ou=People,dc=example,dc=com
+
+Results in the following output from a search on the test1 user:
+
+> # ldapsearch -LL -Y EXTERNAL -H ldapi:/// "(uid=test1)" -b dc=example,dc=com memberOf
+> SASL/EXTERNAL authentication started
+> SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
+> SASL SSF: 0
+> version: 1
+> 
+> dn: uid=test1,ou=People,dc=example,dc=com
+> memberOf: cn=testgroup,ou=Group,dc=example,dc=com
+
+Note that the {{B:memberOf}} attribute is an operational attribute, so it must be
+requested explicitly.
+
+
+H2: The Proxy Cache Engine
+
+{{TERM:LDAP}} servers typically hold one or more subtrees of a
+{{TERM:DIT}}. Replica (or shadow) servers hold shadow copies of
+entries held by one or more master servers.  Changes are propagated
+from the master server to replica (slave) servers using LDAP Sync
+replication.  An LDAP cache is a special type of replica which holds
+entries corresponding to search filters instead of subtrees.
+
+H3: Overview
+
+The proxy cache extension of slapd is designed to improve the
+responsiveness of the ldap and meta backends. It handles a search
+request (query)
+by first determining whether it is contained in any cached search
+filter. Contained requests are answered from the proxy cache's local
+database. Other requests are passed on to the underlying ldap or
+meta backend and processed as usual.
+
+E.g. {{EX:(shoesize>=9)}} is contained in {{EX:(shoesize>=8)}} and
+{{EX:(sn=Richardson)}} is contained in {{EX:(sn=Richards*)}}
+
+Correct matching rules and syntaxes are used while comparing
+assertions for query containment. To simplify the query containment
+problem, a list of cacheable "templates" (defined below) is specified
+at configuration time. A query is cached or answered only if it
+belongs to one of these templates. The entries corresponding to
+cached queries are stored in the proxy cache local database while
+its associated meta information (filter, scope, base, attributes)
+is stored in main memory. 
+
+A template is a prototype for generating LDAP search requests.
+Templates are described by a prototype search filter and a list of
+attributes which are required in queries generated from the template.
+The representation for prototype filter is similar to {{REF:RFC4515}},
+except that the assertion values are missing. Examples of prototype
+filters are: (sn=),(&(sn=)(givenname=)) which are instantiated by
+search filters (sn=Doe) and (&(sn=Doe)(givenname=John)) respectively.
+
+The cache replacement policy removes the least recently used (LRU)
+query and entries belonging to only that query. Queries are allowed
+a maximum time to live (TTL) in the cache thus providing weak
+consistency. A background task periodically checks the cache for
+expired queries and removes them.
+
+The Proxy Cache paper
+({{URL:http://www.openldap.org/pub/kapurva/proxycaching.pdf}}) provides
+design and implementation details.
+
+
+H3: Proxy Cache Configuration
+
+The cache configuration specific directives described below must
+appear after a {{EX:overlay proxycache}} directive within a
+{{EX:"database meta"}} or {{EX:database ldap}} section of
+the server's {{slapd.conf}}(5) file.
+
+H4: Setting cache parameters
+
+> proxyCache <DB> <maxentries> <nattrsets> <entrylimit> <period>
+
+This directive enables proxy caching and sets general cache
+parameters.  The <DB> parameter specifies which underlying database
+is to be used to hold cached entries.  It should be set to
+{{EX:bdb}} or {{EX:hdb}}.  The <maxentries> parameter specifies the
+total number of entries which may be held in the cache.  The
+<nattrsets> parameter specifies the total number of attribute sets
+(as specified by the {{EX:proxyAttrSet}} directive) that may be
+defined.  The <entrylimit> parameter specifies the maximum number of
+entries in a cacheable query.  The <period> specifies the consistency
+check period (in seconds).  In each period, queries with expired
+TTLs are removed.
+
+H4: Defining attribute sets
+
+> proxyAttrset <index> <attrs...>
+
+Used to associate a set of attributes to an index. Each attribute
+set is associated with an index number from 0 to <numattrsets>-1.
+These indices are used by the proxyTemplate directive to define
+cacheable templates.
+
+H4: Specifying cacheable templates 
+
+> proxyTemplate <prototype_string> <attrset_index> <TTL>
+
+Specifies a cacheable template and the "time to live" (in sec) <TTL>
+for queries belonging to the template. A template is described by
+its prototype filter string and set of required attributes identified
+by <attrset_index>.
+
+
+H4: Example
+
+An example {{slapd.conf}}(5) database section for a caching server
+which proxies for the {{EX:"dc=example,dc=com"}} subtree held
+at server {{EX:ldap.example.com}}.
+ 
+>	database 	ldap
+>	suffix 		"dc=example,dc=com" 
+>	rootdn 		"dc=example,dc=com" 
+>	uri    		ldap://ldap.example.com/
+>	overlay proxycache
+>	proxycache    bdb 100000 1 1000 100
+>	proxyAttrset  0 mail postaladdress telephonenumber 
+>	proxyTemplate (sn=) 0 3600
+>	proxyTemplate (&(sn=)(givenName=)) 0 3600
+>	proxyTemplate (&(departmentNumber=)(secretary=*)) 0 3600
+>
+>	cachesize 20
+>	directory ./testrun/db.2.a
+>	index       objectClass eq
+>	index       cn,sn,uid,mail  pres,eq,sub
+
+
+H5: Cacheable Queries
+
+A LDAP search query is cacheable when its filter matches one of the
+templates as defined in the "proxyTemplate" statements and when it references
+only the attributes specified in the corresponding attribute set. 
+In the example above the attribute set number 0 defines that only the
+attributes: {{EX:mail postaladdress telephonenumber}} are cached for the following
+proxyTemplates.
+
+H5: Examples:
+
+>	Filter: (&(sn=Richard*)(givenName=jack)) 
+>	Attrs: mail telephoneNumber
+
+    is cacheable, because it matches the template {{EX:(&(sn=)(givenName=))}} and its
+    attributes are contained in proxyAttrset 0.
+
+>	Filter: (&(sn=Richard*)(telephoneNumber))
+>	Attrs: givenName 
+
+    is not cacheable, because the filter does not match the template,
+    nor is the attribute givenName stored in the cache
+
+>	Filter: (|(sn=Richard*)(givenName=jack))
+>	Attrs: mail telephoneNumber
+
+    is not cacheable, because the filter does not match the template ( logical
+    OR "|" condition instead of logical AND "&" )
+                           
+                           
+H2: Password Policies
+
+
+H3: Overview
+
+This overlay provides a variety of password control mechanisms,
+e.g. password aging, password reuse and duplication control, mandatory
+password resets, etc.
+
+
+H3: Password Policy Configuration
+
+
+H2: Referential Integrity
+
+
+H3: Overview
+
+This overlay can be used with a backend database such as slapd-bdb(5)
+to maintain the cohesiveness of a schema which utilizes reference
+attributes.
+
+Whenever a {{modrdn}} or {{delete}} is performed, that is, when an entry's DN
+is renamed or an entry is removed, the server will search the directory for
+references to this DN (in selected attributes: see below) and update them
+accordingly. If it was a {{delete}} operation, the reference is deleted. If it
+was a {{modrdn}} operation, then the reference is updated with the new DN.
+
+For example, a very common administration task is to maintain group membership
+lists, specially when users are removed from the directory. When an
+user account is deleted or renamed, all groups this user is a member of have to be
+updated. LDAP administrators usually have scripts for that. But we can use the
+{{F:refint}} overlay to automate this task. In this example, if the user is
+removed from the directory, the overlay will take care to remove the user from
+all the groups he/she was a member of. No more scripting for this.
+
+H3: Referential Integrity Configuration
+
+The configuration for this overlay is as follows:
+>       overlay refint
+>       refint_attributes <attribute [attribute ...]>
+>       refint_nothing <string>
+
+* {{F:refint_attributes}}: this parameter specifies a space separated list of
+attributes which will have the referential integrity maintained. When an entry is
+removed or has its DN renamed, the server will do an internal search for any of the
+{{F:refint_attributes}} that point to the affected DN and update them accordingly. IMPORTANT:
+the attributes listed here must have the {{F:distinguishedName}} syntax, that is,
+hold DNs as values.
+* {{F:refint_nothing}}: some times, while trying to maintain the referential
+integrity, the server has to remove the last attribute of its kind from an
+entry. This may be prohibited by the schema: for example, the
+{{F:groupOfNames}} object class requires at least one member. In these cases,
+the server will add the attribute value specified in {{F:refint_nothing}}
+to the entry.
+
+To illustrate this overlay, we will use the group membership scenario.
+
+In {{F:slapd.conf}}:
+>       overlay refint
+>       refint_attributes member
+>       refint_nothing "cn=admin,dc=example,dc=com"
+
+This configuration tells the overlay to maintain the referential integrity of the {{F:member}}
+attribute. This attribute is used in the {{F:groupOfNames}} object class which always needs
+a member, so we add the {{F:refint_nothing}} directive to fill in the group with a standard
+member should all the members vanish.
+
+If we have the following group membership, the refint overlay will
+automatically remove {{F:john}} from the group if his entry is removed from the
+directory:
+
+!import "refint.png"; align="center"; title="Group membership"
+FT[align="Center"] Figure X.Y: Maintaining referential integrity in groups
+
+Notice that if we rename ({{F:modrdn}}) the {{F:john}} entry to, say, {{F:jsmith}}, the refint
+overlay will also rename the reference in the {{F:member}} attribute, so the group membership
+stays correct.
+
+If we removed all users from the directory who are a member of this group, then the end result
+would be a single member in the group: {{F:cn=admin,dc=example,dc=com}}. This is the
+{{F:refint_nothing}} parameter kicking into action so that the schema is not violated.
+
+H2: Return Code
+
+
+H3: Overview
+
+This overlay is useful to test the behavior of clients when
+server-generated erroneous and/or unusual responses occur.
+
+
+H3: Return Code Configuration
+
+
+H2: Rewrite/Remap
+            
+            
+H3: Overview
+
+It performs basic DN/data rewrite and
+objectClass/attributeType mapping.
+
+
+H3: Rewrite/Remap Configuration
+
+
+H2: Sync Provider
+
+
+H3: Overview
+
+This overlay implements the provider-side support for syncrepl
+replication, including persistent search functionality
+
+
+H3: Sync Provider Configuration
+
+
+H2: Translucent Proxy
+
+
+H3: Overview
+
+This overlay can be used with a backend database such as slapd-bdb (5)
+to create a "translucent proxy".
+
+Content of entries retrieved from a remote LDAP server can be partially
+overridden by the database.
+
+
+H3: Translucent Proxy Configuration
+
+
+H2: Attribute Uniqueness
+
+
+H3: Overview
+
+This overlay can be used with a backend database such as slapd-bdb (5)
+to enforce the uniqueness of some or all attributes within a subtree.
+
+
+H3: Attribute Uniqueness Configuration
+
+
+H2: Value Sorting
+
+
+H3: Overview
+
+This overlay can be used to enforce a specific order for the values
+of an attribute when it is returned in a search.
+
+
+H3: Value Sorting Configuration
+
+
+H2: Overlay Stacking
+
+
+H3: Overview
+
+
+H3: Example Scenarios
+
+
+H4: Samba

Modified: openldap/trunk/doc/guide/admin/preface.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/preface.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/preface.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/admin/preface.sdf,v 1.24.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/preface.sdf,v 1.25.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 # 
@@ -9,7 +9,7 @@
 # document's copyright
 P2[notoc] Copyright
 
-Copyright 1998-2005, The {{ORG[expand]OLF}}, {{All Rights Reserved}}.
+Copyright 1998-2007, The {{ORG[expand]OLF}}, {{All Rights Reserved}}.
 
 Copyright 1992-1996, Regents of the {{ORG[expand]UM}}, {{All Rights Reserved}}.
 
@@ -17,21 +17,21 @@
 document is subject to terms of conditions set forth in {{SECT:OpenLDAP
 Software Copyright Notices}} and the {{SECT:OpenLDAP Public License}}.
 Complete copies of the notices and associated license can be found
-in Appendix B and C, respectively.
+in Appendix K and L, respectively.
 
 
 P2[notoc] Scope of this Document
 
 This document provides a guide for installing [[DOC_NAME]]
-({{URL:http://www.openldap.org/software/}})
-on {{TERM:UNIX}} (and UNIX-like) systems.  The document is aimed at
-experienced system administrators but who may not have prior experience
-operating {{TERM:LDAP}}-based directory software.
+({{URL:http://www.openldap.org/software/}}) on {{TERM:UNIX}} (and
+UNIX-like) systems.  The document is aimed at experienced system
+administrators with basic understanding of {{TERM:LDAP}}-based
+directory services.
 
 This document is meant to be used in conjunction with other OpenLDAP
-information resources provided with the software package and on
-the project's extensive site ({{URL:http://www.OpenLDAP.org/}}) on
-the World Wide Web.  The site makes available a number of resources.
+information resources provided with the software package and on the
+project's site ({{URL:http://www.OpenLDAP.org/}}) on the
+{{TERM[expand]WWW}}.  The site makes available a number of resources.
 
 !block table; align=Center; coltags="N,URL"; \
 	title="OpenLDAP Resources"
@@ -40,6 +40,7 @@
 Frequently Asked Questions|http://www.OpenLDAP.org/faq/
 Issue Tracking System|http://www.OpenLDAP.org/its/
 Mailing Lists|http://www.OpenLDAP.org/lists/
+Manual Pages|http://www.OpenLDAP.org/software/man.cgi
 Software Pages|http://www.OpenLDAP.org/software/
 Support Pages|http://www.OpenLDAP.org/support/
 !endblock
@@ -47,26 +48,28 @@
 
 P2[notoc] Acknowledgments
 
-The {{ORG[expand]OLP}} is comprised of a team of volunteers.  This document
-would not be possible without their contribution of time and energy.
+The {{ORG[expand]OLP}} is comprised of a team of volunteers.  This
+document would not be possible without their contribution of time
+and energy.
 
 The OpenLDAP Project would also like to thank the {{ORG[expand]UMLDAP}}
 for building the foundation of LDAP software and information to
 which OpenLDAP Software is built upon.  This document is based upon
-U-Mich LDAP document: {{The SLAPD and SLURPD Administrators Guide}}.
+University of Michigan document: {{REF[expand]UM-GUIDE}}.
 
 
 P2[notoc] Amendments
 
-Suggested enhancements and corrections to this document should
-be submitted using the {{ORG:OpenLDAP}}
-{{{{TERM[expand]ITS}}}} ({{URL: http://www.openldap.org/its/}}).
+Suggested enhancements and corrections to this document should be
+submitted using the {{PRD:OpenLDAP}} {{TERM[expand]ITS}}
+({{URL: http://www.openldap.org/its/}}).
 
 
 P2[notoc] About this document
 
-This document was produced using the {{Simple Document Format}}
-({{URL:http://search.cpan.org/src/IANC/sdf-2.001/doc/}}) documentation
-system developed by {{Ian Clatworthy}}.  Tools for {{SDF}} are
-available from CPAN ({{URL:http://search.cpan.org/search?query=SDF}}).
+This document was produced using the {{TERM[expand]SDF}} ({{TERM:SDF}})
+documentation system
+({{URL:http://search.cpan.org/src/IANC/sdf-2.001/doc/catalog.html}})
+developed by {{Ian Clatworthy}}.  Tools for SDF are available from
+{{ORG:CPAN}} ({{URL:http://search.cpan.org/search?query=SDF&mode=dist}}).
 

Deleted: openldap/trunk/doc/guide/admin/proxycache.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/proxycache.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/proxycache.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,148 +0,0 @@
-# $OpenLDAP: pkg/openldap-guide/admin/proxycache.sdf,v 1.8.2.2 2007/01/02 21:43:43 kurt Exp $
-# Copyright 2003-2007 The OpenLDAP Foundation, All Rights Reserved.
-# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
-
-H1: The Proxy Cache Engine
-
-LDAP servers typically hold one or more subtrees of a DIT. Replica
-(or shadow) servers hold shadow copies of entries held by one or
-more master servers.  Changes are propagated from the master server
-to replica (slave) servers using LDAP Sync or {{slurpd}}(8). An
-LDAP cache is a special type of replica which holds entries
-corresponding to search filters instead of subtrees.
-
-H2: Overview
-
-The proxy cache extension of slapd is designed to improve the
-responseiveness of the ldap and meta backends. It handles a search
-request (query)
-by first determining whether it is contained in any cached search
-filter. Contained requests are answered from the proxy cache's local
-database. Other requests are passed on to the underlying ldap or
-meta backend and processed as usual.
-
-E.g. {{EX:(shoesize>=9)}} is contained in {{EX:(shoesize>=8)}} and
-{{EX:(sn=Richardson)}} is contained in {{EX:(sn=Richards*)}}
-
-Correct matching rules and syntaxes are used while comparing
-assertions for query containment. To simplify the query containment
-problem, a list of cacheable "templates" (defined below) is specified
-at configuration time. A query is cached or answered only if it
-belongs to one of these templates. The entries corresponding to
-cached queries are stored in the proxy cache local database while
-its associated meta information (filter, scope, base, attributes)
-is stored in main memory. 
-
-A template is a prototype for generating LDAP search requests.
-Templates are described by a prototype search filter and a list of
-attributes which are required in queries generated from the template.
-The representation for prototype filter is similar to RFC 2254,
-except that the assertion values are missing. Examples of prototype
-filters are: (sn=),(&(sn=)(givenname=)) which are instantiated by
-search filters (sn=Doe) and (&(sn=Doe)(givenname=John)) respectively.
-
-The cache replacement policy removes the least recently used (LRU)
-query and entries belonging to only that query. Queries are allowed
-a maximum time to live (TTL) in the cache thus providing weak
-consistency. A background task periodically checks the cache for
-expired queries and removes them.
-
-The Proxy Cache paper
-({{URL:http://www.openldap.org/pub/kapurva/proxycaching.pdf}}) provides
-design and implementation details.
-
-
-H2: Proxy Cache Configuration
-
-The cache configuration specific directives described below must
-appear after a {{EX:overlay proxycache}} directive within a
-{{EX:"database meta"}} or {{EX:database ldap}} section of
-the server's {{slapd.conf}}(5) file.
-
-H3: Setting cache parameters
-
-> proxyCache <DB> <maxentries> <nattrsets> <entrylimit> <period>
-
-This directive enables proxy caching and sets general cache parameters.
-The <DB> parameter specifies which underlying database is to be
-used to hold cached entries.  It should be set to {{EX:bdb}},
-{{EX:hdb}}, or {{EX:ldbm}}.  The <maxentries> parameter specifies
-the total number of entries which may be held in the cache.  The
-<nattrsets> parameter specifies the total number of attribute sets
-(as specified by the {{EX:proxyAttrSet}} directive) that may be defined.
-The <entrylimit> parameter specifies the maximum number of entries
-in a cachable query.  The <period> specifies the consistency
-check period (in seconds).  In each period, queries with expired
-TTLs are removed.
-
-H3: Defining attribute sets
-
-> proxyAttrset <index> <attrs...>
-
-Used to associate a set of attributes to an index. Each attribute
-set is associated with an index number from 0 to <numattrsets>-1.
-These indices are used by the proxyTemplate directive to define
-cacheable templates.
-
-H3: Specifying cacheable templates 
-
-> proxyTemplate <prototype_string> <attrset_index> <TTL>
-
-Specifies a cacheable template and the "time to live" (in sec) <TTL>
-for queries belonging to the template. A template is described by
-its prototype filter string and set of required attributes identified
-by <attrset_index>.
-
-
-H3: Example
-
-An example {{slapd.conf}}(5) database section for a caching server
-which proxies for the {{EX:"dc=example,dc=com"}} subtree held
-at server {{EX:ldap.example.com}}.
- 
->	database 	ldap
->	suffix 		"dc=example,dc=com" 
->	rootdn 		"dc=example,dc=com" 
->	uri    		ldap://ldap.example.com/dc=example%2cdc=com
->	overlay proxycache
->	proxycache    bdb 100000 1 1000 100
->	proxyAttrset  0 mail postaladdress telephonenumber 
->	proxyTemplate (sn=) 0 3600
->	proxyTemplate (&(sn=)(givenName=)) 0 3600
->	proxyTemplate (&(departmentNumber=)(secretary=*)) 0 3600
->
->	cachesize 20
->	directory ./testrun/db.2.a
->	index       objectClass eq
->	index       cn,sn,uid,mail  pres,eq,sub
-
-
-H4: Cacheable Queries
-
-A LDAP search query is cacheable when its filter matches one of the
-templates as defined in the "proxyTemplate" statements and when it references
-only the attributes specified in the corresponding attribute set. 
-In the example above the attribute set number 0 defines that only the
-attributes: {{EX:mail postaladdress telephonenumber}} are cached for the following
-proxyTemplates.
-
-H4: Examples:
-
->	Filter: (&(sn=Richard*)(givenName=jack)) 
->	Attrs: mail telephoneNumber
-
-    is cacheable, because it matches the template {{EX:(&(sn=)(givenName=))}} and its
-    attributes are contained in proxyAttrset 0.
-
->	Filter: (&(sn=Richard*)(telephoneNumber))
->	Attrs: givenName 
-
-    is not cacheable, because the filter does not match the template,
-    nor is the attribute givenName stored in the cache
-
->	Filter: (|(sn=Richard*)(givenName=jack))
->	Attrs: mail telephoneNumber
-
-    is not cacheable, because the filter does not match the template ( logical
-    OR "|" condition instead of logical AND "&" )
-

Modified: openldap/trunk/doc/guide/admin/quickstart.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/quickstart.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/quickstart.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,33 +1,34 @@
-# $OpenLDAP: pkg/openldap-guide/admin/quickstart.sdf,v 1.43.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/quickstart.sdf,v 1.44.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
 H1: A Quick-Start Guide
 
 The following is a quick start guide to [[DOC_NAME]],
-including the stand-alone LDAP daemon, {{slapd}}(8).
+including the Standalone {{TERM:LDAP}} Daemon, {{slapd}}(8).
 
 It is meant to walk you through the basic steps needed to install
-and configure OpenLDAP Software. It should be used in conjunction
-with the other chapters of this document, manual pages, and other
-materials provided with the distribution (e.g. the {{F:INSTALL}}
-document) or on the OpenLDAP web site (in particular, the OpenLDAP
-Software {{TERM:FAQ}}).
+and configure {{PRD:OpenLDAP Software}}.  It should be used in
+conjunction with the other chapters of this document, manual pages,
+and other materials provided with the distribution (e.g. the
+{{F:INSTALL}} document) or on the {{PRD:OpenLDAP}} web site
+({{URL: http://www.OpenLDAP.org}}), in particular the OpenLDAP
+Software {{TERM:FAQ}} ({{URL: http://www.OpenLDAP.org/faq/?file=2}}).
 
 If you intend to run OpenLDAP Software seriously, you should review
 all of this document before attempting to install the software.
 
 Note: This quick start guide does not use strong authentication
 nor any integrity or confidential protection services.  These
-services are described in other chapters of the OpenLDAP Administrator's
-Guide.
+services are described in other chapters of the
+OpenLDAP Administrator's Guide.
 
 
 .{{S: }}
 ^{{B: Get the software}}
 
 . You can obtain a copy of the software by following the
-instructions on the OpenLDAP download page
+instructions on the OpenLDAP Software download page
 ({{URL: http://www.openldap.org/software/download/}}).  It is
 recommended that new users start with the latest {{release}}.
 
@@ -56,7 +57,7 @@
 {{F:README}} and {{F:INSTALL}} documents provided with the distribution.
 The {{F:COPYRIGHT}} and {{F:LICENSE}} provide information on
 acceptable use, copying, and limitation of warranty of OpenLDAP
-software. 
+Software. 
 
 .{{S: }}
 . You should also review other chapters of this document.
@@ -85,9 +86,9 @@
 
 . Assuming {{EX:configure}} doesn't dislike your system, you can
 proceed with building the software.  If {{EX:configure}} did
-complain, well, you'll likely need to go to the FAQ Installation
-Section ({{URL:http://www.openldap.org/faq/}} and/or actually
-read the {{SECT:Building and Installing OpenLDAP Software}}
+complain, well, you'll likely need to go to the Software FAQ
+{{Installation}} section ({{URL:http://www.openldap.org/faq/?file=8}})
+and/or actually read the {{SECT:Building and Installing OpenLDAP Software}}
 chapter of this document.
 
 
@@ -171,7 +172,7 @@
 .{{S: }}
 +{{B:Start SLAPD}}.
 
-. You are now ready to start the stand-alone LDAP server, {{slapd}}(8),
+. You are now ready to start the Standalone LDAP Daemon, {{slapd}}(8),
 by running the command:
 
 ..{{EX:su root -c /usr/local/libexec/slapd}}
@@ -179,7 +180,7 @@
 
 . To check to see if the server is running and configured correctly,
 you can run a search against it with {{ldapsearch}}(1).  By default,
-ldapsearch is installed as {{F:/usr/local/bin/ldapsearch}}:
+{{ldapsearch}} is installed as {{F:/usr/local/bin/ldapsearch}}:
 
 ..{{EX:ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts}}
 
@@ -198,7 +199,8 @@
 +{{B:Add initial entries to your directory}}.
 
 . You can use {{ldapadd}}(1) to add entries to your LDAP directory.
-{{ldapadd}} expects input in LDIF form. We'll do it in two steps:
+{{ldapadd}} expects input in {{TERM:LDIF}} form.  We'll do it in two
+steps:
 
 ^^ create an LDIF file
 ++ run ldapadd
@@ -269,10 +271,10 @@
 to everybody}} excepting the {{super-user}} (as specified by the
 {{EX:rootdn}} configuration directive).  It is highly recommended
 that you establish controls to restrict access to authorized users.
-Access controls are discussed in the {{SECT:Access Control}} section
-of {{SECT:The slapd Configuration File}} chapter.  You are also
-encouraged to read the {{SECT:Security Considerations}}, {{SECT:Using
-SASL}} and {{SECT:Using TLS}} sections.
+Access controls are discussed in the {{SECT:The access Configuration
+Directive}} section of {{SECT:The slapd Configuration File}} chapter.
+You are also encouraged to read the {{SECT:Security Considerations}},
+{{SECT:Using SASL}} and {{SECT:Using TLS}} sections.
 
 The following chapters provide more detailed information on making,
 installing, and running {{slapd}}(8).

Modified: openldap/trunk/doc/guide/admin/referrals.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/referrals.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/referrals.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/admin/referrals.sdf,v 1.24.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/referrals.sdf,v 1.25.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -51,7 +51,7 @@
 The server uses this information to generate referrals and
 search continuations to subordinate servers.
 
-For those familiar with X.500, a {{named referral}} object is
+For those familiar with {{TERM:X.500}}, a {{named referral}} object is
 similar to an X.500 knowledge reference held in a {{subr}}
 {{TERM:DSE}}.
 
@@ -75,8 +75,8 @@
 The server uses this information to generate referrals to
 management operations.
 
-For those familiar with X.500, this use of the {{EX:ref}} attribute
-is similar to an X.500 knowledge reference held in a
+For those familiar with {{TERM:X.500}}, this use of the {{EX:ref}}
+attribute is similar to an X.500 knowledge reference held in a
 {{immSupr}} {{TERM:DSE}}.
 !endif
 
@@ -99,12 +99,12 @@
 
 >	referral	ldap://a.example.net/
 
-The server uses this information to generate referrals for
-operations acting upon entries not within or subordinate
-to any of the naming contexts held by the server.
+The server uses this information to generate referrals for operations
+acting upon entries not within or subordinate to any of the naming
+contexts held by the server.
 
-For those familiar with X.500, this use of the {{EX:ref}} attribute
-is similar to an X.500 knowledge reference held in a
+For those familiar with {{TERM:X.500}}, this use of the {{EX:ref}}
+attribute is similar to an X.500 knowledge reference held in a
 {{Supr}} {{TERM:DSE}}.
 
 
@@ -132,3 +132,10 @@
 Note: the {{EX:ref}} attribute is operational and must be explicitly
 requested when desired in search results.
 
+Note: the use of referrals to construct a Distributed Directory Service is
+extremely clumsy and not well supported by common clients. If an existing
+installation has already been built using referrals, the use of the
+{{chain}} overlay to hide the referrals will greatly improve the usability
+of the Directory system. A better approach would be to use explicitly
+defined local and proxy databases in {{subordinate}} configurations to
+provide a seamless view of the Distributed Directory.

Copied: openldap/trunk/doc/guide/admin/refint.png (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/refint.png)
===================================================================
(Binary files differ)

Deleted: openldap/trunk/doc/guide/admin/replication.gif
===================================================================
(Binary files differ)

Modified: openldap/trunk/doc/guide/admin/replication.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/replication.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/replication.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,351 +1,716 @@
-# $OpenLDAP: pkg/openldap-guide/admin/replication.sdf,v 1.30.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/replication.sdf,v 1.32.2.9 2007/12/10 15:31:27 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
-H1: Replication with slurpd
 
-In certain configurations, a single {{slapd}}(8) instance may be
-insufficient to handle the number of clients requiring
-directory service via LDAP. It may become necessary to
-run more than one slapd instance.  At many sites,
-for instance, there are multiple slapd servers: one
-master and one or more slaves.  {{TERM:DNS}} can be setup such that
-a lookup of {{EX:ldap.example.com}} returns the {{TERM:IP}} addresses
-of these servers, distributing the load among them (or
-just the slaves). This master/slave arrangement provides
-a simple and effective way to increase capacity, availability
-and reliability.
+H1: Replication
 
-{{slurpd}}(8) provides the capability for a master slapd to
-propagate changes to slave slapd instances,
-implementing the master/slave replication scheme
-described above.  slurpd runs on the same host as the
-master slapd instance.
+Replicated directories are a fundamental requirement for delivering a 
+resilient enterprise deployment.
 
+{{PRD:OpenLDAP}} has various configuration options for creating a replicated 
+directory. The following sections will discuss these.
 
+H2: Replication Strategies
 
-H2: Overview
 
-{{slurpd}}(8) provides replication services "in band". That is, it
-uses the LDAP protocol to update a slave database from
-the master. Perhaps the easiest way to illustrate this is
-with an example. In this example, we trace the propagation
-of an LDAP modify operation from its initiation by the LDAP
-client to its distribution to the slave slapd instance.
+H3: Push Based
 
 
-{{B: Sample replication scenario:}}
+H5: Replacing Slurpd
 
-^ The LDAP client submits an LDAP modify operation to
-the slave slapd.
+{{Slurpd}} replication has been deprecated in favor of Syncrepl replication and 
+has been completely removed from OpenLDAP 2.4.
 
-+ The slave slapd returns a referral to the LDAP
-client referring the client to the master slapd.
+{{Why was it replaced?}}
 
-+ The LDAP client submits the LDAP modify operation to
-the master slapd.
+The {{slurpd}} daemon was the original replication mechanism inherited from 
+UMich's LDAP and operates in push mode: the master pushes changes to the 
+slaves. It has been replaced for many reasons, in brief:
 
-+ The master slapd performs the modify operation,
-writes out the change to its replication log file and returns
-a success code to the client. 
+ * It is not reliable
+ * It is extremely sensitive to the ordering of records in the replog
+ * It can easily go out of sync, at which point manual intervention is 
+   required to resync the slave database with the master directory
+ * It isn't very tolerant of unavailable servers. If a slave goes down 
+   for a long time, the replog may grow to a size that's too large for 
+   slurpd to process
 
-+ The slurpd process notices that a new entry has
-been appended to the replication log file, reads the
-replication log entry, and sends the change to the slave
-slapd via LDAP. 
+{{What was it replaced with?}}
 
-+ The slave slapd performs the modify operation and
-returns a success code to the slurpd process. 
+Syncrepl
 
+{{Why is Syncrepl better?}}
 
-Note: {{ldapmodify}}(1) and other clients distributed as part of
-OpenLDAP Software do not support automatic referral chasing
-(for security reasons).
+ * Syncrepl is self-synchronizing; you can start with a database in any 
+   state from totally empty to fully synced and it will automatically do 
+   the right thing to achieve and maintain synchronization
+ * Syncrepl can operate in either direction
+ * Data updates can be minimal or maximal
 
+{{How do I implement a pushed based replication system using Syncrepl?}}
 
+The easiest way is to point an LDAP backend ({{SECT: Backends}} and {{slapd-ldap(8)}}) 
+to your slave directory and setup Syncrepl to point to your Master database.
 
-H2: Replication Logs
+REFERENCE test045/048 for better explanation of above.
 
-When slapd is configured to generate a replication logfile, it
-writes out a file containing {{TERM:LDIF}} change records.  The
-replication log gives the replication site(s), a timestamp, the DN
-of the entry being modified, and a series of lines which specify
-the changes to make. In the example below, Barbara ({{EX:uid=bjensen}})
-has replaced the {{EX:description}} value.  The change is to be
-propagated to the slapd instance running on {{EX:slave.example.net}}
-Changes to various operational attributes, such as {{EX:modifiersName}}
-and {{EX:modifyTimestamp}}, are included in the change record and
-will be propagated to the slave slapd.
+If you imagine Syncrepl pulling down changes from the Master server, and then
+pushing those changes out to your slave servers via {{slapd-ldap(8)}}. This is 
+called proxy mode (elaborate/confirm?).
 
->	replica: slave.example.com:389
->	time: 809618633
->	dn: uid=bjensen,dc=example,dc=com
->	changetype: modify
->	replace: multiLineDescription
->	description: A dreamer...
->	-
->	replace: modifiersName
->	modifiersName: uid=bjensen,dc=example,dc=com
->	-
->	replace: modifyTimestamp
->	modifyTimestamp: 20000805073308Z
->	-
+DIAGRAM HERE
 
-The modifications to {{EX:modifiersName}} and {{EX:modifyTimestamp}}
-operational attributes were added by the master {{slapd}}.
+BETTER EXAMPLE here from test045/048 for different push/multiproxy examples.
 
+Here's an example:
 
 
-H2: Command-Line Options
+>	include		./schema/core.schema
+>	include		./schema/cosine.schema
+>	include		./schema/inetorgperson.schema
+>	include		./schema/openldap.schema
+>	include		./schema/nis.schema
+>	
+>	pidfile		/home/ghenry/openldap/ldap/tests/testrun/slapd.3.pid
+>	argsfile	/home/ghenry/openldap/ldap/tests/testrun/slapd.3.args
+>	
+>	modulepath	../servers/slapd/back-bdb/
+>	moduleload	back_bdb.la
+>	modulepath  ../servers/slapd/back-monitor/
+>	moduleload  back_monitor.la
+>	modulepath  ../servers/slapd/overlays/
+>	moduleload  syncprov.la
+>	modulepath  ../servers/slapd/back-ldap/
+>	moduleload  back_ldap.la
+>	
+>	# We don't need any access to this DSA
+>	restrict	all
+>	
+>	#######################################################################
+>	# consumer proxy database definitions
+>	#######################################################################
+>	
+>	database	ldap
+>	suffix		"dc=example,dc=com"
+>	rootdn		"cn=Whoever"
+>	uri		ldap://localhost:9012/
+>	
+>	lastmod		on
+>	
+>	# HACK: use the RootDN of the monitor database as UpdateDN so ACLs apply
+>	# without the need to write the UpdateDN before starting replication
+>	acl-bind	bindmethod=simple
+>			binddn="cn=Monitor"
+>			credentials=monitor
+>	
+>	# HACK: use the RootDN of the monitor database as UpdateDN so ACLs apply
+>	# without the need to write the UpdateDN before starting replication
+>	syncrepl	rid=1
+>			provider=ldap://localhost:9011/
+>			binddn="cn=Manager,dc=example,dc=com"
+>			bindmethod=simple
+>			credentials=secret
+>			searchbase="dc=example,dc=com"
+>			filter="(objectClass=*)"
+>			attrs="*,structuralObjectClass,entryUUID,entryCSN,creatorsName,createTimestamp,modifiersName,modifyTimestamp"
+>			schemachecking=off
+>			scope=sub
+>			type=refreshAndPersist
+>			retry="5 5 300 5"
+>	
+>	overlay		syncprov
+>	
+>	database	monitor
 
-This section details commonly used {{slurpd}}(8) command-line options.
+DETAILED EXPLANATION OF ABOVE LIKE IN OTHER SECTIONS (line numbers?)
 
->	-d <level> | ?
 
-This option sets the slurpd debug level to {{EX: <level>}}. When
-level is a `?' character, the various debugging levels are printed
-and slurpd exits, regardless of any other options you give it.
-Current debugging levels (a subset of slapd's debugging levels) are
+ANOTHER DIAGRAM HERE
 
-!block table; colaligns="RL"; align=Center; \
-	title="Table 13.1: Debugging Levels"
-Level	Description
-4	heavy trace debugging
-64	configuration file processing
-65535	enable all debugging
-!endblock
+As you can see, you can let your imagination go wild using Syncrepl and 
+{{slapd-ldap(8)}} tailoring your replication to fit your specific network 
+topology.
 
-Debugging levels are additive. That is, if you want heavy trace
-debugging and want to watch the config file being processed, you
-would set level to the sum of those two levels (in this case, 68).
+H3: Pull Based
 
->	-f <filename>
 
-This option specifies an alternate slapd configuration file.  Slurpd
-does not have its own configuration file. Instead, all configuration
-information is read from the slapd configuration file.
+H4: syncrepl replication
 
->	-r <filename>
 
-This option specifies an alternate slapd replication log file.
-Under normal circumstances, slurpd reads the name of the slapd
-replication log file from the slapd configuration file. However,
-you can override this with the -r flag, to cause slurpd to process
-a different replication log file. See the {{SECT:Advanced slurpd
-Operation}} section for a discussion of how you might use this
-option.
+H4: delta-syncrepl replication
 
->	-o
 
-Operate in "one-shot" mode. Under normal circumstances, when slurpd
-finishes processing a replication log, it remains active and
-periodically checks to see if new entries have been added to the
-replication log.  In one-shot mode, by comparison, slurpd processes
-a replication log and exits immediately. If the -o option is given,
-the replication log file must be explicitly specified with the -r
-option.  See the {{SECT:One-shot mode and reject files}} section
-for  a discussion of this mode.
+H2: Replication Types
 
->	-t <directory>
 
-Specify an alternate directory for slurpd's temporary copies of
-replication logs. The default location is {{F:/usr/tmp}}.
+H3: syncrepl replication
 
 
-H2: Configuring slurpd and a slave slapd instance
+H3: delta-syncrepl replication
 
-To bring up a replica slapd instance, you must configure the master
-and slave slapd instances for replication, then shut down the master
-slapd so you can copy the database. Finally, you bring up the master
-slapd instance, the slave slapd instance, and the slurpd instance.
-These steps are detailed in the following sections. You can set up
-as many slave slapd instances as you wish.
 
+H3: N-Way Multi-Master replication
 
-H3: Set up the master {{slapd}}
+Multi-Master replication is a replication technique using Syncrepl to replicate 
+data to multiple Master Directory servers. 
 
-The following section assumes you have a properly working {{slapd}}(8)
-instance. To configure your working {{slapd}}(8) server as a
-replication master, you need to make the following changes to your
-{{slapd.conf}}(5).
+* Advantages of Multi-Master replication:
 
-^ Add a {{EX:replica}} directive for each replica. The {{EX:binddn=}}
-parameter should match the {{EX:updatedn}} option in the corresponding
-slave slapd configuration file, and should name an entry with write
-permission to the slave database (e.g., an entry allowed access via
-{{EX:access}} directives in the slave slapd configuration file).
-This DN generally {{should not}} be the same as the master's
-{{EX:rootdn}}.
+- If any master fails, other masters will continue to accept updates
+- Avoids a single point of failure
+- Masters can be located in several physical sites i.e. distributed across the 
+network/globe.
+- Good for Automatic failover/High Availability
 
-+ Add a {{EX:replogfile}} directive, which tells slapd where to log
-changes. This file will be read by slurpd.
+* Disadvantages of Multi-Master replication:
 
+- It has {{B:NOTHING}} to do with load balancing
+- {{URL:http://www.openldap.org/faq/data/cache/1240.html}}
+- If connectivity with a master is lost because of a network partition, then 
+"automatic failover" can just compound the problem
+- Typically, a particular machine cannot distinguish between losing contact
+ with a peer because that peer crashed, or because the network link has failed
+- If a network is partitioned and multiple clients start writing to each of the 
+"masters" then reconciliation will be a pain; it may be best to simply deny 
+writes to the clients that are partitioned from the single master
+- Masters {{B:must}} propagate writes to {{B:all}} the other servers, which 
+means the network traffic and write load is constant and spreads across all 
+of the servers
 
-H3: Set up the slave {{slapd}}
 
-Install the slapd software on the host which is to be the slave
-slapd server. The configuration of the slave server should be
-identical to that of the master, with the following exceptions:
+This is discussed in full in the {{SECT:N-Way Multi-Master}} section below
 
-^ Do not include a {{EX:replica}} directive. While it is possible
-to create "chains" of replicas, in most cases this is inappropriate.
+H3: MirrorMode replication
 
-+ Do not include a {{EX:replogfile}} directive.
+MirrorMode is a hybrid configuration that provides all of the consistency
+guarantees of single-master replication, while also providing the high
+availability of multi-master. In MirrorMode two masters are set up to
+replicate from each other (as a multi-master configuration) but an
+external frontend is employed to direct all writes to only one of
+the two servers. The second master will only be used for writes if
+the first master crashes, at which point the frontend will switch to
+directing all writes to the second master. When a crashed master is
+repaired and restarted it will automatically catch up to any changes
+on the running master and resync.
 
-+ Do include an {{EX:updatedn}} line. The DN given should match the
-DN given in the {{EX:binddn=}} parameter of the corresponding
-{{EX:replica=}} directive in the master slapd config file.  The
-{{EX:updatedn}} generally {{should not}} be the same as the
-{{EX:rootdn}} of the master database.
+This is discussed in full in the {{SECT:MirrorMode}} section below
 
-+ Make sure the DN given in the {{EX:updatedn}} directive has
-permission to write the database (e.g., it is is allowed {{EX:access}}
-by one or more access directives).
+H2: LDAP Sync Replication
 
-+ Use the {{EX:updateref}} directive to define the URL the slave
-should return if an update request is received.
+The {{TERM:LDAP Sync}} Replication engine, {{TERM:syncrepl}} for
+short, is a consumer-side replication engine that enables the
+consumer {{TERM:LDAP}} server to maintain a shadow copy of a
+{{TERM:DIT}} fragment. A syncrepl engine resides at the consumer-side
+as one of the {{slapd}}(8) threads. It creates and maintains a
+consumer replica by connecting to the replication provider to perform
+the initial DIT content load followed either by periodic content
+polling or by timely updates upon content changes.
 
+Syncrepl uses the LDAP Content Synchronization (or LDAP Sync for
+short) protocol as the replica synchronization protocol.  It provides
+a stateful replication which supports both pull-based and push-based
+synchronization and does not mandate the use of a history store.
 
-H3: Shut down the master server
+Syncrepl keeps track of the status of the replication content by
+maintaining and exchanging synchronization cookies. Because the
+syncrepl consumer and provider maintain their content status, the
+consumer can poll the provider content to perform incremental
+synchronization by asking for the entries required to make the
+consumer replica up-to-date with the provider content. Syncrepl
+also enables convenient management of replicas by maintaining replica
+status.  The consumer replica can be constructed from a consumer-side
+or a provider-side backup at any synchronization status. Syncrepl
+can automatically resynchronize the consumer replica up-to-date
+with the current provider content.
 
-In order to ensure that the slave starts with an exact copy of the
-master's data, you must shut down the master slapd. Do this by
-sending the master slapd process an interrupt signal with
-{{EX:kill -INT <pid>}}, where {{EX:<pid>}} is the process-id of the master
-slapd process.
+Syncrepl supports both pull-based and push-based synchronization.
+In its basic refreshOnly synchronization mode, the provider uses
+pull-based synchronization where the consumer servers need not be
+tracked and no history information is maintained.  The information
+required for the provider to process periodic polling requests is
+contained in the synchronization cookie of the request itself.  To
+optimize the pull-based synchronization, syncrepl utilizes the
+present phase of the LDAP Sync protocol as well as its delete phase,
+instead of falling back on frequent full reloads. To further optimize
+the pull-based synchronization, the provider can maintain a per-scope
+session log as a history store. In its refreshAndPersist mode of
+synchronization, the provider uses a push-based synchronization.
+The provider keeps track of the consumer servers that have requested
+a persistent search and sends them necessary updates as the provider
+replication content gets modified.
 
-If you like, you may restart the master slapd in read-only mode
-while you are replicating the database. During this time, the master
-slapd will return an "unwilling to perform" error to clients that
-attempt to modify data.
+With syncrepl, a consumer server can create a replica without
+changing the provider's configurations and without restarting the
+provider server, if the consumer server has appropriate access
+privileges for the DIT fragment to be replicated. The consumer
+server can stop the replication also without the need for provider-side
+changes and restart.
 
+Syncrepl supports both partial and sparse replications.  The shadow
+DIT fragment is defined by a general search criteria consisting of
+base, scope, filter, and attribute list.  The replica content is
+also subject to the access privileges of the bind identity of the
+syncrepl replication connection.
 
-H3: Copy the master slapd's database to the slave
 
-Copy the master's database(s) to the slave. For an {{TERM:BDB}} and
-{{TERM:LDBM}} databases, you must copy all database files located
-in the database {{EX:directory}} specified in {{slapd.conf}}(5).
-In general, you should copy each file found in the database {{EX:
-directory}} unless you know it is not used by {{slapd}}(8).
+H3: The LDAP Content Synchronization Protocol
 
-Note: This copy process assumes homogeneous servers with identically
-configured OpenLDAP installations. Alternatively, you may use
-{{slapcat}} to output the master's database in LDIF format and use
-the LDIF with {{slapadd}} to populate the slave. Using LDIF avoids
-any potential incompatibilities due to differing server architectures
-or software configurations.  See the {{SECT:Database Creation and
-Maintenance Tools}} chapter for details on these tools.
+The LDAP Sync protocol allows a client to maintain a synchronized
+copy of a DIT fragment. The LDAP Sync operation is defined as a set
+of controls and other protocol elements which extend the LDAP search
+operation. This section introduces the LDAP Content Sync protocol
+only briefly.  For more information, refer to {{REF:RFC4533}}.
 
+The LDAP Sync protocol supports both polling and listening for
+changes by defining two respective synchronization operations:
+{{refreshOnly}} and {{refreshAndPersist}}.  Polling is implemented
+by the {{refreshOnly}} operation.  The client copy is synchronized
+to the server copy at the time of polling.  The server finishes the
+search operation by returning {{SearchResultDone}} at the end of
+the search operation as in the normal search.  The listening is
+implemented by the {{refreshAndPersist}} operation.  Instead of
+finishing the search after returning all entries currently matching
+the search criteria, the synchronization search remains persistent
+in the server. Subsequent updates to the synchronization content
+in the server cause additional entry updates to be sent to the
+client.
 
-H3: Configure the master slapd for replication
+The {{refreshOnly}} operation and the refresh stage of the
+{{refreshAndPersist}} operation can be performed with a present
+phase or a delete phase.
 
-To configure slapd to generate a replication logfile, you add a
-"{{EX: replica}}" configuration option to the master slapd's config
-file. For example, if we wish to propagate changes to the slapd
-instance running on host {{EX:slave.example.com}}:
+In the present phase, the server sends the client the entries updated
+within the search scope since the last synchronization. The server
+sends all requested attributes, be it changed or not, of the updated
+entries.  For each unchanged entry which remains in the scope, the
+server sends a present message consisting only of the name of the
+entry and the synchronization control representing state present.
+The present message does not contain any attributes of the entry.
+After the client receives all update and present entries, it can
+reliably determine the new client copy by adding the entries added
+to the server, by replacing the entries modified at the server, and
+by deleting entries in the client copy which have not been updated
+nor specified as being present at the server.
 
->	replica uri=ldap://slave.example.com:389
->		binddn="cn=Replicator,dc=example,dc=com"
->		bindmethod=simple credentials=secret
+The transmission of the updated entries in the delete phase is the
+same as in the present phase. The server sends all the requested
+attributes of the entries updated within the search scope since the
+last synchronization to the client. In the delete phase, however,
+the server sends a delete message for each entry deleted from the
+search scope, instead of sending present messages.  The delete
+message consists only of the name of the entry and the synchronization
+control representing state delete.  The new client copy can be
+determined by adding, modifying, and removing entries according to
+the synchronization control attached to the {{SearchResultEntry}}
+message.
 
-In this example, changes will be sent to port 389 (the standard
-LDAP port) on host slave.example.com. The slurpd process will bind
-to the slave slapd as "{{EX:cn=Replicator,dc=example,dc=com}}" using
-simple authentication with password "{{EX:secret}}".
+In the case that the LDAP Sync server maintains a history store and
+can determine which entries are scoped out of the client copy since
+the last synchronization time, the server can use the delete phase.
+If the server does not maintain any history store, cannot determine
+the scoped-out entries from the history store, or the history store
+does not cover the outdated synchronization state of the client,
+the server should use the present phase.  The use of the present
+phase is much more efficient than a full content reload in terms
+of the synchronization traffic.  To reduce the synchronization
+traffic further, the LDAP Sync protocol also provides several
+optimizations such as the transmission of the normalized {{EX:entryUUID}}s
+and the transmission of multiple {{EX:entryUUIDs}} in a single
+{{syncIdSet}} message.
 
-If we wish to perform the same replication using ldaps on port 636:  
+At the end of the {{refreshOnly}} synchronization, the server sends
+a synchronization cookie to the client as a state indicator of the
+client copy after the synchronization is completed.  The client
+will present the received cookie when it requests the next incremental
+synchronization to the server.
 
->	replica uri=ldaps://slave.example.com:636
->		binddn="cn=Replicator,dc=example,dc=com"
->		bindmethod=simple credentials=secret
+When {{refreshAndPersist}} synchronization is used, the server sends
+a synchronization cookie at the end of the refresh stage by sending
+a Sync Info message with TRUE refreshDone.  It also sends a
+synchronization cookie by attaching it to {{SearchResultEntry}}
+generated in the persist stage of the synchronization search. During
+the persist stage, the server can also send a Sync Info message
+containing the synchronization cookie at any time the server wants
+to update the client-side state indicator.  The server also updates
+a synchronization indicator of the client at the end of the persist
+stage.
 
-The host option is deprecated in favor of uri, but the following 
-replica configuration is still supported:
+In the LDAP Sync protocol, entries are uniquely identified by the
+{{EX:entryUUID}} attribute value. It can function as a reliable
+identifier of the entry. The DN of the entry, on the other hand,
+can be changed over time and hence cannot be considered as the
+reliable identifier.  The {{EX:entryUUID}} is attached to each
+{{SearchResultEntry}} or {{SearchResultReference}} as a part of the
+synchronization control.
 
->	replica host=slave.example.com:389
->		binddn="cn=Replicator,dc=example,dc=com"
->		bindmethod=simple credentials=secret
 
-Note that the DN given by the {{EX:binddn=}} directive must exist
-in the slave slapd's database (or be the rootdn specified in the
-slapd config file) in order for the bind operation to succeed.  The
-DN should also be listed as the {{EX:updatedn}} for the database
-in the slave's slapd.conf(5).  It is generally recommended that
-this DN be different than the {{EX:rootdn}} of the master database.
+H3: Syncrepl Details
 
-Note: The use of strong authentication and transport security is
-highly recommended.
+The syncrepl engine utilizes both the {{refreshOnly}} and the
+{{refreshAndPersist}} operations of the LDAP Sync protocol.  If a
+syncrepl specification is included in a database definition,
+{{slapd}}(8) launches a syncrepl engine as a {{slapd}}(8) thread
+and schedules its execution. If the {{refreshOnly}} operation is
+specified, the syncrepl engine will be rescheduled at the interval
+time after a synchronization operation is completed.  If the
+{{refreshAndPersist}} operation is specified, the engine will remain
+active and process the persistent synchronization messages from the
+provider.
 
+The syncrepl engine utilizes both the present phase and the delete
+phase of the refresh synchronization. It is possible to configure
+a per-scope session log in the provider server which stores the
+{{EX:entryUUID}}s of a finite number of entries deleted from a
+replication content.  Multiple replicas of single provider content
+share the same per-scope session log. The syncrepl engine uses the
+delete phase if the session log is present and the state of the
+consumer server is recent enough that no session log entries are
+truncated after the last synchronization of the client.  The syncrepl
+engine uses the present phase if no session log is configured for
+the replication content or if the consumer replica is too outdated
+to be covered by the session log.  The current design of the session
+log store is memory based, so the information contained in the
+session log is not persistent over multiple provider invocations.
+It is not currently supported to access the session log store by
+using LDAP operations. It is also not currently supported to impose
+access control to the session log.
 
-H3: Restart the master slapd and start the slave slapd
+As a further optimization, even in the case the synchronization
+search is not associated with any session log, no entries will be
+transmitted to the consumer server when there has been no update
+in the replication context.
 
-Restart the master slapd process. To check that it is
-generating replication logs, perform a modification of any
-entry in the database, and check that data has been
-written to the log file.
+The syncrepl engine, which is a consumer-side replication engine,
+can work with any backends. The LDAP Sync provider can be configured
+as an overlay on any backend, but works best with the {{back-bdb}}
+or {{back-hdb}} backend.
 
+The LDAP Sync provider maintains a {{EX:contextCSN}} for each
+database as the current synchronization state indicator of the
+provider content.  It is the largest {{EX:entryCSN}} in the provider
+context such that no transactions for an entry having smaller
+{{EX:entryCSN}} value remains outstanding.  The {{EX:contextCSN}}
+could not just be set to the largest issued {{EX:entryCSN}} because
+{{EX:entryCSN}} is obtained before a transaction starts and
+transactions are not committed in the issue order.
 
-H3: Start slurpd
+The provider stores the {{EX:contextCSN}} of a context in the
+{{EX:contextCSN}} attribute of the context suffix entry. The attribute
+is not written to the database after every update operation though;
+instead it is maintained primarily in memory. At database start
+time the provider reads the last saved {{EX:contextCSN}} into memory
+and uses the in-memory copy exclusively thereafter. By default,
+changes to the {{EX:contextCSN}} as a result of database updates
+will not be written to the database until the server is cleanly
+shut down. A checkpoint facility exists to cause the contextCSN to
+be written out more frequently if desired.
 
-Start the slurpd process. Slurpd should immediately send
-the test modification you made to the slave slapd. Watch
-the slave slapd's logfile to be sure that the modification
-was sent.
+Note that at startup time, if the provider is unable to read a
+{{EX:contextCSN}} from the suffix entry, it will scan the entire
+database to determine the value, and this scan may take quite a
+long time on a large database. When a {{EX:contextCSN}} value is
+read, the database will still be scanned for any {{EX:entryCSN}}
+values greater than it, to make sure the {{EX:contextCSN}} value
+truly reflects the greatest committed {{EX:entryCSN}} in the database.
+On databases which support inequality indexing, setting an eq index
+on the {{EX:entryCSN}} attribute and configuring {{contextCSN}}
+checkpoints will greatly speed up this scanning step.
 
->	slurpd -f <masterslapdconfigfile>
+If no {{EX:contextCSN}} can be determined by reading and scanning
+the database, a new value will be generated. Also, if scanning the
+database yielded a greater {{EX:entryCSN}} than was previously
+recorded in the suffix entry's {{EX:contextCSN}} attribute, a
+checkpoint will be immediately written with the new value.
 
+The consumer also stores its replica state, which is the provider's
+{{EX:contextCSN}} received as a synchronization cookie, in the
+{{EX:contextCSN}} attribute of the suffix entry.  The replica state
+maintained by a consumer server is used as the synchronization state
+indicator when it performs subsequent incremental synchronization
+with the provider server. It is also used as a provider-side
+synchronization state indicator when it functions as a secondary
+provider server in a cascading replication configuration.  Since
+the consumer and provider state information are maintained in the
+same location within their respective databases, any consumer can
+be promoted to a provider (and vice versa) without any special
+actions.
 
+Because a general search filter can be used in the syncrepl
+specification, some entries in the context may be omitted from the
+synchronization content.  The syncrepl engine creates a glue entry
+to fill in the holes in the replica context if any part of the
+replica content is subordinate to the holes. The glue entries will
+not be returned in the search result unless {{ManageDsaIT}} control
+is provided.
 
-H2: Advanced slurpd Operation
+Also as a consequence of the search filter used in the syncrepl
+specification, it is possible for a modification to remove an entry
+from the replication scope even though the entry has not been deleted
+on the provider. Logically the entry must be deleted on the consumer
+but in {{refreshOnly}} mode the provider cannot detect and propagate
+this change without the use of the session log.
 
-H3: Replication errors
 
-When slurpd propagates a change to a slave slapd and receives an
-error return code, it writes the reason for the error and the
-replication record to a reject file. The reject file is located in
-the same directory as the per-replica replication logfile, and has
-the same name, but with the string "{{F:.rej}}" appended. For
-example, for a replica running on host {{EX:slave.example.com}},
-port 389, the reject file, if it exists, will be named
+H3: Configuring Syncrepl
 
->	/usr/local/var/openldap/replog.slave.example.com:389.rej
+Because syncrepl is a consumer-side replication engine, the syncrepl
+specification is defined in {{slapd.conf}}(5) of the consumer
+server, not in the provider server's configuration file.  The initial
+loading of the replica content can be performed either by starting
+the syncrepl engine with no synchronization cookie or by populating
+the consumer replica by adding an {{TERM:LDIF}} file dumped as a
+backup at the provider.
 
-A sample rejection log entry follows:
+When loading from a backup, it is not required to perform the initial
+loading from the up-to-date backup of the provider content. The
+syncrepl engine will automatically synchronize the initial consumer
+replica to the current provider content. As a result, it is not
+required to stop the provider server in order to avoid the replica
+inconsistency caused by the updates to the provider content during
+the content backup and loading process.
 
->	ERROR: No such attribute
->	replica: slave.example.com:389
->	time: 809618633
->	dn: uid=bjensen,dc=example,dc=com
->	changetype: modify
->	replace: description
->	description: A dreamer...
->	-
->	replace: modifiersName
->	modifiersName: uid=bjensen,dc=example,dc=com
->	-
->	replace: modifyTimestamp
->	modifyTimestamp: 20000805073308Z
->	-
+When replicating a large scale directory, especially in a bandwidth
+constrained environment, it is advised to load the consumer replica
+from a backup instead of performing a full initial load using
+syncrepl.
 
-Note that this is precisely the same format as the original replication
-log entry, but with an {{EX:ERROR}} line prepended to the entry.
 
+H4: Set up the provider slapd
 
+The provider is implemented as an overlay, so the overlay itself
+must first be configured in {{slapd.conf}}(5) before it can be
+used. The provider has only two configuration directives, for setting
+checkpoints on the {{EX:contextCSN}} and for configuring the session
+log.  Because the LDAP Sync search is subject to access control,
+proper access control privileges should be set up for the replicated
+content.
 
-H3: One-shot mode and reject files
+The {{EX:contextCSN}} checkpoint is configured by the
 
-It is possible to use slurpd to process a rejection log with its
-"one-shot mode." In normal operation, slurpd watches for more
-replication records to be appended to the replication log file. In
-one-shot mode, by contrast, slurpd processes a single log file and
-exits. Slurpd ignores {{EX:ERROR}} lines at the beginning of
-replication log entries, so it's not necessary to edit them out
-before feeding it the rejection log.
+>	syncprov-checkpoint <ops> <minutes>
 
-To use one-shot mode, specify the name of the rejection log on the
-command line as the argument to the -r flag, and specify one-shot
-mode with the -o flag. For example, to process the rejection log
-file {{F:/usr/local/var/openldap/replog.slave.example.com:389}} and
-exit, use the command
+directive. Checkpoints are only tested after successful write
+operations.  If {{<ops>}} operations or more than {{<minutes>}}
+time has passed since the last checkpoint, a new checkpoint is
+performed.
 
->	slurpd -r /usr/tmp/replog.slave.example.com:389 -o
+The session log is configured by the
 
+>	syncprov-sessionlog <size>
+
+directive, where {{<size>}} is the maximum number of session log
+entries the session log can record. When a session log is configured,
+it is automatically used for all LDAP Sync searches within the
+database.
+
+Note that using the session log requires searching on the {{entryUUID}}
+attribute. Setting an eq index on this attribute will greatly benefit
+the performance of the session log on the provider.
+
+A more complete example of the {{slapd.conf}}(5) content is thus:
+
+>	database bdb
+>	suffix dc=Example,dc=com
+>	rootdn dc=Example,dc=com
+>	directory /var/ldap/db
+>	index objectclass,entryCSN,entryUUID eq
+>
+>	overlay syncprov
+>	syncprov-checkpoint 100 10
+>	syncprov-sessionlog 100
+
+
+H4: Set up the consumer slapd
+
+The syncrepl replication is specified in the database section of
+{{slapd.conf}}(5) for the replica context.  The syncrepl engine
+is backend independent and the directive can be defined with any
+database type.
+
+>	database hdb
+>	suffix dc=Example,dc=com
+>	rootdn dc=Example,dc=com
+>	directory /var/ldap/db
+>	index objectclass,entryCSN,entryUUID eq
+>
+>	syncrepl rid=123
+>		provider=ldap://provider.example.com:389
+>		type=refreshOnly
+>		interval=01:00:00:00
+>		searchbase="dc=example,dc=com"
+>		filter="(objectClass=organizationalPerson)"
+>		scope=sub
+>		attrs="cn,sn,ou,telephoneNumber,title,l"
+>		schemachecking=off
+>		bindmethod=simple
+>		binddn="cn=syncuser,dc=example,dc=com"
+>		credentials=secret
+
+In this example, the consumer will connect to the provider {{slapd}}(8)
+at port 389 of {{FILE:ldap://provider.example.com}} to perform a
+polling ({{refreshOnly}}) mode of synchronization once a day.  It
+will bind as {{EX:cn=syncuser,dc=example,dc=com}} using simple
+authentication with password "secret".  Note that the access control
+privilege of {{EX:cn=syncuser,dc=example,dc=com}} should be set
+appropriately in the provider to retrieve the desired replication
+content. Also the search limits must be high enough on the provider
+to allow the syncuser to retrieve a complete copy of the requested
+content.  The consumer uses the rootdn to write to its database so
+it always has full permissions to write all content.
+
+The synchronization search in the above example will search for the
+entries whose objectClass is organizationalPerson in the entire
+subtree rooted at {{EX:dc=example,dc=com}}. The requested attributes
+are {{EX:cn}}, {{EX:sn}}, {{EX:ou}}, {{EX:telephoneNumber}},
+{{EX:title}}, and {{EX:l}}. The schema checking is turned off, so
+that the consumer {{slapd}}(8) will not enforce entry schema
+checking when it process updates from the provider {{slapd}}(8).
+
+For more detailed information on the syncrepl directive, see the
+{{SECT:syncrepl}} section of {{SECT:The slapd Configuration File}}
+chapter of this admin guide.
+
+
+H4: Start the provider and the consumer slapd
+
+The provider {{slapd}}(8) is not required to be restarted.
+{{contextCSN}} is automatically generated as needed: it might be
+originally contained in the {{TERM:LDIF}} file, generated by
+{{slapadd}} (8), generated upon changes in the context, or generated
+when the first LDAP Sync search arrives at the provider.  If an
+LDIF file is being loaded which did not previously contain the
+{{contextCSN}}, the {{-w}} option should be used with {{slapadd}}
+(8) to cause it to be generated. This will allow the server to
+startup a little quicker the first time it runs.
+
+When starting a consumer {{slapd}}(8), it is possible to provide
+a synchronization cookie as the {{-c cookie}} command line option
+in order to start the synchronization from a specific state.  The
+cookie is a comma separated list of name=value pairs. Currently
+supported syncrepl cookie fields are {{csn=<csn>}} and {{rid=<rid>}}.
+{{<csn>}} represents the current synchronization state of the
+consumer replica.  {{<rid>}} identifies a consumer replica locally
+within the consumer server. It is used to relate the cookie to the
+syncrepl definition in {{slapd.conf}}(5) which has the matching
+replica identifier.  The {{<rid>}} must have no more than 3 decimal
+digits.  The command line cookie overrides the synchronization
+cookie stored in the consumer replica database.
+
+
+H2: N-Way Multi-Master
+
+Import and expand from link:
+
+{{URL:http://blog.suretecsystems.com/archives/40-OpenLDAP-Weekly-News-Issue-5.html#extended}}
+
+H2: MirrorMode
+
+H3: Arguments for MirrorMode
+
+* Provides a high-availability (HA) solution for directory writes (replicas handle reads)
+* As long as one Master is operational, writes can safely be accepted
+* Master nodes replicate from each other, so they are always up to date and
+can be ready to take over (hot standby)
+* Syncrepl also allows the master nodes to re-synchronize after any downtime
+* Delta-Syncrepl can be used
+
+
+H3: Arguments against MirrorMode
+
+* MirrorMode is not what is termed as a Multi-Master solution. This is because 
+writes have to go to one of the mirror nodes at a time
+* MirrorMode can be termed as Active-Active Hot-Standby, therefor an external 
+server (slapd in proxy mode) or device (hardware load balancer) to manage which 
+master is currently active
+* While syncrepl can recover from a completely empty database, slapadd is much 
+faster
+* Does not provide faster or more scalable write performance (neither could 
+  any Multi-Master solution)
+* Backups are managed slightly differently
+- If backing up the Berkeley database itself and periodically backing up the 
+transaction log files, then the same member of the mirror pair needs to be 
+used to collect logfiles until the next database backup is taken 
+- To ensure that both databases are consistent, each database might have to be 
+put in read-only mode while performing a slapcat. 
+- When using slapcat, the generated LDIF files can be rather large. This can 
+happen with a non-MirrorMode deployment also.
+
+H3: MirrorMode Configuration
+
+MirrorMode configuration is actually very easy. If you have ever setup a normal
+slapd syncrepl provider, then the only change is the following two directives:
+
+>       mirrormode  on
+>       serverID    1
+
+Note: You need to make sure that the {{serverID}} of each mirror node pair is 
+different and that the {{provider}} syncrepl directive points to the opposite 
+mirror node.
+
+H4: Mirror Node Configuration
+
+This is the same as the {{SECT:Set up the provider slapd}} section, reference
+{{SECT:delta-syncrepl replication}} if using {{delta-syncrepl}}.
+
+Here's a specific cut down example using {{SECT:LDAP Sync Replication}} in
+{{refreshAndPersist}} mode ({{delta-syncrepl}} can be used also):
+
+MirrorMode node 1:
+
+>       # syncrepl directives    
+>       syncrepl      rid=1
+>                     provider=ldap://ldap-rid2.example.com
+>                     bindmethod=simple
+>                     binddn="cn=mirrormode,dc=example,dc=com"
+>                     credentials=mirrormode
+>                     searchbase="dc=example,dc=com"
+>                     schemachecking=on
+>                     type=refreshAndPersist
+>                     retry="60 +"
+>       
+>       mirrormode on
+>       serverID    1
+
+MirrorMode node 2:
+
+>       # syncrepl directives
+>       syncrepl      rid=1
+>                     provider=ldap://ldap-rid1.example.com
+>                     bindmethod=simple
+>                     binddn="cn=mirrormode,dc=example,dc=com"
+>                     credentials=mirrormode
+>                     searchbase="dc=example,dc=com"
+>                     schemachecking=on
+>                     type=refreshAndPersist
+>                     retry="60 +"
+>       
+>       mirrormode on
+>       serverID    2
+
+It's simple really; each MirrorMode node is setup {{B:exactly}} the same, except
+that the {{B:provider}} directive is set to point to the other MirrorMode node
+and the {{serverID}} is unique.
+
+H4: Failover Configuration
+
+There are generally 2 choices for this; 1.  Hardware proxies/load-balancing or 
+dedicated proxy software, 2. using a Back-LDAP proxy as a syncrepl provider
+
+A typical enterprise example might be:
+
+!import "dual_dc.png"; align="center"; title="MirrorMode Enterprise Configuration"
+FT[align="Center"] Figure X.Y: MirrorMode in a Dual Data Center Configuration
+
+H4: Normal Consumer Configuration
+
+This is exactly the same as the {{SECT:Set up the consumer slapd}} section. It
+can either setup in normal {{SECT:syncrepl replication}} mode, or in 
+{{SECT:delta-syncrepl replication}} mode.
+
+H3: MirrorMode Summary
+
+Hopefully you will now have a directory architecture that provides all of the 
+consistency guarantees of single-master replication, whilst also providing the 
+high availability of multi-master replication.
+
+

Modified: openldap/trunk/doc/guide/admin/runningslapd.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/runningslapd.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/runningslapd.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,12 +1,12 @@
-# $OpenLDAP: pkg/openldap-guide/admin/runningslapd.sdf,v 1.15.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/runningslapd.sdf,v 1.16.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 H1: Running slapd
 
-{{slapd}}(8) is designed to be run as a stand-alone server.  This allows
-the server to take advantage of caching, manage concurrency issues
-with underlying databases, and conserve system resources.  Running
-from {{inetd}}(8) is {{NOT}} an option.
+{{slapd}}(8) is designed to be run as a standalone service.  This
+allows the server to take advantage of caching, manage concurrency
+issues with underlying databases, and conserve system resources.
+Running from {{inetd}}(8) is {{NOT}} an option.
 
 
 H2: Command-Line Options
@@ -19,24 +19,36 @@
 This option specifies an alternate configuration file for slapd.
 The default is normally {{F:/usr/local/etc/openldap/slapd.conf}}.
 
+>	-F <slapd-config-directory>
+
+Specifies the slapd configuration directory. The default is {{F:/usr/local/etc/openldap/slapd.d}}
+
+If both {{EX:-f}} and {{EX:-F}} are specified, the config file will be read and converted 
+to config directory format and written to the specified directory.  
+If neither option is specified, slapd will attempt to read the default config 
+directory before trying to use the default config file. If a valid config 
+directory exists then the default config file is ignored. All of the slap tools 
+that use the config options observe this same behavior.
+
 >	-h <URLs>
 
 This option specifies alternative listener configurations.  The
-default is {{EX:ldap:///}} which implies LDAP over TCP on all
-interfaces on the default LDAP port 389.  You can specify
-specific host-port pairs or other protocol schemes (such as
-ldaps:// or ldapi://).  For example,
-{{EX:-h "ldaps:// ldap://127.0.0.1:666"}} will create
-two listeners: one for LDAP over SSL on all interfaces on
-the default LDAP/SSL port 636, and one for LDAP over TCP on
-the {{EX:localhost}} ({{loopback}}) interface on port 666.
-Hosts may be specified using IPv4 dotted-decimal form or
-using host names.  Port values must be numeric.
+default is {{EX:ldap:///}} which implies {{TERM:LDAP}} over
+{{TERM:TCP}} on all interfaces on the default LDAP port 389.  You
+can specify specific host-port pairs or other protocol schemes (such
+as {{EX:ldaps://}} or {{EX:ldapi://}}).  For example, {{EX:-h
+"ldaps:// ldap://127.0.0.1:666"}} will create two listeners: one
+for the (non-standard) {{EX:ldaps://}} scheme on all interfaces on
+the default {{EX:ldaps://}} port 636, and one for the standard
+{{EX:ldap://}} scheme on the {{EX:localhost}} ({{loopback}}) interface
+on port 666.  Hosts may be specified using using hostnames or
+{{TERM:IPv4}} or {{TERM:IPv6}} addresses.  Port values must be
+numeric.
 
 >	-n <service-name>
 
 This option specifies the service name used for logging and
-other purposes.  The default service name is {{EX:slapd}}.
+other purposes. The default service name is {{EX:slapd}}.
 
 >	-l <syslog-local-user>
 
@@ -67,7 +79,7 @@
 debugging levels are
 
 !block table; colaligns="RL"; align=Center; \
-	title="Table 6.1: Debugging Levels"
+	title="Table 7.1: Debugging Levels"
 Level	Description
 -1	enable all debugging
 0	no debugging
@@ -103,9 +115,9 @@
 
 In general, slapd is run like this:
 
->	/usr/local/etc/libexec/slapd [<option>]*
+>	/usr/local/libexec/slapd [<option>]*
 
-where {{F:/usr/local/etc/libexec}} is determined by {{EX:configure}}
+where {{F:/usr/local/libexec}} is determined by {{EX:configure}}
 and <option> is one of the options described above (or in {{slapd}}(8)).
 Unless you have specified a debugging level (including level {{EX:0}}),
 slapd will automatically fork and detach itself from its controlling
@@ -113,11 +125,11 @@
 
 H2: Stopping slapd
 
-To kill off slapd safely, you should give a command like this
+To kill off {{slapd}}(8) safely, you should give a command like this
 
 > 	kill -INT `cat /usr/local/var/slapd.pid`
 
 where {{F:/usr/local/var}} is determined by {{EX:configure}}.
 
-Killing slapd by a more drastic method may cause information
-loss or database corruption.
+Killing slapd by a more drastic method may cause information loss or
+database corruption.

Modified: openldap/trunk/doc/guide/admin/sasl.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/sasl.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/sasl.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,3 +1,4 @@
+# $OpenLDAP: pkg/openldap-guide/admin/sasl.sdf,v 1.34.2.6 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -5,26 +6,26 @@
 
 OpenLDAP clients and servers are capable of authenticating via the
 {{TERM[expand]SASL}} ({{TERM:SASL}}) framework, which is detailed
-in {{REF:RFC2222}}.   This chapter describes how to make use of
+in {{REF:RFC4422}}.   This chapter describes how to make use of
 SASL in OpenLDAP.
 
 There are several industry standard authentication mechanisms that
 can be used with SASL, including {{TERM:GSSAPI}} for {{TERM:Kerberos}}
-V, DIGEST-MD5, and PLAIN and EXTERNAL for use with {{TERM[expand]TLS}}
-(TLS).
+V, {{TERM:DIGEST-MD5}}, and {{TERM:PLAIN}} and {{TERM:EXTERNAL}}
+for use with {{TERM[expand]TLS}} (TLS).
 
 The standard client tools provided with OpenLDAP Software, such as
 {{ldapsearch}}(1) and {{ldapmodify}}(1), will by default attempt
-to authenticate the user to the {{slapd}}(8) server using SASL.
-Basic authentication service can be set up by the LDAP administrator
-with a few steps, allowing users to be authenticated to the slapd
-server as their LDAP entry.  With a few extra steps, some users and
-services can be allowed to exploit SASL's proxy authorization
-feature, allowing them to authenticate themselves and then switch
-their identity to that of another user or service.
+to authenticate the user to the {{TERM:LDAP}} directory server using
+SASL.  Basic authentication service can be set up by the LDAP
+administrator with a few steps, allowing users to be authenticated
+to the slapd server as their LDAP entry.  With a few extra steps,
+some users and services can be allowed to exploit SASL's proxy
+authorization feature, allowing them to authenticate themselves and
+then switch their identity to that of another user or service.
 
 This chapter assumes you have read {{Cyrus SASL for System
-Administrators}}, provided with the {{PRD:Cyrus}} {{PRD:SASL}}
+Administrators}}, provided with the {{PRD:Cyrus SASL}}
 package (in {{FILE:doc/sysadmin.html}}) and have a working Cyrus
 SASL installation.  You should use the Cyrus SASL {{EX:sample_client}}
 and {{EX:sample_server}} to test your SASL installation before
@@ -56,19 +57,19 @@
 The DIGEST-MD5 mechanism is the mandatory-to-implement authentication
 mechanism for LDAPv3.  Though DIGEST-MD5 is not a strong authentication
 mechanism in comparison with trusted third party authentication
-systems (such as Kerberos or public key systems), it does offer
-significant protections against a number of attacks.  Unlike the
-CRAM-MD5 mechanism, it prevents chosen plaintext attacks.  DIGEST-MD5
-is favored over the use of plaintext password mechanisms.  The
-CRAM-MD5 mechanism is deprecated in favor of DIGEST-MD5.  Use of
-{{SECT:DIGEST-MD5}} is discussed below.
+systems (such as {{TERM:Kerberos}} or public key systems), it does
+offer significant protections against a number of attacks.  Unlike
+the {{TERM:CRAM-MD5}} mechanism, it prevents chosen plaintext
+attacks.  DIGEST-MD5 is favored over the use of plaintext password
+mechanisms.  The CRAM-MD5 mechanism is deprecated in favor of
+DIGEST-MD5.  Use of {{SECT:DIGEST-MD5}} is discussed below.
 
-The GSSAPI mechanism utilizes Kerberos V to provide secure
-authentication services.  The KERBEROS_V4 mechanism is available
-for those using Kerberos IV.  Kerberos is viewed as a secure,
-distributed authentication system suitable for both small and large
-enterprises.  Use of {{SECT:GSSAPI}} and {{SECT:KERBEROS_V4}} are
-discussed below.
+The GSSAPI mechanism utilizes {{TERM:GSS-API}} {{TERM:Kerberos}} V
+to provide secure authentication services.  The KERBEROS_V4 mechanism
+is available for those using Kerberos IV.  Kerberos is viewed as a
+secure, distributed authentication system suitable for both small
+and large enterprises.  Use of {{SECT:GSSAPI}} and {{SECT:KERBEROS_V4}}
+are discussed below.
 
 The EXTERNAL mechanism utilizes authentication services provided
 by lower level network services such as {{TERM:TLS}} (TLS).  When
@@ -85,18 +86,18 @@
 H2: SASL Authentication
 
 Getting basic SASL authentication running involves a few steps.
-The first step configures your slapd server environment so
-that it can communicate with client programs using the security
-system in place at your site. This usually involves setting up a
-service key, a public key, or other form of secret. The second step
-concerns mapping authentication identities to LDAP DN's, which
+The first step configures your slapd server environment so that it
+can communicate with client programs using the security system in
+place at your site. This usually involves setting up a service key,
+a public key, or other form of secret. The second step concerns
+mapping authentication identities to LDAP {{TERM:DN}}'s, which
 depends on how entries are laid out in your directory. An explanation
 of the first step will be given in the next section using Kerberos
 V4 as an example mechanism. The steps necessary for your site's
 authentication mechanism will be similar, but a guide to every
 mechanism available under SASL is beyond the scope of this chapter.
-The second step is described in the section 
-{{SECT:Mapping Authentication Identities}}.
+The second step is described in the section {{SECT:Mapping
+Authentication Identities}}.
 
 
 H3: GSSAPI
@@ -352,7 +353,7 @@
 or pattern, and terms in parenthesis are remembered for the replacement
 pattern.
 
-The replacement pattern will produce either a DN or URL refering
+The replacement pattern will produce either a DN or URL referring
 to the user.  Anything from the authentication request DN that
 matched a string in parenthesis in the search pattern is stored in
 the variable "$1". That variable "$1" can appear in the replacement
@@ -483,6 +484,10 @@
 the realm name becoming part of the UID.  Also note the use of scope
 and filters to limit matching to desirable entries.
 
+Note as well that {{EX:authz-regexp}} internal search are subject
+to access controls.  Specifically, the authentication identity
+must have {{EX:auth}} access.
+
 See {{slapd.conf}}(5) for more detailed information.
 
 
@@ -538,7 +543,7 @@
 become that DN, users must first authenticate as one of the persons
 on the list. This allows for better auditing of who made changes
 to the LDAP database.  If people were allowed to authenticate
-directly to the priviliged account, possibly through the {{EX:rootpw}}
+directly to the privileged account, possibly through the {{EX:rootpw}}
 {{slapd.conf}}(5) directive or through a {{EX:userPassword}}
 attribute, then auditing becomes more difficult.
 
@@ -572,7 +577,7 @@
 
 In the first form, the <username> is from the same namespace as
 the authentication identities above. It is the user's username as
-it is refered to by the underlying authentication mechanism.
+it is referred to by the underlying authentication mechanism.
 Authorization identities of this form are converted into a DN format
 by the same function that the authentication process used, producing
 an {{authorization request DN}} of the form
@@ -613,7 +618,7 @@
 specify the authorization is permitted, the {{EX:authzFrom}}
 rules in the authorization DN entry are then checked. If neither
 case specifies that the request be honored, the request is denied.
-Since the default behaviour is to deny authorization requests, rules
+Since the default behavior is to deny authorization requests, rules
 only specify that a request be allowed; there are no negative rules
 telling what authorizations to deny.
 
@@ -647,7 +652,7 @@
 be DNs with regular expression characters in them. This means a
 source rule like
 
->	authzTo: uid=[^,]*,dc=example,dc=com
+>	authzTo: dn.regex=^uid=[^,]*,dc=example,dc=com$
 
 would allow that authenticated user to authorize to any DN that
 matches the regular expression pattern given. This regular expression
@@ -657,7 +662,7 @@
 Also note that the values in an authorization rule must be one of
 the two forms: an LDAP URL or a DN (with or without regular expression
 characters). Anything that does not begin with "{{EX:ldap://}}" is
-taken as a DN. It is not permissable to enter another authorization
+taken as a DN. It is not permissible to enter another authorization
 identity of the form "{{EX:u:<username>}}" as an authorization rule.
 
 
@@ -679,10 +684,10 @@
 source rules, {{EX:from}} for destination rules, or {{EX:both}} for
 both source and destination rules.
 
-Destination rules are extremely powerful. If ordinary users have
+Source rules are extremely powerful. If ordinary users have
 access to write the {{EX:authzTo}} attribute in their own
 entries, then they can write rules that would allow them to authorize
-as anyone else.  As such, when using destination rules, the
+as anyone else.  As such, when using source rules, the
 {{EX:authzTo}} attribute should be protected with an ACL that
 only allows privileged users to set its values.
 

Modified: openldap/trunk/doc/guide/admin/schema.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/schema.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/schema.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,11 +1,11 @@
-# $OpenLDAP: pkg/openldap-guide/admin/schema.sdf,v 1.39.2.3 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/schema.sdf,v 1.41.2.5 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
 H1: Schema Specification
 
 This chapter describes how to extend the user schema used by
-{{slapd}}(8).  The chapter assumes the reader is familar with the
+{{slapd}}(8).  The chapter assumes the reader is familiar with the
 {{TERM:LDAP}}/{{TERM:X.500}} information model.
 
 The first section, {{SECT:Distributed Schema Files}} details optional
@@ -28,7 +28,7 @@
 
 H2: Distributed Schema Files
 
-OpenLDAP is distributed with a set of schema specifications for
+OpenLDAP Software is distributed with a set of schema specifications for
 your use.  Each set is defined in a file suitable for inclusion
 (using the {{EX:include}} directive) in your {{slapd.conf}}(5)
 file.  These schema files are normally installed in the
@@ -55,7 +55,7 @@
 >	include /usr/local/etc/openldap/schema/inetorgperson.schema
 
 Additional files may be available.  Please consult the OpenLDAP
-FAQ ({{URL:http://www.openldap.org/faq/}}).
+{{TERM:FAQ}} ({{URL:http://www.openldap.org/faq/}}).
 
 Note: You should not modify any of the schema items defined
 in provided files.
@@ -72,7 +72,7 @@
 and hence is not discussed here.
 
 There are five steps to defining new schema:
-^	obtain Object Identifer
+^	obtain Object Identifier
 +	choose a name prefix
 +	create local schema file
 +	define custom attribute types (if necessary)
@@ -96,61 +96,53 @@
 1.1.1		SNMP Elements
 1.1.2		LDAP Elements
 1.1.2.1		AttributeTypes
-1.1.2.1.1	myAttribute
+1.1.2.1.1	x-my-Attribute
 1.1.2.2		ObjectClasses
-1.1.2.2.1	myObjectClass
+1.1.2.2.1	x-my-ObjectClass
 !endblock
 
 You are, of course, free to design a hierarchy suitable to your
-organizational needs under your organization's OID.  No matter what
-hierarchy you choose, you should maintain a registry of assignments
-you make.  This can be a simple flat file or something more
-sophisticated such as the {{OpenLDAP OID Registry}}
-({{URL:http://www.openldap.org/faq/index.cgi?file=197}}).
+organizational needs under your organization's OID. No matter what hierarchy you choose, you should maintain a registry of assignments you make.  This can be a simple flat file or something more sophisticated such as the {{OpenLDAP OID Registry}} ({{URL:http://www.openldap.org/faq/index.cgi?file=197}}).
 
-For more information about Object Identifers (and a listing service)
+For more information about Object Identifiers (and a listing service)
 see {{URL:http://www.alvestrand.no/harald/objectid/}}.
 
 .{{Under no circumstances should you hijack OID namespace!}}
 
-To obtain a registered OID at {{no cost}}, apply for an OID under
-the {{ORG[expand]IANA}} (IANA) maintained {{Private Enterprise}}
-arc.  Any private enterprise (organization) may request an OID to
-be assigned under this arc.  Just fill out the {{ORG:IANA}} form
-at {{URL: http://www.iana.org/cgi-bin/enterprise.pl}} and your
-official OID will be sent to you usually within a few days.  Your
-base OID will be something like {{EX:1.3.6.1.4.1.X}} where {{EX:X}}
-is an integer.
+To obtain a registered OID at {{no cost}}, apply for a OID
+under the {{ORG[expand]IANA}} (ORG:IANA) maintained {{Private Enterprise}} arc.  
+Any private enterprise (organization) may request a {{TERM[expand]PEN}} (PEN) to be assigned under this arc. Just fill out the IANA form at {{URL: http://pen.iana.org/pen/PenApplication.page}} and your official PEN will be sent to you usually within a few days. Your base OID will be something like {{EX:1.3.6.1.4.1.X}} where {{EX:X}} is an integer.
 
-Note: Don't let the "MIB/SNMP" statement on the IANA page confuse
-you.  OIDs obtained using this form may be used for any purpose
+Note: PENs obtained using this form may be used for any purpose
 including identifying LDAP schema elements.
 
 Alternatively, OID name space may be available from a national
 authority (e.g., {{ORG:ANSI}}, {{ORG:BSI}}).
 
 
-H3: Name Prefix
+H3: Naming Elements
 
 In addition to assigning a unique object identifier to each schema
 element, you should provide a least one textual name for each
-element.  The name should be both descriptive and not likely to
-clash with names of other schema elements.  In particular, any name
-you choose should not clash with present or future Standard Track
-names.
+element.  Names should be registered with the {{ORG:IANA}} or
+prefixed with "x-" to place in the "private use" name space.
 
-To reduce (but not eliminate) the potential for name clashes, the
-convention is to prefix names of non-Standard Track with a few
-letters to localize the changes to your organization.  The smaller
-the organization, the longer your prefix should be.
+The name should be both descriptive and not likely to clash with
+names of other schema elements.  In particular, any name you choose
+should not clash with present or future Standard Track names (this
+is assured if you registered names or use names beginning with "x-").
 
-In the examples below, we have chosen a short prefix '{{EX:my}}'
-(to save space).  Such a short prefix would only be suitable for a
-very large, global organization.  In general, we recommend something
-like '{{EX:deFirm}}' (German company) or '{{EX:comExample}}' (elements
-associated with organization associated with {{EX:example.com}}).
+It is noted that you can obtain your own registered name
+prefix so as to avoid having to register your names individually.
+See {{REF:RFC4520}} for details.
 
+In the examples below, we have used a short prefix '{{EX:x-my-}}'.
+Such a short prefix would only be suitable for a very large, global
+organization.  In general, we recommend something like '{{EX:x-de-Firm-}}'
+(German company) or '{{EX:x-com-Example}}' (elements associated with
+organization associated with {{EX:example.com}}).
 
+
 H3: Local schema file
 
 The {{EX:objectclass}} and {{EX:attributeTypes}} configuration file
@@ -173,13 +165,13 @@
 
 The {{attributetype}} directive is used to define a new attribute
 type.  The directive uses the same Attribute Type Description
-(as defined in {{REF:RFC2252}}) used by the attributeTypes
+(as defined in {{REF:RFC4512}}) used by the attributeTypes
 attribute found in the subschema subentry, e.g.:
 
-E:	attributetype <{{REF:RFC2252}} Attribute Type Description>
+E:	attributetype <{{REF:RFC4512}} Attribute Type Description>
 
 where Attribute Type Description is defined by the following
-{{TERM:BNF}}:
+{{TERM:ABNF}}:
 
 >      AttributeTypeDescription = "(" whsp
 >            numericoid whsp              ; AttributeType identifier
@@ -227,26 +219,26 @@
 {{slapd}}(8) returns the first listed name when returning results.
 
 The first attribute, {{EX:name}}, holds values of {{EX:directoryString}}
-(UTF-8 encoded Unicode) syntax.  The syntax is specified by OID
-(1.3.6.1.4.1.1466.115.121.1.15 identifies the directoryString
-syntax).  A length recommendation of 32768 is specified.  Servers
-should support values of this length, but may support longer values
-The field does NOT specify a size constraint, so is ignored on
-servers (such as slapd) which don't impose such size limits.  In
-addition, the equality and substring matching uses case ignore
-rules.  Below are tables listing commonly used syntax and
-matching rules (OpenLDAP supports these and many more).
+({{TERM:UTF-8}} encoded Unicode) syntax.  The syntax is
+specified by OID (1.3.6.1.4.1.1466.115.121.1.15 identifies the
+directoryString syntax).  A length recommendation of 32768 is
+specified.  Servers should support values of this length, but may
+support longer values The field does NOT specify a size constraint,
+so is ignored on servers (such as slapd) which don't impose such
+size limits.  In addition, the equality and substring matching uses
+case ignore rules.  Below are tables listing commonly used syntax
+and matching rules ({{slapd}}(8) supports these and many more).
 
 !block table; align=Center; coltags="EX,EX,N"; \
 	title="Table 8.3: Commonly Used Syntaxes"
 Name			OID				Description
 boolean			1.3.6.1.4.1.1466.115.121.1.7	boolean value
 directoryString		1.3.6.1.4.1.1466.115.121.1.15	Unicode (UTF-8) string
-distinguishedName	1.3.6.1.4.1.1466.115.121.1.12	LDAP DN
+distinguishedName	1.3.6.1.4.1.1466.115.121.1.12	LDAP {{TERM:DN}}
 integer			1.3.6.1.4.1.1466.115.121.1.27	integer
 numericString		1.3.6.1.4.1.1466.115.121.1.36	numeric string
 OID			1.3.6.1.4.1.1466.115.121.1.38	object identifier
-octetString		1.3.6.1.4.1.1466.115.121.1.40	arbitary octets
+octetString		1.3.6.1.4.1.1466.115.121.1.40	arbitrary octets
 !endblock
 
 > 
@@ -283,7 +275,7 @@
 The following subsections provide a couple of examples.
 
 
-H4: myUniqueName
+H4: x-my-UniqueName
 
 Many organizations maintain a single unique name for each user.
 Though one could use {{EX:displayName}} ({{REF:RFC2798}}), this
@@ -292,33 +284,33 @@
 from {{F:inetorgperson.schema}} and replace the OID, name, and
 description, e.g:
 
->	attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
+>	attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
 >		DESC 'unique name with my organization' 
 >		EQUALITY caseIgnoreMatch
 >		SUBSTR caseIgnoreSubstringsMatch
 >		SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
 >		SINGLE-VALUE )
 
-However, if we want this name to be included in
-{{EX:name}} assertions [e.g. {{EX:(name=*Jane*)}}], the attribute
-could alternatively be defined as a subtype of {{EX:name}}, e.g.:
+However, if we want this name to be used in {{EX:name}} assertions,
+e.g. {{EX:(name=*Jane*)}}, the attribute could alternatively be
+defined as a subtype of {{EX:name}}, e.g.:
 
->	attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
+>	attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
 >		DESC 'unique name with my organization' 
 >		SUP name )
 
 
-H4: myPhoto
+H4: x-my-Photo
 
 Many organizations maintain a photo of each each user.  A
-{{EX:myPhoto}} attribute type could be defined to hold a photo.
+{{EX:x-my-Photo}} attribute type could be defined to hold a photo.
 Of course, one could use just use {{EX:jpegPhoto}} ({{REF:RFC2798}})
 (or a subtype) to hold the photo.  However, you can only do
 this if the photo is in {{JPEG File Interchange Format}}.
 Alternatively, an attribute type which uses the {{Octet String}}
 syntax can be defined, e.g.:
 
->	attributetype ( 1.1.2.1.2 NAME 'myPhoto'
+>	attributetype ( 1.1.2.1.2 NAME 'x-my-Photo'
 >		DESC 'a photo (application defined format)' 
 >		SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
 >		SINGLE-VALUE )
@@ -337,7 +329,7 @@
 {{EX:labeledURI}} ({{REF:RFC2079}}) or simply create a subtype,
 e.g.:
 
->	attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'
+>	attributetype ( 1.1.2.1.3 NAME 'x-my-PhotoURI'
 >		DESC 'URI and optional label referring to a photo' 
 >		SUP labeledURI )
 
@@ -346,13 +338,13 @@
 
 The {{objectclasses}} directive is used to define a new object
 class.  The directive uses the same Object Class Description
-(as defined in {{REF:RFC2252}}) used by the objectClasses
+(as defined in {{REF:RFC4512}}) used by the objectClasses
 attribute found in the subschema subentry, e.g.:
 
-E:	objectclass <{{REF:RFC2252}} Object Class Description>
+E:	objectclass <{{REF:RFC4512}} Object Class Description>
 
 where Object Class Description is defined by the following
-{{TERM:BNF}}:
+{{TERM:ABNF}}:
 
 >	ObjectClassDescription = "(" whsp
 >		numericoid whsp      ; ObjectClass identifier
@@ -367,22 +359,22 @@
 >		whsp ")"
 
 where whsp is a space ('{{EX: }}'), numericoid is a globally unique
-OID in numeric form (e.g. {{EX:1.1.0}}), qdescrs is one or more
+OID in dotted-decimal form (e.g. {{EX:1.1.0}}), qdescrs is one or more
 names, and oids is one or more names and/or OIDs.
 
 
-H4: myPhotoObject
+H4: x-my-PhotoObject
 
 To define an {{auxiliary}} object class which allows
-myPhoto to be added to any existing entry.
+x-my-Photo to be added to any existing entry.
 
->	objectclass ( 1.1.2.2.1 NAME 'myPhotoObject'
->		DESC 'mixin myPhoto'
+>	objectclass ( 1.1.2.2.1 NAME 'x-my-PhotoObject'
+>		DESC 'mixin x-my-Photo'
 >		AUXILIARY
->		MAY myPhoto )
+>		MAY x-my-Photo )
 
 
-H4: myPerson
+H4: x-my-Person
 
 If your organization would like have a private {{structural}}
 object class to instantiate users, you can subclass one of
@@ -390,22 +382,22 @@
 ({{REF:RFC2798}}), and add any additional attributes which
 you desire.
 
->	objectclass ( 1.1.2.2.2 NAME 'myPerson'
+>	objectclass ( 1.1.2.2.2 NAME 'x-my-Person'
 >		DESC 'my person'
 >		SUP inetOrgPerson
->		MUST ( myUniqueName $ givenName )
->		MAY myPhoto )
+>		MUST ( x-my-UniqueName $ givenName )
+>		MAY x-my-Photo )
 
 The object class inherits the required/allowed attribute
-types of {{EX:inetOrgPerson}} but requires {{EX:myUniqueName}}
-and {{EX:givenName}} and allows {{EX:myPhoto}}.
+types of {{EX:inetOrgPerson}} but requires {{EX:x-my-UniqueName}}
+and {{EX:givenName}} and allows {{EX:x-my-Photo}}.
 
 !if 0
 H2: Transferring Schema
 
-Since the {{slapd.conf}}(5) schema directives use {{REF:RFC2252}}
-format values, you can extract schema elements published by
-any LDAPv3 server and easily construct directives for use with
+Since the {{slapd.conf}}(5) schema directives use {{REF:RFC4512}}
+format values, you can extract schema elements published by any
+{{TERM:LDAPv3}} server and easily construct directives for use with
 {{slapd}}(8).
 
 LDAPv3 servers publish schema elements in special {{subschema}}
@@ -430,12 +422,12 @@
 pairs.  The following is an abbreviated example:
 
 >	dn: cn=Subschema
->	objectClasses: ( 1.1.2.2.2 NAME 'myPerson' DESC 'my person' SUP inet
->	 OrgPerson MUST ( myUniqueName $ givenName ) MAY myPhoto )
->	attributeTypes: ( 1.1.2.1.1 NAME 'myUniqueName' DESC 'unique name wi
->	 th my organization' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubst
->	 ringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
->	attributeTypes: ( 1.1.2.1.2 NAME 'myPhoto' DESC 'a photo (applicatio
+>	objectClasses: ( 1.1.2.2.2 NAME 'x-my-Person' DESC 'my person' SUP inet
+>	 OrgPerson MUST ( x-my-UniqueName $ givenName ) MAY x-my-Photo )
+>	attributeTypes: ( 1.1.2.1.1 NAME 'x-my-UniqueName' DESC 'unique name wi
+>	 th my organization' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstrin
+>	 gsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+>	attributeTypes: ( 1.1.2.1.2 NAME 'x-my-Photo' DESC 'a photo (applicatio
 >	 n defined format)' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
 
 Capture the output of the search in a file and then edit the file:
@@ -451,20 +443,20 @@
 For the three type/value pairs in our example, the edit should
 result in a file with contains of:
 
->	attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
+>	attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
 >		DESC 'unique name with my organization' 
 >		EQUALITY caseIgnoreMatch
 >		SUBSTR caseIgnoreSubstringsMatch
 >		SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
 >		SINGLE-VALUE )
->	attributeType ( 1.1.2.1.2 NAME 'myPhoto'
+>	attributeType ( 1.1.2.1.2 NAME 'x-my-Photo'
 >		DESC 'a photo (application defined format)'
 >		SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
->	objectClass ( 1.1.2.2.2 NAME 'myPerson'
+>	objectClass ( 1.1.2.2.2 NAME 'x-my-Person'
 >		DESC 'my person'
 >		SUP inetOrgPerson
->		MUST ( myUniqueName $ givenName )
->		MAY myPhoto )
+>		MUST ( x-my-UniqueName $ givenName )
+>		MAY x-my-Photo )
 
 Save in an appropriately named file (e.g. {{F:local.schema}}).
 You may now include this file in your {{slapd.conf}}(5) file.
@@ -489,11 +481,11 @@
 >	objectIdentifier myLDAP	myOID:2
 >	objectIdentifier myAttributeType	myLDAP:1
 >	objectIdentifier myObjectClass	myLDAP:2
->	attributetype ( myAttributeType:3 NAME 'myPhotoURI'
+>	attributetype ( myAttributeType:3 NAME 'x-my-PhotoURI'
 >		DESC 'URI and optional label referring to a photo' 
 >		SUP labeledURI )
->	objectclass ( myObjectClass:1 NAME 'myPhotoObject'
->		DESC 'mixin myPhoto'
+>	objectclass ( myObjectClass:1 NAME 'x-my-PhotoObject'
+>		DESC 'mixin x-my-Photo'
 >		AUXILIARY
->		MAY myPhoto )
+>		MAY x-my-Photo )
 

Modified: openldap/trunk/doc/guide/admin/security.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/security.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/security.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,3 +1,4 @@
+# $OpenLDAP: pkg/openldap-guide/admin/security.sdf,v 1.16.2.5 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -76,9 +77,10 @@
 See the {{SECT:Using TLS}} chapter for more information.  StartTLS
 is the standard track mechanism.
 
-A number of {{TERM[expand]SASL}} (SASL) mechanisms, such as DIGEST-MD5
-and {{TERM:GSSAPI}}, also provide data integrity and confidentiality
-protection.  See the {{SECT:Using SASL}} chapter for more information.
+A number of {{TERM[expand]SASL}} (SASL) mechanisms, such as
+{{TERM:DIGEST-MD5}} and {{TERM:GSSAPI}}, also provide data integrity
+and confidentiality protection.  See the {{SECT:Using SASL}} chapter
+for more information.
 
 
 H3: Security Strength Factors
@@ -102,9 +104,9 @@
 protection, 3DES equivalent, for update operations (e.g. add, delete,
 modify, etc.).  See {{slapd.conf}}(5) for details.
 
-For fine-grained control, SSFs may be used in access controls.  See
-{{SECT:Access Control}} section of the {{SECT:The slapd Configuration
-File}} for more information.
+For fine-grained control, SSFs may be used in access controls.
+See {{SECT:The access Configuration Directive}} section of the
+{{SECT:The slapd Configuration File}} for more information.
 
 
 H2: Authentication Methods
@@ -141,10 +143,10 @@
 A successful user/password authenticated bind results in a user
 authorization identity, the provided name, being associated with
 the session.  User/password authenticated bind is enabled by default.
-However, as this mechanism itself offers no evesdropping protection
+However, as this mechanism itself offers no eavesdropping protection
 (e.g., the password is set in the clear), it is recommended that
 it be used only in tightly controlled systems or when the LDAP
-session is protected by other means (e.g., TLS, {{TERM:IPSEC}}).
+session is protected by other means (e.g., TLS, {{TERM:IPsec}}).
 Where the administrator relies on TLS to protect the password, it
 is recommended that unprotected authentication be disabled.  This
 is done using the {{EX:security}} directive's {{EX:simple_bind}}

Modified: openldap/trunk/doc/guide/admin/slapdconf2.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/slapdconf2.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/slapdconf2.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/admin/slapdconf2.sdf,v 1.1.2.14 2007/04/06 03:59:58 quanah Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/slapdconf2.sdf,v 1.20.2.9 2007/11/27 20:31:23 quanah Exp $
 # Copyright 2005-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -6,35 +6,33 @@
 
 Once the software has been built and installed, you are ready
 to configure {{slapd}}(8) for use at your site. Unlike previous
-OpenLDAP releases, the slapd runtime configuration in 2.3 is
-fully LDAP-enabled and can be managed using the standard LDAP
+OpenLDAP releases, the slapd(8) runtime configuration in 2.3 (and later)
+is fully LDAP-enabled and can be managed using the standard LDAP
 operations with data in {{TERM:LDIF}}. The LDAP configuration engine
 allows all of slapd's configuration options to be changed on the fly,
 generally without requiring a server restart for the changes
 to take effect. The old style {{slapd.conf}}(5) file is still
-supported, but must be converted to the new {{slapd.d}}(5) format
+supported, but must be converted to the new {{slapd-config}}(5) format
 to allow runtime changes to be saved. While the old style
 configuration uses a single file, normally installed as
 {{F:/usr/local/etc/openldap/slapd.conf}}, the new style
 uses a slapd backend database to store the configuration. The
 configuration database normally resides in the
-{{F:/usr/local/etc/openldap/slapd.d}} directory.
+{{F:/usr/local/etc/openldap/slapd.d}} directory. When
+converting from the slapd.conf format to slapd.d format, any
+include files will also be integrated into the resulting configuration
+database.
 
-An alternate configuration directory (or file) can be specified via a
-command-line option to {{slapd}}(8) or {{slurpd}}(8). This chapter
-describes the general format of the configuration system, followed by a
-detailed description of commonly used config settings.
+An alternate configuration directory (or file) can be specified via
+a command-line option to {{slapd}}(8). This chapter describes the
+general format of the configuration system, followed by a detailed
+description of commonly used config settings.
 
 Note: some of the backends and of the distributed overlays
 do not support runtime configuration yet.  In those cases,
 the old style {{slapd.conf}}(5) file must be used.
 
-Note: the current version of {{slurpd}} has not been updated for
-compatibility with this new configuration engine. If you must use
-slurpd for replication at your site, you will have to maintain an
-old-style {{slapd.conf}} file for slurpd to use.
 
-
 H2: Configuration Layout
 
 The slapd configuration is stored as a special LDAP directory with
@@ -43,19 +41,15 @@
 database definitions, and assorted other items. A sample config tree
 is shown in Figure 5.1.
 
-!import "config_dit.gif"; align="center"; title="Sample configuration tree"
+!import "config_dit.png"; align="center"; title="Sample configuration tree"
 FT[align="Center"] Figure 5.1: Sample configuration tree.
 
 Other objects may be part of the configuration but were omitted from
 the illustration for clarity.
 
-The {{slapd.d}} configuration tree has a very specific structure. The
+The {{slapd-config}} configuration tree has a very specific structure. The
 root of the tree is named {{EX:cn=config}} and contains global configuration
 settings. Additional settings are contained in separate child entries:
-* Include files
-.. Usually these are just pathnames left over from a converted
-{{EX:slapd.conf}} file.
-.. Otherwise use of Include files is deprecated.
 * Dynamically loaded modules
 .. These may only be used if the {{EX:--enable-modules}} option was
 used to configure the software.
@@ -146,7 +140,7 @@
 H2: Configuration Directives
 
 This section details commonly used configuration directives.  For
-a complete list, see the {{slapd.d}}(5) manual page.  This section
+a complete list, see the {{slapd-config}}(5) manual page.  This section
 will treat the configuration directives in a top-down order, starting
 with the global directives in the {{EX:cn=config}} entry. Each
 directive will be described along with its default value (if any) and
@@ -244,39 +238,6 @@
 >olcReferral: ldap://root.openldap.org
 
 
-
-H3: cn=include
-
-An include entry holds the pathname of one include file. Include files
-are part of the old style slapd.conf configuration system and must be in
-slapd.conf format. Include files were commonly used to load schema
-specifications. While they are still supported, their use is deprecated.
-Include entries must have the {{EX:olcIncludeFile}} objectClass.
-
-
-H4: olcInclude: <filename>
-
-This directive specifies that slapd should read additional
-configuration information from the given file. 
-
-Note: You should be careful when using this directive - there is
-no small limit on the number of nested include directives, and no
-loop detection is done.
-
-
-H4: Sample Entries
-
->dn: cn=include{0},cn=config
->objectClass: olcIncludeFile
->cn: include{0}
->olcInclude: ./schema/core.schema
->
->dn: cn=include{1},cn=config
->objectClass: olcIncludeFile
->cn: include{1}
->olcInclude: ./schema/cosine.schema
-
-
 H3: cn=module
 
 If support for dynamically loaded modules was enabled when configuring
@@ -323,14 +284,14 @@
 objectClass.
 
 
-H4: olcAttributeTypes: <{{REF:RFC2252}} Attribute Type Description>
+H4: olcAttributeTypes: <{{REF:RFC4512}} Attribute Type Description>
 
 This directive defines an attribute type.
 Please see the {{SECT:Schema Specification}} chapter
 for information regarding how to use this directive.
 
 
-H4: olcObjectClasses: <{{REF:RFC2252}} Object Class Description>
+H4: olcObjectClasses: <{{REF:RFC4512}} Object Class Description>
 
 This directive defines an object class.
 Please see the {{SECT:Schema Specification}} chapter for
@@ -377,7 +338,6 @@
 dnssrv	DNS SRV backend
 hdb	Hierarchical variant of bdb backend
 ldap	Lightweight Directory Access Protocol (Proxy) backend
-ldbm	Lightweight DBM backend
 ldif	Lightweight Data Interchange Format backend
 meta	Meta Directory backend
 monitor	Monitor backend
@@ -434,11 +394,11 @@
 This marks the beginning of a new {{TERM:BDB}} database instance.
 
 
-H4: olcAccess: to <what> [ by <who> <accesslevel> <control> ]+
+H4: olcAccess: to <what> [ by <who> [<accesslevel>] [<control>] ]+
 
 This directive grants access (specified by <accesslevel>) to a
 set of entries and/or attributes (specified by <what>) by one or
-more requesters (specified by <who>).
+more requestors (specified by <who>).
 See the {{SECT:Access Control}} section of this chapter for a
 summary of basic usage.
 
@@ -466,73 +426,6 @@
 >	olcReadonly: FALSE
 
 
-H4: olcReplica
-
->	olcReplica: uri=ldap[s]://<hostname>[:<port>] | host=<hostname>[:<port>]
->		[bindmethod={simple|sasl}]
->		["binddn=<DN>"]
->		[saslmech=<mech>]
->		[authcid=<identity>]
->		[authzid=<identity>]
->		[credentials=<password>]
-
-This directive specifies a replication site for this database for
-use with slurpd. The
-{{EX:uri=}} parameter specifies a scheme, a host and optionally a port where
-the slave slapd instance can be found. Either a domain name
-or IP address may be used for <hostname>. If <port> is not
-given, the standard LDAP port number (389 or 636) is used.
-
-{{EX:host}} is deprecated in favor of the {{EX:uri}} parameter.
-
-{{EX:uri}} allows the replica LDAP server to be specified as an LDAP 
-URI such as {{EX:ldap://slave.example.com:389}} or
-{{EX:ldaps://slave.example.com:636}}.
-
-The {{EX:binddn=}} parameter gives the DN to bind as for updates
-to the slave slapd. It should be a DN which has read/write access
-to the slave slapd's database.  It must also match the {{EX:updatedn}}
-directive in the slave slapd's config file.  Generally, this DN
-{{should not}} be the same as the {{EX:rootdn}} of the master
-database.  Since DNs are likely to contain embedded spaces, the
-entire {{EX:"binddn=<DN>"}} string should be enclosed in double
-quotes.
-
-The {{EX:bindmethod}} is {{EX:simple}} or {{EX:sasl}},
-depending on whether simple password-based authentication
-or {{TERM:SASL}} authentication is to be used when connecting
-to the slave slapd.
-
-Simple authentication should not be used unless adequate data
-integrity and confidentiality protections are in place (e.g. TLS
-or IPSEC).  Simple authentication requires specification of
-{{EX:binddn}} and {{EX:credentials}} parameters.
-
-SASL authentication is generally recommended.  SASL authentication
-requires specification of a mechanism using the {{EX:saslmech}} parameter.
-Depending on the mechanism, an authentication identity and/or
-credentials can be specified using {{EX:authcid}} and {{EX:credentials}}
-respectively.  The {{EX:authzid}} parameter may be used to specify
-an authorization identity.
-
-See the chapter entitled {{SECT:Replication with slurpd}} for more
-information on how to use this directive.
-
-
-H4: olcReplogfile: <filename>
-
-This directive specifies the name of the replication log file to
-which slapd will log changes. The replication log is typically
-written by slapd and read by slurpd. Normally, this directive is
-only used if slurpd is being used to replicate the database.
-However, you can also use it to generate a transaction log, if
-slurpd is not running. In this case, you will need to periodically
-truncate the file, since it will grow indefinitely otherwise.
-
-See the chapter entitled {{SECT:Replication with slurpd}} for more
-information on how to use this directive.
-
-
 H4: olcRootDN: <DN>
 
 This directive specifies the DN that is not subject to
@@ -562,8 +455,9 @@
 
 >	olcRootPW: secret
 
-It is also permissible to provide a hash of the password in RFC 2307
-form.  {{slappasswd}}(8) may be used to generate the password hash.
+It is also permissible to provide a hash of the password in
+{{REF:RFC2307}} form.  {{slappasswd}}(8) may be used to generate
+the password hash.
 
 \Example:
 
@@ -609,7 +503,6 @@
 
 >	olcSyncrepl: rid=<replica ID>
 >		provider=ldap[s]://<hostname>[:port]
->		[starttls=yes|critical]
 >		[type=refreshOnly|refreshAndPersist]
 >		[interval=dd:hh:mm:ss]
 >		[retry=[<retry interval> <# of retries>]+]
@@ -629,6 +522,17 @@
 >		[credentials=<passwd>]
 >		[realm=<realm>]
 >		[secprops=<properties>]
+>		[starttls=yes|critical]
+>		[tls_cert=<file>]
+>		[tls_key=<file>]
+>		[tls_cacert=<file>]
+>		[tls_cacertdir=<path>]
+>		[tls_reqcert=never|allow|try|demand]
+>		[tls_ciphersuite=<ciphers>]
+>		[tls_crlcheck=none|peer|all]
+>		[logbase=<base DN>]
+>		[logfilter=<filter str>]
+>		[syncdata=default|accesslog|changelog]
 
 
 This directive specifies the current database as a replica of the
@@ -637,8 +541,8 @@
 The master database is located at the replication provider site
 specified by the {{EX:provider}} parameter. The replica database is
 kept up-to-date with the master content using the LDAP Content
-Synchronization protocol. See {{EX:draft-zeilenga-ldup-sync-xx.txt}}
-({{a work in progress}}) for more information on the protocol.
+Synchronization protocol. See {{REF:RFC4533}}
+for more information on the protocol.
 
 The {{EX:rid}} parameter is used for identification of the current
 {{EX:syncrepl}} directive within the replication consumer server,
@@ -659,12 +563,6 @@
 {{EX:replica}} directives define two independent replication
 mechanisms. They do not represent the replication peers of each other.
 
-The {{EX:starttls}} parameter specifies use of the StartTLS extended
-operation to establish a TLS session before Binding to the provider. If the
-StartTLS request fails and the {{EX:critical}} argument was used, the
-session will be aborted. Otherwise the syncrepl session continues without
-TLS.
-
 The content of the syncrepl replica is defined using a search
 specification as its result set. The consumer slapd will
 send search requests to the provider slapd according to the search
@@ -679,7 +577,7 @@
 and {{EX:timelimit}} default to "unlimited", and only positive integers
 or "unlimited" may be specified.
 
-The LDAP Content Synchronization protocol has two operation
+The {{TERM[expand]LDAP Sync}} protocol has two operation
 types: {{EX:refreshOnly}} and {{EX:refreshAndPersist}}.
 The operation type is specified by the {{EX:type}} parameter.
 In the {{EX:refreshOnly}} operation, the next synchronization search operation
@@ -687,7 +585,7 @@
 synchronization operation finishes. The interval is specified
 by the {{EX:interval}} parameter. It is set to one day by default.
 In the {{EX:refreshAndPersist}} operation, a synchronization search
-remains persistent in the provider slapd. Further updates to the
+remains persistent in the provider {{slapd}} instance. Further updates to the
 master replica will generate {{EX:searchResultEntry}} to the consumer slapd
 as the search responses to the persistent synchronization search.
 
@@ -715,11 +613,11 @@
 The {{EX:bindmethod}} is {{EX:simple}} or {{EX:sasl}},
 depending on whether simple password-based authentication or
 {{TERM:SASL}} authentication is to be used when connecting
-to the provider slapd.
+to the provider {{slapd}} instance.
 
 Simple authentication should not be used unless adequate data
 integrity and confidentiality protections are in place (e.g. TLS
-or IPSEC). Simple authentication requires specification of {{EX:binddn}}
+or IPsec). Simple authentication requires specification of {{EX:binddn}}
 and {{EX:credentials}} parameters.
 
 SASL authentication is generally recommended.  SASL authentication
@@ -733,13 +631,33 @@
 mechanisms authenticate the identity within. The {{EX:secprops}}
 parameter specifies Cyrus SASL security properties.
 
-The syncrepl replication mechanism is supported by the
-three native backends: back-bdb, back-hdb, and back-ldbm.
+The {{EX:starttls}} parameter specifies use of the StartTLS extended
+operation to establish a TLS session before authenticating to the provider.
+If the {{EX:critical}} argument is supplied, the session will be aborted
+if the StartTLS request fails.  Otherwise the syncrepl session continues
+without TLS.  Note that the main slapd TLS settings are not used by the
+syncrepl engine; by default the TLS parameters from a {{ldap.conf}}(5)
+configuration file will be used.  TLS settings may be specified here,
+in which case any {{ldap.conf}}(5) settings will be completely ignored.
 
-See the {{SECT:LDAP Sync Replication}} chapter of the admin guide
-for more information on how to use this directive.
+Rather than replicating whole entries, the consumer can query logs
+of data modifications.  This mode of operation is referred to as
+{{delta syncrepl}}.  In addition to the above parameters, the
+{{EX:logbase}} and {{EX:logfilter}} parameters must be set appropriately
+for the log that will be used. The {{EX:syncdata}} parameter must
+be set to either {{EX:"accesslog"}} if the log conforms to the
+{{slapo-accesslog}}(5) log format, or {{EX:"changelog"}} if the log
+conforms to the obsolete {{changelog}} format. If the {{EX:syncdata}}
+parameter is omitted or set to {{EX:"default"}} then the log
+parameters are ignored.
 
+The {{syncrepl}} replication mechanism is supported by the {{bdb}} and
+{{hdb}} backends.
 
+See the {{SECT:LDAP Sync Replication}} chapter of this guide for
+more information on how to use this directive.
+
+
 H4: olcTimeLimit: <integer>
 
 This directive specifies the maximum number of seconds (in real
@@ -752,24 +670,6 @@
 >	olcTimeLimit: 3600
 
 
-H4: olcUpdateDN: <DN>
-
-This directive is only applicable in a slave slapd. It specifies
-the DN allowed to make changes to the replica.  This may be the DN
-{{slurpd}}(8) binds as when making changes to the replica or the DN
-associated with a SASL identity.
-
-Entry-based Example:
-
->	olcUpdateDN: "cn=Update Daemon,dc=example,dc=com"
-
-SASL-based Example:
-
->	olcUpdateDN: "uid=slurpd,cn=example.com,cn=digest-md5,cn=auth"
-
-See the {{SECT:Replication with slurpd}} chapter for more information
-on how to use this directive.
-
 H4: olcUpdateref: <URL>
 
 This directive is only applicable in a slave slapd. It
@@ -834,7 +734,7 @@
 A checkpoint operation flushes the database buffers to disk and writes a
 checkpoint record in the log.
 The checkpoint will occur if either <kbyte> data has been written or
-<min> minutes have passed since the last checkpont. Both arguments default
+<min> minutes have passed since the last checkpoint. Both arguments default
 to zero, in which case they are ignored. When the <min> argument is
 non-zero, an internal task will run every <min> minutes to perform the
 checkpoint. See the Berkeley DB reference guide for more details.
@@ -851,10 +751,18 @@
 no such file exists yet, the {{EX:DB_CONFIG}} file will be created and the
 settings in this attribute will be written to it. If the file exists,
 its contents will be read and displayed in this attribute. The attribute
-is multi-valued, to accomodate multiple configuration directives. No default
+is multi-valued, to accommodate multiple configuration directives. No default
 is provided, but it is essential to use proper settings here to get the
 best server performance.
 
+Any changes made to this attribute will be written to the {{EX:DB_CONFIG}}
+file and will cause the database environment to be reset so the changes
+can take immediate effect. If the environment cache is large and has not
+been recently checkpointed, this reset operation may take a long time. It
+may be advisable to manually perform a single checkpoint using the Berkeley DB
+{{db_checkpoint}} utility before using LDAP Modify to change this
+attribute.
+
 \Example:
 
 >	olcDbConfig: set_cachesize 0 10485760 0
@@ -868,16 +776,16 @@
 delete transaction log files as soon as their contents have been
 checkpointed and they are no longer needed. Without this setting the
 transaction log files will continue to accumulate until some other
-cleanup procedure removes them. See the SleepyCat documentation for the
+cleanup procedure removes them. See the Berkeley DB documentation for the
 {{EX:db_archive}} command for details.
 
 Ideally the BDB cache must be
 at least as large as the working set of the database, the log buffer size
-should be large enough to accomodate most transactions without overflowing,
+should be large enough to accommodate most transactions without overflowing,
 and the log directory must be on a separate physical disk from the main
 database files. And both the database directory and the log directory
 should be separate from disks used for regular system activities such as
-the root, boot, or swap filesystems. See the FAQ-o-Matic and the SleepyCat
+the root, boot, or swap filesystems. See the FAQ-o-Matic and the Berkeley DB
 documentation for more details.
 
 
@@ -907,7 +815,8 @@
 
 This directive specifies the indices to maintain for the given
 attribute. If only an {{EX:<attrlist>}} is given, the default
-indices are maintained.
+indices are maintained. The index keywords correspond to the
+common types of matches that may be used in an LDAP search filter.
 
 \Example:
 
@@ -924,11 +833,37 @@
 fourth line causes an equality index for the {{EX:objectClass}}
 attribute type.
 
+There is no index keyword for inequality matches. Generally these
+matches do not use an index. However, some attributes do support
+indexing for inequality matches, based on the equality index.
+
+A substring index can be more explicitly specified as {{EX:subinitial}},
+{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three 
+possible components
+of a substring match filter. A subinitial index only indexes
+substrings that appear at the beginning of an attribute value.
+A subfinal index only indexes substrings that appear at the end
+of an attribute value, while subany indexes substrings that occur
+anywhere in a value.
+
+Note that by default, setting an index for an attribute also
+affects every subtype of that attribute. E.g., setting an equality
+index on the {{EX:name}} attribute causes {{EX:cn}}, {{EX:sn}}, and every other
+attribute that inherits from {{EX:name}} to be indexed.
+
 By default, no indices are maintained.  It is generally advised
 that minimally an equality index upon objectClass be maintained.
 
 >	olcDbindex: objectClass eq
 
+Additional indices should be configured corresponding to the
+most common searches that are used on the database.
+Presence indexing should not be configured for an attribute
+unless the attribute occurs very rarely in the database, and
+presence searches on the attribute occur very frequently during
+normal use of the directory. Most applications don't use presence
+searches, so usually presence indexing is not very useful.
+
 If this setting is changed while slapd is running, an internal task
 will be run to generate the changed index data. All server operations
 can continue as normal while the indexer does its work.  If slapd is
@@ -963,7 +898,7 @@
 H4: olcDbSearchStack: <integer>
 
 Specify the depth of the stack used for search filter evaluation.
-Search filters are evaluated on a stack to accomodate nested {{EX:AND}} /
+Search filters are evaluated on a stack to accommodate nested {{EX:AND}} /
 {{EX:OR}} clauses. An individual stack is allocated for each server thread.
 The depth of the stack determines how complex a filter can be evaluated
 without requiring any additional memory allocation. Filters that are
@@ -1021,7 +956,7 @@
 
 >	olcAccess: <access directive>
 >	<access directive> ::= to <what>
->		[by <who> <access> <control>]+
+>		[by <who> [<access>] [<control>] ]+
 >	<what> ::= * |
 >		[dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>]
 >		[filter=<ldapfilter>] [attrs=<attrlist>]
@@ -1040,8 +975,8 @@
 >		[set=<setspec>]
 >		[aci=<attrname>]
 >	<access> ::= [self]{<level>|<priv>}
->	<level> ::= none | auth | compare | search | read | write
->	<priv> ::= {=|+|-}{w|r|s|c|x|0}+
+>	<level> ::= none | disclose | auth | compare | search | read | write | manage
+>	<priv> ::= {=|+|-}{m|w|r|s|c|x|d|0}+
 >	<control> ::= [stop | continue | break]
 
 where the <what> part selects the entries and/or attributes to which
@@ -1071,7 +1006,7 @@
 discussed further in this document.)  The third form is used to
 select entries which are within the requested scope of DN.  The
 <DN> is a string representation of the Distinguished Name, as
-described in {{REF:RFC2253}}.
+described in {{REF:RFC4514}}.
 
 The scope can be either {{EX:base}}, {{EX:one}}, {{EX:subtree}},
 or {{EX:children}}.  Where {{EX:base}} matches only the entry with
@@ -1101,7 +1036,7 @@
 >	to filter=<ldap filter>
 
 where <ldap filter> is a string representation of an LDAP
-search filter, as described in {{REF:RFC2254}}.  For example:
+search filter, as described in {{REF:RFC4515}}.  For example:
 
 >	to filter=(objectClass=person)
 
@@ -1169,30 +1104,30 @@
 
 Some factors may not be appropriate in all environments (or any).
 For example, the domain factor relies on IP to domain name lookups.
-As these can easily spoofed, the domain factor should not be avoided.
+As these can easily be spoofed, the domain factor should be avoided.
 
 
 H3: The access to grant
 
-
 The kind of <access> granted can be one of the following:
 
-
 !block table; colaligns="LRL"; coltags="EX,EX,N"; align=Center; \
 	title="Table 5.4: Access Levels"
-Level	Privileges	Description
-none	=0		no access
-auth	=x		needed to bind
-compare	=cx		needed to compare
-search	=scx		needed to apply search filters
-read	=rscx		needed to read search results
-write	=wrscx		needed to modify/rename
+Level		Privileges	Description
+none		=0			no access
+disclose	=d			needed for information disclosure on error
+auth		=dx			needed to authenticate (bind)
+compare		=cdx		needed to compare
+search		=scdx		needed to apply search filters
+read		=rscdx		needed to read search results
+write		=wrscdx		needed to modify/rename
+manage		=mwrscdx	needed to manage
 !endblock
 
-Each level implies all lower levels of access. So, for
-example, granting someone {{EX:write}} access to an entry also
-grants them {{EX:read}}, {{EX:search}}, {{EX:compare}}, and 
-{{EX:auth}} access.  However, one may use the privileges specifier
+Each level implies all lower levels of access. So, for example,
+granting someone {{EX:write}} access to an entry also grants them
+{{EX:read}}, {{EX:search}}, {{EX:compare}}, {{EX:auth}} and
+{{EX:disclose}} access.  However, one may use the privileges specifier
 to grant specific permissions.
 
 
@@ -1200,15 +1135,16 @@
 
 When evaluating whether some requester should be given access to
 an entry and/or attribute, slapd compares the entry and/or attribute
-to the {{EX:<what>}} selectors given in the configuration.
-For each entry, access controls provided in the database which holds
+to the {{EX:<what>}} selectors given in the configuration.  For
+each entry, access controls provided in the database which holds
 the entry (or the first database if not held in any database) apply
 first, followed by the global access directives (which are held in
-the {{EX:frontend}} database definition).  Within this
-priority, access directives are examined in the order in which they
-appear in the configuration attribute.  Slapd stops with the first {{EX:<what>}}
-selector that matches the entry and/or attribute. The corresponding
-access directive is the one slapd will use to evaluate access.
+the {{EX:frontend}} database definition).  Within this priority,
+access directives are examined in the order in which they appear
+in the configuration attribute.  Slapd stops with the first
+{{EX:<what>}} selector that matches the entry and/or attribute. The
+corresponding access directive is the one slapd will use to evaluate
+access.
 
 Next, slapd compares the entity requesting access to the {{EX:<who>}}
 selectors within the access directive selected above in the order
@@ -1523,16 +1459,21 @@
 The next section of the example configuration file defines another
 BDB database. This one handles queries involving the
 {{EX:dc=example,dc=net}} subtree but is managed by the same entity
-as the first database.  Note that without line 51, the read access
+as the first database.  Note that without line 52, the read access
 would be allowed due to the global access rule at line 19.
 
-E: 42.	# BDB definition for example.net
-E: 43.	dn: olcDatabase=bdb,cn=config
-E: 44.	objectClass: olcDatabaseConfig
-E: 45.	objectClass: olcBdbConfig
-E: 46.	olcDatabase: bdb
-E: 47.	olcSuffix: "dc=example,dc=net"
-E: 48.	olcDbDirectory: /usr/local/var/openldap-data-net
-E: 49.	olcRootDN: "cn=Manager,dc=example,dc=com"
-E: 50.	olcDbIndex: objectClass eq
-E: 51.	olcAccess: to * by users read
+E: 43.	# BDB definition for example.net
+E: 44.	dn: olcDatabase=bdb,cn=config
+E: 45.	objectClass: olcDatabaseConfig
+E: 46.	objectClass: olcBdbConfig
+E: 47.	olcDatabase: bdb
+E: 48.	olcSuffix: "dc=example,dc=net"
+E: 49.	olcDbDirectory: /usr/local/var/openldap-data-net
+E: 50.	olcRootDN: "cn=Manager,dc=example,dc=com"
+E: 51.	olcDbIndex: objectClass eq
+E: 52.	olcAccess: to * by users read
+
+
+H2: Converting from slapd.conf(8) to a {{B:cn=config}} directory format
+
+Discuss slap* -f slapd.conf -F slapd.d/  (man slapd-config)

Modified: openldap/trunk/doc/guide/admin/slapdconfig.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/slapdconfig.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/slapdconfig.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/admin/slapdconfig.sdf,v 1.79.2.8 2007/04/06 04:00:41 quanah Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/slapdconfig.sdf,v 1.87.2.11 2007/11/27 20:31:23 quanah Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -10,10 +10,10 @@
 {{slapd.conf}}(5) file, normally installed in the
 {{EX:/usr/local/etc/openldap}} directory.
 
-An alternate configuration file can be specified via a
-command-line option to {{slapd}}(8) or {{slurpd}}(8). This chapter
-describes the general format of the config file, followed by a
-detailed description of commonly used config file directives.
+An alternate configuration file location can be specified via a command-line
+option to {{slapd}}(8). This chapter describes the general format
+of the {{slapd.conf}}(5) configuration file, followed by a detailed
+description of commonly used config file directives.
 
 
 H2: Configuration File Format
@@ -87,13 +87,13 @@
 by actual text are shown in brackets {{EX:<>}}.
 
 
-H4: access to <what> [ by <who> <accesslevel> <control> ]+
+H4: access to <what> [ by <who> [<accesslevel>] [<control>] ]+
 
-This directive grants access (specified by <accesslevel>) to a
-set of entries and/or attributes (specified by <what>) by one or
-more requesters (specified by <who>).
-See the {{SECT:Access Control}} section of this chapter for a
-summary of basic usage.
+This directive grants access (specified by <accesslevel>) to a set
+of entries and/or attributes (specified by <what>) by one or more
+requestors (specified by <who>).  See the {{SECT:The access
+Configuration Directive}} section of this chapter for a summary of
+basic usage.
 
 !if 0
 More details discussion of this directive can be found in the
@@ -105,7 +105,7 @@
 both authenticated and anonymous users read access.
 
 
-H4: attributetype <{{REF:RFC2252}} Attribute Type Description>
+H4: attributetype <{{REF:RFC4512}} Attribute Type Description>
 
 This directive defines an attribute type.
 Please see the {{SECT:Schema Specification}} chapter
@@ -142,7 +142,7 @@
 or consult the table below. The possible values for <integer> are:
 
 !block table; colaligns="RL"; align=Center; \
-	title="Table 5.1: Debugging Levels"
+	title="Table 6.1: Debugging Levels"
 Level	Description
 -1	enable all debugging
 0	no debugging
@@ -172,7 +172,7 @@
 E: loglevel 256
 
 
-H4: objectclass <{{REF:RFC2252}} Object Class Description>
+H4: objectclass <{{REF:RFC4512}} Object Class Description>
 
 This directive defines an object class.
 Please see the {{SECT:Schema Specification}} chapter for
@@ -229,7 +229,7 @@
 
 This directive marks the beginning of a backend declaration.
 {{EX:<type>}} should be one of the
-supported backend types listed in Table 5.2.
+supported backend types listed in Table 6.2.
 
 !block table; align=Center; coltags="EX,N"; \
 	title="Table 5.2: Database Backends"
@@ -238,7 +238,6 @@
 dnssrv	DNS SRV backend
 hdb	Hierarchical variant of bdb backend
 ldap	Lightweight Directory Access Protocol (Proxy) backend
-ldbm	Lightweight DBM backend
 meta	Meta Directory backend
 monitor	Monitor backend
 passwd	Provides read-only access to {{passwd}}(5)
@@ -265,7 +264,7 @@
 This directive marks the beginning of a database instance
 declaration.
 {{EX:<type>}} should be one of the
-supported backend types listed in Table 5.2.
+supported backend types listed in Table 6.2.
 
 \Example:
 
@@ -285,71 +284,7 @@
 
 >	readonly off
 
-H4: replica
 
->	replica uri=ldap[s]://<hostname>[:<port>] | host=<hostname>[:<port>]
->		[bindmethod={simple|sasl}]
->		["binddn=<DN>"]
->		[saslmech=<mech>]
->		[authcid=<identity>]
->		[authzid=<identity>]
->		[credentials=<password>]
-
-This directive specifies a replication site for this database. The
-{{EX:uri=}} parameter specifies a scheme, a host and optionally a port where
-the slave slapd instance can be found. Either a domain name
-or IP address may be used for <hostname>. If <port> is not
-given, the standard LDAP port number (389 or 636) is used.
-
-{{EX:host}} is deprecated in favor of the {{EX:uri}} parameter.
-
-{{EX:uri}} allows the replica LDAP server to be specified as an LDAP 
-URI such as {{EX:ldap://slave.example.com:389}} or
-{{EX:ldaps://slave.example.com:636}}.
-
-The {{EX:binddn=}} parameter gives the DN to bind as for updates
-to the slave slapd. It should be a DN which has read/write access
-to the slave slapd's database.  It must also match the {{EX:updatedn}}
-directive in the slave slapd's config file.  Generally, this DN
-{{should not}} be the same as the {{EX:rootdn}} of the master
-database.  Since DNs are likely to contain embedded spaces, the
-entire {{EX:"binddn=<DN>"}} string should be enclosed in double
-quotes.
-
-The {{EX:bindmethod}} is {{EX:simple}} or {{EX:sasl}}, depending
-on whether simple password-based authentication or {{TERM:SASL}}
-authentication is to be used when connecting to the slave slapd.
-
-Simple authentication should not be used unless adequate data
-integrity and confidentiality protections are in place (e.g. TLS
-or IPSEC).  Simple authentication requires specification of
-{{EX:binddn}} and {{EX:credentials}} parameters.
-
-SASL authentication is generally recommended.  SASL authentication
-requires specification of a mechanism using the {{EX:saslmech}} parameter.
-Depending on the mechanism, an authentication identity and/or
-credentials can be specified using {{EX:authcid}} and {{EX:credentials}}
-respectively.  The {{EX:authzid}} parameter may be used to specify
-an authorization identity.
-
-See the chapter entitled {{SECT:Replication with slurpd}} for more
-information on how to use this directive.
-
-
-H4: replogfile <filename>
-
-This directive specifies the name of the replication log file to
-which slapd will log changes. The replication log is typically
-written by slapd and read by slurpd. Normally, this directive is
-only used if slurpd is being used to replicate the database.
-However, you can also use it to generate a transaction log, if
-slurpd is not running. In this case, you will need to periodically
-truncate the file, since it will grow indefinitely otherwise.
-
-See the chapter entitled {{SECT:Replication with slurpd}} for more
-information on how to use this directive.
-
-
 H4: rootdn <DN>
 
 This directive specifies the DN that is not subject to
@@ -379,7 +314,7 @@
 
 >	rootpw secret
 
-It is also permissible to provide hash of the password in RFC 2307
+It is also permissible to provide hash of the password in {{REF:RFC2307}}
 form.  {{slappasswd}}(8) may be used to generate the password hash.
 
 \Example:
@@ -416,7 +351,7 @@
 >		[type=refreshOnly|refreshAndPersist]
 >		[interval=dd:hh:mm:ss]
 >		[retry=[<retry interval> <# of retries>]+]
->		[searchbase=<base DN>]
+>		searchbase=<base DN>
 >		[filter=<filter str>]
 >		[scope=sub|one|base]
 >		[attrs=<attr list>]
@@ -440,8 +375,8 @@
 The master database is located at the replication provider site
 specified by the {{EX:provider}} parameter. The replica database is
 kept up-to-date with the master content using the LDAP Content
-Synchronization protocol. See {{EX:draft-zeilenga-ldup-sync-xx.txt}}
-({{a work in progress}}) for more information on the protocol.
+Synchronization protocol. See {{REF:RFC4533}}
+for more information on the protocol.
 
 The {{EX:rid}} parameter is used for identification of the current
 {{EX:syncrepl}} directive within the replication consumer server,
@@ -516,7 +451,7 @@
 
 Simple authentication should not be used unless adequate data
 integrity and confidentiality protections are in place (e.g. TLS
-or IPSEC). Simple authentication requires specification of {{EX:binddn}}
+or IPsec). Simple authentication requires specification of {{EX:binddn}}
 and {{EX:credentials}} parameters.
 
 SASL authentication is generally recommended.  SASL authentication
@@ -530,34 +465,17 @@
 mechanisms authenticate the identity within. The {{EX:secprops}}
 parameter specifies Cyrus SASL security properties.
 
-The syncrepl replication mechanism is supported by the
-three native backends: back-bdb, back-hdb, and back-ldbm.
+The syncrepl replication mechanism is supported by the two primary
+database backends: back-bdb and back-hdb.
 
 See the {{SECT:LDAP Sync Replication}} chapter of the admin guide
 for more information on how to use this directive.
 
 
-H4: updatedn <DN>
-
-This directive is only applicable in a slave slapd. It specifies
-the DN allowed to make changes to the replica.  This may be the DN
-{{slurpd}}(8) binds as when making changes to the replica or the DN
-associated with a SASL identity.
-
-Entry-based Example:
-
->	updatedn "cn=Update Daemon,dc=example,dc=com"
-
-SASL-based Example:
-
->	updatedn "uid=slurpd,cn=example.com,cn=digest-md5,cn=auth"
-
-See the {{SECT:Replication with slurpd}} chapter for more information
-on how to use this directive.
-
 H4: updateref <URL>
 
-This directive is only applicable in a slave slapd. It
+This directive is only applicable in a {{slave}} (or {{shadow}})
+{{slapd}}(8) instance. It
 specifies the URL to return to clients which submit update
 requests upon the replica.
 If specified multiple times, each {{TERM:URL}} is provided.
@@ -587,107 +505,14 @@
 >	directory /usr/local/var/openldap-data
 
 
-H3: LDBM Database Directives
+H2: The access Configuration Directive
 
-Directives in this category only apply to a {{TERM:LDBM}} database.
-That is, they must follow a "database ldbm" line and come before
-any subsequent "backend" or "database" line.  For a complete reference
-of LDBM configuration directives, see {{slapd-ldbm}}(5).
-
-H4: cachesize <integer>
-
-This directive specifies the size in entries of the in-memory
-cache maintained by the LDBM backend database instance.
-
-\Default:
-
->	cachesize 1000
-
-
-H4: dbcachesize <integer>
-
-This directive specifies the size in bytes of the in-memory cache
-associated with each open index file. If not supported by the
-underlying database method, this directive is ignored without
-comment. Increasing this number uses more memory but can
-cause a dramatic performance increase, especially during
-modifies or when building indices.
-
-\Default:
-
->	dbcachesize 100000
-
-
-H4: dbnolocking
-
-This option, if present, disables database locking.
-Enabling this option may improve performance at the expense
-of data security.
-
-
-H4: dbnosync
-
-This option causes on-disk database contents to not be immediately
-synchronized with in memory changes upon change.  Enabling this option
-may improve performance at the expense of data integrity.
-
-
-H4: directory <directory>
-
-This directive specifies the directory where the LDBM files
-containing the database and associated indices live.
-
-\Default:
-
->	directory /usr/local/var/openldap-data
-
-
-H4: index {<attrlist> | default} [pres,eq,approx,sub,none]
-
-This directive specifies the indices to maintain for the given
-attribute. If only an {{EX:<attrlist>}} is given, the default
-indices are maintained.
-
-\Example:
-
->	index default pres,eq
->	index uid
->	index cn,sn pres,eq,sub
->	index objectClass eq
-
-The first line sets the default set of indices to maintain to
-present and equality.  The second line causes the default (pres,eq)
-set of indices to be maintained for the {{EX:uid}} attribute type.
-The third line causes present, equality, and substring indices to
-be maintained for {{EX:cn}} and {{EX:sn}} attribute types.  The
-fourth line causes an equality index for the {{EX:objectClass}}
-attribute type.
-
-By default, no indices are maintained.  It is generally advised
-that minimally an equality index upon objectClass be maintained.
-
->	index objectClass eq
-
-
-
-H4: mode <integer>
-
-This directive specifies the file protection mode that newly
-created database index files should have.
-
-\Default:
-
->	mode 0600
-
-
-H2: Access Control
-
-Access to slapd entries and attributes is controlled by the
+Access to entries and attributes is controlled by the
 access configuration file directive. The general form of an
 access line is:
 
 >	<access directive> ::= access to <what>
->		[by <who> <access> <control>]+
+>		[by <who> [<access>] [<control>] ]+
 >	<what> ::= * |
 >		[dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>]
 >		[filter=<ldapfilter>] [attrs=<attrlist>]
@@ -706,8 +531,8 @@
 >		[set=<setspec>]
 >		[aci=<attrname>]
 >	<access> ::= [self]{<level>|<priv>}
->	<level> ::= none | auth | compare | search | read | write
->	<priv> ::= {=|+|-}{w|r|s|c|x|0}+
+>	<level> ::= none | disclose | auth | compare | search | read | write | manage
+>	<priv> ::= {=|+|-}{m|w|r|s|c|x|d|0}+
 >	<control> ::= [stop | continue | break]
 
 where the <what> part selects the entries and/or attributes to which
@@ -737,7 +562,7 @@
 discussed further in this document.)  The third form is used to
 select entries which are within the requested scope of DN.  The
 <DN> is a string representation of the Distinguished Name, as
-described in {{REF:RFC2253}}.
+described in {{REF:RFC4514}}.
 
 The scope can be either {{EX:base}}, {{EX:one}}, {{EX:subtree}},
 or {{EX:children}}.  Where {{EX:base}} matches only the entry with
@@ -767,7 +592,7 @@
 >	to filter=<ldap filter>
 
 where <ldap filter> is a string representation of an LDAP
-search filter, as described in {{REF:RFC2254}}.  For example:
+search filter, as described in {{REF:RFC4515}}.  For example:
 
 >	to filter=(objectClass=person)
 
@@ -810,7 +635,7 @@
 The following table summarizes entity specifiers:
 
 !block table; align=Center; coltags="EX,N"; \
-	title="Table 5.3: Access Entity Specifiers"
+	title="Table 6.3: Access Entity Specifiers"
 Specifier|Entities
 *|All, including anonymous and authenticated users
 anonymous|Anonymous (non-authenticated) users
@@ -835,30 +660,30 @@
 
 Some factors may not be appropriate in all environments (or any).
 For example, the domain factor relies on IP to domain name lookups.
-As these can easily spoofed, the domain factor should not be avoided.
+As these can easily be spoofed, the domain factor should be avoided.
 
 
 H3: The access to grant
 
-
 The kind of <access> granted can be one of the following:
 
-
 !block table; colaligns="LRL"; coltags="EX,EX,N"; align=Center; \
-	title="Table 5.4: Access Levels"
-Level	Privileges	Description
-none	=0		no access
-auth	=x		needed to bind
-compare	=cx		needed to compare
-search	=scx		needed to apply search filters
-read	=rscx		needed to read search results
-write	=wrscx		needed to modify/rename
+	title="Table 6.4: Access Levels"
+Level		Privileges	Description
+none		=0			no access
+disclose	=d			needed for information disclosure on error
+auth		=dx			needed to authenticate (bind)
+compare		=cdx		needed to compare
+search		=scdx		needed to apply search filters
+read		=rscdx		needed to read search results
+write		=wrscdx		needed to modify/rename
+manage		=mwrscdx	needed to manage
 !endblock
 
-Each level implies all lower levels of access. So, for
-example, granting someone {{EX:write}} access to an entry also
-grants them {{EX:read}}, {{EX:search}}, {{EX:compare}}, and 
-{{EX:auth}} access.  However, one may use the privileges specifier
+Each level implies all lower levels of access. So, for example,
+granting someone {{EX:write}} access to an entry also grants them
+{{EX:read}}, {{EX:search}}, {{EX:compare}}, {{EX:auth}} and
+{{EX:disclose}} access.  However, one may use the privileges specifier
 to grant specific permissions.
 
 
@@ -1044,28 +869,20 @@
 E:  8.	directory /usr/local/var/openldap-data
 E:  9.	rootdn "cn=Manager,dc=example,dc=com"
 E: 10.	rootpw secret
-E: 11.	# replication directives
-E: 12.	replogfile /usr/local/var/openldap/slapd.replog
-E: 13.	replica uri=ldap://slave1.example.com:389
-E: 14.		binddn="cn=Replicator,dc=example,dc=com"
-E: 15.		bindmethod=simple credentials=secret
-E: 16.	replica uri=ldaps://slave2.example.com:636
-E: 17.		binddn="cn=Replicator,dc=example,dc=com"
-E: 18.		bindmethod=simple credentials=secret
-E: 19.	# indexed attribute definitions
-E: 20.	index uid pres,eq
-E: 21.	index cn,sn,uid pres,eq,approx,sub
-E: 22.	index objectClass eq
-E: 23.	# database access control definitions
-E: 24.	access to attrs=userPassword
-E: 25.		by self write
-E: 26.		by anonymous auth
-E: 27.		by dn.base="cn=Admin,dc=example,dc=com" write
-E: 28.		by * none
-E: 29.	access to *
-E: 30.		by self write
-E: 31.		by dn.base="cn=Admin,dc=example,dc=com" write
-E: 32.		by * read
+E: 11.	# indexed attribute definitions
+E: 12.	index uid pres,eq
+E: 13.	index cn,sn,uid pres,eq,approx,sub
+E: 14.	index objectClass eq
+E: 15.	# database access control definitions
+E: 16.	access to attrs=userPassword
+E: 17.		by self write
+E: 18.		by anonymous auth
+E: 19.		by dn.base="cn=Admin,dc=example,dc=com" write
+E: 20.		by * none
+E: 21.	access to *
+E: 22.		by self write
+E: 23.		by dn.base="cn=Admin,dc=example,dc=com" write
+E: 24.		by * read
 
 Line 5 is a comment. The start of the database definition is marked
 by the database keyword on line 6. Line 7 specifies the DN suffix
@@ -1076,19 +893,10 @@
 password. This entry is not subject to access control or size or
 time limit restrictions.
 
-Lines 11 through 18 are for replication. Line 12 specifies the
-replication log file (where changes to the database are logged -
-this file is written by slapd and read by slurpd). Lines 13 through
-15 specify the hostname and port for a replicated host, the DN to
-bind as when performing updates, the bind method (simple) and the
-credentials (password) for the binddn. Lines 16 through 18 specify
-a second replication site.  See the {{SECT:Replication with slurpd}}
-chapter for more information on these directives.
-
-Lines 20 through 22 indicate the indices to maintain for various
+Lines 12 through 14 indicate the indices to maintain for various
 attributes.
 
-Lines 24 through 32 specify access control for entries in this
+Lines 16 through 24 specify access control for entries in this
 database.  As this is the first database, the controls also apply
 to entries not held in any database (such as the Root DSE).  For
 all applicable entries, the {{EX:userPassword}} attribute is writable

Deleted: openldap/trunk/doc/guide/admin/syncrepl.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/syncrepl.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/syncrepl.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,407 +0,0 @@
-# $OpenLDAP: pkg/openldap-guide/admin/syncrepl.sdf,v 1.14.2.3 2007/01/02 21:43:43 kurt Exp $
-# Copyright 2003-2007 The OpenLDAP Foundation, All Rights Reserved.
-# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
-
-H1: LDAP Sync Replication
-
-The LDAP Sync replication engine, syncrepl for short, is a consumer-side
-replication engine that enables the consumer LDAP server to maintain
-a shadow copy of a DIT fragment. A syncrepl engine resides at the
-consumer-side as one of the {{slapd}} (8) threads. It creates and
-maintains a consumer replica by connecting to the replication
-provider to perform the initial DIT content load followed either
-by periodic content polling or by timely updates upon content
-changes.
-
-Syncrepl uses the LDAP Content Synchronization (or LDAP Sync for
-short) protocol as the replica synchronization protocol.  It provides
-a stateful replication which supports both pull-based and push-based
-synchronization and does not mandate the use of a history store.
-
-Syncrepl keeps track of the status of the replication content by
-maintaining and exchanging synchronization cookies. Because the
-syncrepl consumer and provider maintain their content status, the
-consumer can poll the provider content to perform incremental
-synchronization by asking for the entries required to make the
-consumer replica up-to-date with the provider content. Syncrepl
-also enables convenient management of replicas by maintaining replica
-status.  The consumer replica can be constructed from a consumer-side
-or a provider-side backup at any synchronization status. Syncrepl
-can automatically resynchronize the consumer replica up-to-date
-with the current provider content.
-
-Syncrepl supports both pull-based and push-based synchronization.
-In its basic refreshOnly synchronization mode, the provider uses
-pull-based synchronization where the consumer servers need not be
-tracked and no history information is maintained.  The information
-required for the provider to process periodic polling requests is
-contained in the synchronization cookie of the request itself.  To
-optimize the pull-based synchronization, syncrepl utilizes the
-present phase of the LDAP Sync protocol as well as its delete phase,
-instead of falling back on frequent full reloads. To further optimize
-the pull-based synchronization, the provider can maintain a per-scope
-session log as a history store. In its refreshAndPersist mode of
-synchronization, the provider uses a push-based synchronization.
-The provider keeps track of the consumer servers that have requested
-a persistent search and sends them necessary updates as the provider
-replication content gets modified.
-
-With syncrepl, a consumer server can create a replica without
-changing the provider's configurations and without restarting the
-provider server, if the consumer server has appropriate access
-privileges for the DIT fragment to be replicated. The consumer
-server can stop the replication also without the need for provider-side
-changes and restart.
-
-Syncrepl supports both partial and sparse replications.  The shadow
-DIT fragment is defined by a general search criteria consisting of
-base, scope, filter, and attribute list.  The replica content is
-also subject to the access privileges of the bind identity of the
-syncrepl replication connection.
-
-
-H2: The LDAP Content Synchronization Protocol
-
-The LDAP Sync protocol allows a client to maintain a synchronized
-copy of a DIT fragment. The LDAP Sync operation is defined as a set
-of controls and other protocol elements which extend the LDAP search
-operation. This section introduces the LDAP Content Sync protocol
-only briefly. For more information, refer to the Internet Draft
-{{The LDAP Content Synchronization Operation
-<draft-zeilenga-ldup-sync-05.txt>}}.
-
-The LDAP Sync protocol supports both polling and listening for
-changes by defining two respective synchronization operations:
-{{refreshOnly}} and {{refreshAndPersist}}.  Polling is implemented
-by the {{refreshOnly}} operation.  The client copy is synchronized
-to the server copy at the time of polling.  The server finishes the
-search operation by returning {{SearchResultDone}} at the end of
-the search operation as in the normal search.  The listening is
-implemented by the {{refreshAndPersist}} operation.  Instead of
-finishing the search after returning all entries currently matching
-the search criteria, the synchronization search remains persistent
-in the server. Subsequent updates to the synchronization content
-in the server cause additional entry updates to be sent to the
-client.
-
-The {{refreshOnly}} operation and the refresh stage of the
-{{refreshAndPersist}} operation can be performed with a present
-phase or a delete phase.
-
-In the present phase, the server sends the client the entries updated
-within the search scope since the last synchronization. The server
-sends all requested attributes, be it changed or not, of the updated
-entries.  For each unchanged entry which remains in the scope, the
-server sends a present message consisting only of the name of the
-entry and the synchronization control representing state present.
-The present message does not contain any attributes of the entry.
-After the client receives all update and present entries, it can
-reliably determine the new client copy by adding the entries added
-to the server, by replacing the entries modified at the server, and
-by deleting entries in the client copy which have not been updated
-nor specified as being present at the server.
-
-The transmission of the updated entries in the delete phase is the
-same as in the present phase. The server sends all the requested
-attributes of the entries updated within the search scope since the
-last synchronization to the client. In the delete phase, however,
-the server sends a delete message for each entry deleted from the
-search scope, instead of sending present messages.  The delete
-message consists only of the name of the entry and the synchronization
-control representing state delete.  The new client copy can be
-determined by adding, modifying, and removing entries according to
-the synchronization control attached to the {{SearchResultEntry}}
-message.
-
-In the case that the LDAP Sync server maintains a history store and
-can determine which entries are scoped out of the client copy since
-the last synchronization time, the server can use the delete phase.
-If the server does not maintain any history store, cannot determine
-the scoped-out entries from the history store, or the history store
-does not cover the outdated synchronization state of the client,
-the server should use the present phase.  The use of the present
-phase is much more efficient than a full content reload in terms
-of the synchronization traffic.  To reduce the synchronization
-traffic further, the LDAP Sync protocol also provides several
-optimizations such as the transmission of the normalized {{EX:entryUUID}}s
-and the transmission of multiple {{EX:entryUUIDs}} in a single
-{{syncIdSet}} message.
-
-At the end of the {{refreshOnly}} synchronization, the server sends
-a synchronization cookie to the client as a state indicator of the
-client copy after the synchronization is completed.  The client
-will present the received cookie when it requests the next incremental
-synchronization to the server.
-
-When {{refreshAndPersist}} synchronization is used, the server sends
-a synchronization cookie at the end of the refresh stage by sending
-a Sync Info message with TRUE refreshDone.  It also sends a
-synchronization cookie by attaching it to {{SearchResultEntry}}
-generated in the persist stage of the synchronization search. During
-the persist stage, the server can also send a Sync Info message
-containing the synchronization cookie at any time the server wants
-to update the client-side state indicator.  The server also updates
-a synchronization indicator of the client at the end of the persist
-stage.
-
-In the LDAP Sync protocol, entries are uniquely identified by the
-{{EX:entryUUID}} attribute value. It can function as a reliable
-identifier of the entry. The DN of the entry, on the other hand,
-can be changed over time and hence cannot be considered as the
-reliable identifier.  The {{EX:entryUUID}} is attached to each
-{{SearchResultEntry}} or {{SearchResultReference}} as a part of the
-synchronization control.
-
-
-H2: Syncrepl Details
-
-The syncrepl engine utilizes both the {{refreshOnly}} and the
-{{refreshAndPersist}} operations of the LDAP Sync protocol.  If a
-syncrepl specification is included in a database definition, {{slapd}}
-(8) launches a syncrepl engine as a {{slapd}} (8) thread and schedules
-its execution. If the {{refreshOnly}} operation is specified, the
-syncrepl engine will be rescheduled at the interval time after a
-synchronization operation is completed.  If the {{refreshAndPersist}}
-operation is specified, the engine will remain active and process
-the persistent synchronization messages from the provider.
-
-The syncrepl engine utilizes both the present phase and the delete
-phase of the refresh synchronization. It is possible to configure
-a per-scope session log in the provider server which stores the
-{{EX:entryUUID}}s of a finite number of entries deleted from a
-replication content.  Multiple replicas of single provider content
-share the same per-scope session log. The syncrepl engine uses the
-delete phase if the session log is present and the state of the
-consumer server is recent enough that no session log entries are
-truncated after the last synchronization of the client.  The syncrepl
-engine uses the present phase if no session log is configured for
-the replication content or if the consumer replica is too outdated
-to be covered by the session log.  The current design of the session
-log store is memory based, so the information contained in the
-session log is not persistent over multiple provider invocations.
-It is not currently supported to access the session log store by
-using LDAP operations. It is also not currently supported to impose
-access control to the session log.
-
-As a further optimization, even in the case the synchronization
-search is not associated with any session log, no entries will be
-transmitted to the consumer server when there has been no update
-in the replication context.
-
-The syncrepl engine, which is a consumer-side replication engine,
-can work with any backends. The LDAP Sync provider can be configured
-as an overlay on any backend, but works best with the {{back-bdb}}
-or {{back-hdb}} backend. The provider can not support refreshAndPersist
-mode on {{back-ldbm}} due to limits in that backend's locking
-architecture.
-
-The LDAP Sync provider maintains a {{EX:contextCSN}} for each
-database as the current synchronization state indicator of the
-provider content.  It is the largest {{EX:entryCSN}} in the provider
-context such that no transactions for an entry having smaller
-{{EX:entryCSN}} value remains outstanding.  The {{EX:contextCSN}}
-could not just be set to the largest issued {{EX:entryCSN}} because
-{{EX:entryCSN}} is obtained before a transaction starts and
-transactions are not committed in the issue order.
-
-The provider stores the {{EX:contextCSN}} of a context in the
-{{EX:contextCSN}} attribute of the context suffix entry. The attribute
-is not written to the database after every update operation though;
-instead it is maintained primarily in memory. At database start
-time the provider reads the last saved {{EX:contextCSN}} into memory
-and uses the in-memory copy exclusively thereafter. By default,
-changes to the {{EX:contextCSN}} as a result of database updates
-will not be written to the database until the server is cleanly
-shut down. A checkpoint facility exists to cause the contextCSN to
-be written out more frequently if desired.
-
-Note that at startup time, if the provider is unable to read a
-{{EX:contextCSN}} from the suffix entry, it will scan the entire
-database to determine the value, and this scan may take quite a
-long time on a large database. When a {{EX:contextCSN}} value is
-read, the database will still be scanned for any {{EX:entryCSN}}
-values greater than it, to make sure the {{EX:contextCSN}} value
-truly reflects the greatest committed {{EX:entryCSN}} in the database.
-On databases which support inequality indexing, setting an eq index
-on the {{EX:entryCSN}} attribute and configuring {{contextCSN}}
-checkpoints will greatly speed up this scanning step.
-
-If no {{EX:contextCSN}} can be determined by reading and scanning
-the database, a new value will be generated. Also, if scanning the
-database yielded a greater {{EX:entryCSN}} than was previously
-recorded in the suffix entry's {{EX:contextCSN}} attribute, a
-checkpoint will be immediately written with the new value.
-
-The consumer also stores its replica state, which is the provider's
-{{EX:contextCSN}} received as a synchronization cookie, in the
-{{EX:contextCSN}} attribute of the suffix entry.  The replica state
-maintained by a consumer server is used as the synchronization state
-indicator when it performs subsequent incremental synchronization
-with the provider server. It is also used as a provider-side
-synchronization state indicator when it functions as a secondary
-provider server in a cascading replication configuration.  Since
-the consumer and provider state information are maintained in the
-same location within their respective databases, any consumer can
-be promoted to a provider (and vice versa) without any special
-actions.
-
-Because a general search filter can be used in the syncrepl
-specification, some entries in the context may be omitted from the
-synchronization content.  The syncrepl engine creates a glue entry
-to fill in the holes in the replica context if any part of the
-replica content is subordinate to the holes. The glue entries will
-not be returned in the search result unless {{ManageDsaIT}} control
-is provided.
-
-Also as a consequence of the search filter used in the syncrepl
-specification, it is possible for a modification to remove an entry
-from the replication scope even though the entry has not been deleted
-on the provider. Logically the entry must be deleted on the consumer
-but in {{refreshOnly}} mode the provider cannot detect and propagate
-this change without the use of the session log.
-
-
-H2: Configuring Syncrepl
-
-Because syncrepl is a consumer-side replication engine, the syncrepl
-specification is defined in {{slapd.conf}} (5) of the consumer
-server, not in the provider server's configuration file.  The initial
-loading of the replica content can be performed either by starting
-the syncrepl engine with no synchronization cookie or by populating
-the consumer replica by adding an {{TERM:LDIF}} file dumped as a
-backup at the provider.
-
-When loading from a backup, it is not required to perform the initial
-loading from the up-to-date backup of the provider content. The
-syncrepl engine will automatically synchronize the initial consumer
-replica to the current provider content. As a result, it is not
-required to stop the provider server in order to avoid the replica
-inconsistency caused by the updates to the provider content during
-the content backup and loading process.
-
-When replicating a large scale directory, especially in a bandwidth
-constrained environment, it is advised to load the consumer replica
-from a backup instead of performing a full initial load using
-syncrepl.
-
-
-H3: Set up the provider slapd
-
-The provider is implemented as an overlay, so the overlay itself
-must first be configured in {{slapd.conf}} (5) before it can be
-used. The provider has only two configuration directives, for setting
-checkpoints on the {{EX:contextCSN}} and for configuring the session
-log.  Because the LDAP Sync search is subject to access control,
-proper access control privileges should be set up for the replicated
-content.
-
-The {{EX:contextCSN}} checkpoint is configured by the
-
->	syncprov-checkpoint <ops> <minutes>
-
-directive. Checkpoints are only tested after successful write
-operations.  If {{<ops>}} operations or more than {{<minutes>}}
-time has passed since the last checkpoint, a new checkpoint is
-performed.
-
-The session log is configured by the
-
->	syncprov-sessionlog <size>
-
-directive, where {{<size>}} is the maximum number of session log
-entries the session log can record. When a session log is configured,
-it is automatically used for all LDAP Sync searches within the
-database.
-
-Note that using the session log requires searching on the {{entryUUID}}
-attribute. Setting an eq index on this attribute will greatly benefit
-the performance of the session log on the provider.
-
-A more complete example of the {{slapd.conf}} content is thus:
-
->	database bdb
->	suffix dc=Example,dc=com
->	rootdn dc=Example,dc=com
->	directory /var/ldap/db
->	index objectclass,entryCSN,entryUUID eq
->
->	overlay syncprov
->	syncprov-checkpoint 100 10
->	syncprov-sessionlog 100
-
-
-H3: Set up the consumer slapd
-
-The syncrepl replication is specified in the database section of
-{{slapd.conf}} (5) for the replica context.  The syncrepl engine
-is backend independent and the directive can be defined with any
-database type.
-
->	database hdb
->	suffix dc=Example,dc=com
->	rootdn dc=Example,dc=com
->	directory /var/ldap/db
->	index objectclass,entryCSN,entryUUID eq
->
->	syncrepl rid=123
->		provider=ldap://provider.example.com:389
->		type=refreshOnly
->		interval=01:00:00:00
->		searchbase="dc=example,dc=com"
->		filter="(objectClass=organizationalPerson)"
->		scope=sub
->		attrs="cn,sn,ou,telephoneNumber,title,l"
->		schemachecking=off
->		bindmethod=simple
->		binddn="cn=syncuser,dc=example,dc=com"
->		credentials=secret
-
-In this example, the consumer will connect to the provider slapd
-at port 389 of {{FILE:ldap://provider.example.com}} to perform a
-polling ({{refreshOnly}}) mode of synchronization once a day.  It
-will bind as {{EX:cn=syncuser,dc=example,dc=com}} using simple
-authentication with password "secret".  Note that the access control
-privilege of {{EX:cn=syncuser,dc=example,dc=com}} should be set
-appropriately in the provider to retrieve the desired replication
-content. Also the search limits must be high enough on the provider
-to allow the syncuser to retrieve a complete copy of the requested
-content.  The consumer uses the rootdn to write to its database so
-it always has full permissions to write all content.
-
-The synchronization search in the above example will search for the
-entries whose objectClass is organizationalPerson in the entire
-subtree rooted at {{EX:dc=example,dc=com}}. The requested attributes
-are {{EX:cn}}, {{EX:sn}}, {{EX:ou}}, {{EX:telephoneNumber}},
-{{EX:title}}, and {{EX:l}}. The schema checking is turned off, so
-that the consumer {{slapd}} (8) will not enforce entry schema
-checking when it process updates from the provider {{slapd}} (8).
-
-For more detailed information on the syncrepl directive, see the
-{{SECT:syncrepl}} section of {{SECT:The slapd Configuration File}}
-chapter of this admin guide.
-
-
-H3: Start the provider and the consumer slapd
-
-The provider {{slapd}} (8) is not required to be restarted.
-{{contextCSN}} is automatically generated as needed: it might be
-originally contained in the {{TERM:LDIF}} file, generated by
-{{slapadd}} (8), generated upon changes in the context, or generated
-when the first LDAP Sync search arrives at the provider.  If an
-LDIF file is being loaded which did not previously contain the
-{{contextCSN}}, the {{-w}} option should be used with {{slapadd}}
-(8) to cause it to be generated. This will allow the server to
-startup a little quicker the first time it runs.
-
-When starting a consumer {{slapd}} (8), it is possible to provide
-a synchronization cookie as the {{-c cookie}} command line option
-in order to start the synchronization from a specific state.  The
-cookie is a comma separated list of name=value pairs. Currently
-supported syncrepl cookie fields are {{csn=<csn>}} and {{rid=<rid>}}.
-{{<csn>}} represents the current synchronization state of the
-consumer replica.  {{<rid>}} identifies a consumer replica locally
-within the consumer server. It is used to relate the cookie to the
-syncrepl definition in {{slapd.conf}} (5) which has the matching
-replica identifier.  The {{<rid>}} must have no more than 3 decimal
-digits.  The command line cookie overrides the synchronization
-cookie stored in the consumer replica database.

Modified: openldap/trunk/doc/guide/admin/title.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/title.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/title.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,11 +1,12 @@
-# $OpenLDAP: pkg/openldap-guide/admin/title.sdf,v 1.9 2005/03/23 16:21:00 kurt Exp $
-# Copyright 1999--2005, The OpenLDAP Foundation, All Rights Reserved.
+# $OpenLDAP: pkg/openldap-guide/admin/title.sdf,v 1.9.6.4 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 1999-2007, The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 #
 # Document: OpenLDAP Administrator's Guide
 # Master: master.sdf
 # 
 
+!define DOC_TOC	3
 !define DOC_TYPE	"Administrator's Guide"
 
 !build_title

Modified: openldap/trunk/doc/guide/admin/tls.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/tls.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/tls.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,3 +1,4 @@
+# $OpenLDAP: pkg/openldap-guide/admin/tls.sdf,v 1.13.2.6 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -6,24 +7,28 @@
 OpenLDAP clients and servers are capable of using the
 {{TERM[expand]TLS}} ({{TERM:TLS}}) framework to provide
 integrity and confidentiality protections and to support
-LDAP authentication using the {{TERM:SASL}} EXTERNAL mechanism. 
+LDAP authentication using the {{TERM:SASL}} {{TERM:EXTERNAL}} mechanism. 
+TLS is defined in {{REF:RFC4346}}.
 
+Note: For generating certifcates, please reference {{URL:http://www.openldap.org/faq/data/cache/185.html}}
+
 H2: TLS Certificates
 
 TLS uses {{TERM:X.509}} certificates to carry client and server
-identities. All servers are required to have valid certificates,
-whereas client certificates are optional. Clients must have a
+identities.  All servers are required to have valid certificates,
+whereas client certificates are optional.  Clients must have a
 valid certificate in order to authenticate via SASL EXTERNAL.
 For more information on creating and managing certificates,
 see the {{PRD:OpenSSL}} documentation.
 
 H3: Server Certificates
 
-The DN of a server certificate must use the CN attribute
-to name the server, and the {{EX:CN}} must carry the server's
-fully qualified domain name. Additional alias names and wildcards
-may be present in the {{EX:subjectAltName}} certificate extension.
-More details on server certificate names are in {{REF:RFC2830}}.
+The {{TERM:DN}} of a server certificate must use the {{EX:CN}}
+attribute to name the server, and the {{EX:CN}} must carry the
+server's fully qualified domain name. Additional alias names and
+wildcards may be present in the {{EX:subjectAltName}} certificate
+extension.  More details on server certificate names are in
+{{REF:RFC4513}}.
 
 H3: Client Certificates
 
@@ -35,18 +40,18 @@
 identical to the DN of their LDAP entry. However, sometimes
 the DNs may not be exactly the same, and so the mapping
 facility described in 
-{{SECT:Mapping Authentication identities to LDAP entries}}
+{{SECT:Mapping Authentication Identities}}
 can be applied to these DNs as well.
 
 H2: TLS Configuration
 
-After obtaining the required certificates, a
-number of options must be configured on both the client
-and the server to enable TLS and make use of the certificates.
-At a minimum, the clients must be configured with the filename
-containing all of the {{TERM[expand]CA}} (CA) certificates it
-will trust. The server must be configured with the {{TERM:CA}}
-certificates and also its own server certificate and private key.
+After obtaining the required certificates, a number of options must
+be configured on both the client and the server to enable TLS and
+make use of the certificates.  At a minimum, the clients must be
+configured with the name of the file containing all of the
+{{TERM[expand]CA}} (CA) certificates it will trust. The server must
+be configured with the {{TERM:CA}} certificates and also its own
+server certificate and private key.
 
 Typically a single CA will have issued the server certificate
 and all of the trusted client certificates, so the server only
@@ -116,29 +121,29 @@
 H4: TLSRandFile <filename>
 
 This directive specifies the file to obtain random bits from when
-{{EX:/dev/urandom}} is not available. If the
-system provides {{EX:/dev/urandom}} then this option is not needed,
-otherwise a source of random data must be configured.
-Some systems (e.g. Linux)
-provide {{EX:/dev/urandom}} by default, while others (e.g. Solaris)
+{{FILE:/dev/urandom}} is not available. If the system provides
+{{FILE:/dev/urandom}} then this option is not needed, otherwise a
+source of random data must be configured.  Some systems (e.g. Linux)
+provide {{FILE:/dev/urandom}} by default, while others (e.g. Solaris)
 require the installation of a patch to provide it, and others may
 not support it at all. In the latter case, EGD or PRNGD should be
 installed, and this directive should specify the name of the EGD/PRNGD
-socket. The environment variable {{EX:RANDFILE}} can also be used to specify
-the filename. Also, in the absence of these options, the {{EX:.rnd}}
-file in the slapd user's home directory may be used if it exists. To
-use the {{EX:.rnd}} file, just create the file and copy a few hundred
-bytes of arbitrary data into the file. The file is only used to
-provide a seed for the pseudo-random number generator, and it doesn't
-need very much data to work.
+socket. The environment variable {{EX:RANDFILE}} can also be used
+to specify the filename. Also, in the absence of these options, the
+{{EX:.rnd}} file in the slapd user's home directory may be used if
+it exists. To use the {{EX:.rnd}} file, just create the file and
+copy a few hundred bytes of arbitrary data into the file. The file
+is only used to provide a seed for the pseudo-random number generator,
+and it doesn't need very much data to work.
 
 H4: TLSEphemeralDHParamFile <filename>
 
-This directive specifies the file that contains parameters for Diffie-Hellman
-ephemeral key exchange.  This is required in order to use a DSA certificate on
-the server side (i.e. {{EX:TLSCertificateKeyFile}} points to a DSA key).
-Multiple sets of parameters can be included in the file; all of them will
-be processed.  Parameters can be generated using the following command
+This directive specifies the file that contains parameters for
+Diffie-Hellman ephemeral key exchange.  This is required in order
+to use a DSA certificate on the server side (i.e.
+{{EX:TLSCertificateKeyFile}} points to a DSA key).  Multiple sets
+of parameters can be included in the file; all of them will be
+processed.  Parameters can be generated using the following command
 
 >	openssl dhparam [-dsaparam] -out <filename> <numbits>
 
@@ -176,8 +181,8 @@
 individual users in their {{.ldaprc}} files.
 
 The LDAP Start TLS operation is used in LDAP to initiate TLS
-negotatation.  All OpenLDAP command line tools support a {{E:-Z}}
-and {{E:-ZZ}} flag to indicate whether a Start TLS operation is to
+negotiation.  All OpenLDAP command line tools support a {{EX:-Z}}
+and {{EX:-ZZ}} flag to indicate whether a Start TLS operation is to
 be issued.  The latter flag indicates that the tool is to cease
 processing if TLS cannot be started while the former allows the
 command to continue.
@@ -185,7 +190,7 @@
 In LDAPv2 environments, TLS is normally started using the LDAP
 Secure URI scheme ({{EX:ldaps://}}) instead of the normal LDAP URI
 scheme ({{EX:ldap://}}).  OpenLDAP command line tools allow either
-scheme to used with the {{EX:-U}} flag and with the {{EX:URI}}
+scheme to used with the {{EX:-H}} flag and with the {{EX:URI}}
 {{ldap.conf}}(5) option.
 
 

Copied: openldap/trunk/doc/guide/admin/troubleshooting.sdf (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/admin/troubleshooting.sdf)
===================================================================
--- openldap/trunk/doc/guide/admin/troubleshooting.sdf	                        (rev 0)
+++ openldap/trunk/doc/guide/admin/troubleshooting.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,104 @@
+# $OpenLDAP: pkg/openldap-guide/admin/troubleshooting.sdf,v 1.10.2.3 2007/11/07 23:01:35 ghenry Exp $
+# Copyright 2007 The OpenLDAP Foundation, All Rights Reserved.
+# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
+
+H1: Troubleshooting
+
+If you're having trouble using OpenLDAP, get onto the
+OpenLDAP-Software mailing list, or:
+
+* Browse the list archives at {{URL:http://www.openldap.org/lists/#archives}} 
+* Search the FAQ at {{URL:http://www.openldap.org/faq/}}
+* Search the Issue Tracking System at {{URL:http://www.openldap.org/its/}}
+
+Chances are the problem has been solved and explained in detail many times before.
+
+H2: User or Software errors?
+
+More often than not, an error is caused by a configuration problem or a misunderstanding
+of what you are trying to implement and/or achieve. 
+
+We will now attempt to discuss common user errors.
+
+H2: Checklist
+
+The following checklist can help track down your problem. Please try to use if {{B:before}}
+posting to the list, or in the rare circumstances of reporting a bug.
+
+.{{S: }}
+^{{B: Use the {{slaptest}} tool to verify configurations before starting {{slapd}}}}
+
+.{{S: }}
++{{B: Verify that {{slapd}} is listening to the specified port(s) (389 and 636, generally) before trying the {{ldapsearch}}}}
+
+.{{S: }}
++{{B: Can you issue an {{ldapsearch}}?}}
+
+.{{S: }}
++{{B: If not, have you enabled complex ACLs without fully understanding them?}}
+
+.{{S: }}
++{{B: Do you have a system wide LDAP setting pointing to the wrong LDAP Directory?}}
+
+.{{S: }}
++{{B: Are you using TLS?}}
+
+.{{S: }}
++{{B: Have your certificates expired?}}
+
+H2: OpenLDAP Bugs
+
+Sometimes you may encounter an actual OpenLDAP bug, in which case please visit 
+our Issue Tracking system {{URL:http://www.openldap.org/its/}} and report it.
+However, make sure it's not already a known bug or a common user problem.
+
+* bugs in historic versions of OpenLDAP will not be considered;
+* bugs in released versions that are no longer present in HEAD code, 
+either because they have been fixed or because they no longer apply, 
+will not be considered as well;
+* bugs in distributions of OpenLDAP software that are not related to the 
+software as provided by OpenLDAP will not be considered; in those cases please 
+refer to the distributor.
+
+Note: Our Issue Tracking system is {{B:NOT}} for OpenLDAP {{B:Support}}, please join our
+mailing Lists: {{URL:http://www.openldap.org/lists/}} for that.
+
+The information you should provide in your bug report is discussed in our FAQ-O-MATIC at
+{{URL:http://www.openldap.org/faq/data/cache/59.html}}
+
+H2: 3rd party software error
+
+The OpenLDAP Project only supports OpenLDAP software. 
+
+You may however seek commercial support ({{URL:http://www.openldap.org/support/}}) or join 
+the general LDAP forum for non-commercial discussions and information relating to LDAP at: 
+{{URL:http://www.umich.edu/~dirsvcs/ldap/mailinglist.html}}
+
+
+H2: How to contact the OpenLDAP Project
+
+* Mailing Lists: {{URL:http://www.openldap.org/lists/}}
+* Project: {{URL: http://www.openldap.org/project/}}
+* Issue Tracking: {{URL:http://www.openldap.org/its/}}
+
+
+H2: How to present your problem
+
+
+H2: Debugging {{slapd}}(8)
+
+After reading through the above sections and before e-mailing the OpenLDAP lists, you
+might want to try out some of the following to track down the cause of your problems:
+
+* Loglevel 256 is generally a good first loglevel to try for getting 
+  information useful to list members on issues
+* Running {{slapd -d -1}} can often track down fairly simple issues, such as 
+  missing schemas and incorrect file permissions for the {{slapd}} user to things like certs
+* Check your logs for errors, as discussed at {{URL:http://www.openldap.org/faq/data/cache/358.html}}
+
+H2: Commercial Support
+
+The firms listed at {{URL:http://www.openldap.org/support/}} offer technical support services catering to OpenLDAP community. 
+
+The listing of any given firm should not be viewed as an endorsement or recommendation of any kind, nor as otherwise indicating 
+there exists a business relationship or an affiliation between any listed firm and the OpenLDAP Foundation or the OpenLDAP Project or its contributors.

Modified: openldap/trunk/doc/guide/admin/tuning.sdf
===================================================================
--- openldap/trunk/doc/guide/admin/tuning.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/admin/tuning.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,90 +1,345 @@
-# $OpenLDAP: pkg/openldap-guide/admin/tuning.sdf,v 1.8.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/admin/tuning.sdf,v 1.9.2.4 2007/11/07 23:01:35 ghenry Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
-H1: Performance Tuning
+H1: Tuning
 
-Note: this chapter needs to be updated to discuss BDB tuning.
+This is perhaps one of the most important chapters in the guide, because if 
+you have not tuned {{slapd}}(8) correctly or grasped how to design your
+directory and environment, you can expect very poor performance.
 
-There are several things you can do to tune the performance of
-slapd for your system. Most of them have to do with the LDBM
-backend. LDBM uses an index mechanism to store and retrieve
-information in slapd. Each entry is assigned a unique ID, used to
-refer to the entry in the indexes. A search for entries with a
-surname of "Jensen", for example, would look up the index entry
-"=JENSEN" in the surname index. The data returned is a list of
-IDs of entries having that value for the surname attribute. We
-have found several things to be useful in improving the
-performance of this indexing scheme, especially on modify
-operations.
+Reading, understanding and experimenting using the instructions and information
+in the following sections, will enable you to fully understand how to tailor 
+your directory server to your specific requirements.
 
+It should be noted that the following information has been collected over time
+from our community based FAQ. So obviously the benefit of this real world experience
+and advice should be of great value to the reader.
 
 
-H2: The allIDs threshold
+H2: Performance Factors
 
-Some index entries become so large as to be useless. For
-example, if every entry in your database is a person entry, the
-"=PERSON" index entry in the objectclass index contains every
-entry. This returns very little useful information, and can cause
-significant delays, especially on updates. To alleviate this
-problem, we have introduced the idea of an allIDs index entry.
+Various factors can play a part in how your directory performs on your chosen 
+hardware and environment. We will attempt to discuss these here.
 
-The allIDs entry stands for a real index entry containing the IDs
-of every entry in the database, but it takes up very little space,
-never needs updating, and can be manipulated quickly and
-efficiently. The trade-off is that it does not prune the set of
-candidate entries at all during a search. This must be done
-using other, more "high-powered" index entries.
 
-You can set the minimum number of IDs that an index entry may
-contain before it turns into an allIDs block by changing the
-{{EX: SLAPD_LDBM_MIN_MAXIDS}} variable in the
-{{EX: include/ldapconfig.h}} file. The actual number is determined at
-runtime by the LDBM backend, depending on the block size of
-the underlying device (i.e., the number you provide is rounded up
-to the nearest multiple of a block size).
+H3: Memory
 
+Scale your cache to use available memory and increase system memory if you can.
 
+More info here.
 
-H2: The entry cache
 
-The LDBM backend can be configured to keep a cache of
-entries in memory. Since the LDBM database spends much of its
-time reading entries from the id2entry file into memory, this cache
-can greatly speed performance. The trade-off is that the cache
-uses some extra memory. The default cache size is 1000
-entries. See the discussion of the cachesize option in Section
-5.2.3 on LDBM configuration.
+H3: Disks
 
+Use fast subsystems. Put each database and logs on separate disks.
 
+Example showing config settings
 
-H2: The DB cache
 
-The LDBM backend uses a number of disk-based index files. If
-the underlying hash or B-tree package supports in-memory
-caching of these files, performance can be greatly improved,
-especially on modifies. The size of this in-memory file cache is
-given by the dbcachesize option, discussed in more detail in
-section 5.2.3 on LDBM configuration. The default {{EX: dbcachesize}} is
-100K.
+H3: Network Topology
 
+http://www.openldap.org/faq/data/cache/363.html
 
+Drawing here.
 
-H2: Maintain the right indices
 
-Finally, one of the best performance tune-ups you can do is to
-make sure you are maintaining the right indices. Too few indices
-can lead to poor search performance. Too many indices can
-lead to poor update performance. For example, the LDBM
-backend would be perfectly happy to maintain substring and
-approximate indices for the {{EX: objectclass attribute}}, but this would
-not be useful and would just slow down update operations. If
-your database has many entries and is handling queries for
-substring equality on the surname attribute, you should make
-sure to maintain a surname substring index so these queries are
-answered quickly.
+H3: Directory Layout Design
 
-So, take a look at the index lines in your slapd configuration file to
-ensure that only those indices that make sense and are needed
-are being maintained.
+Reference to other sections and good/bad drawing here.
 
+
+H3: Expected Usage
+
+Discussion.
+
+
+H2: Indexes
+
+H3: Understanding how a search works
+
+If you're searching on a filter that has been indexed, then the search reads 
+the index and pulls exactly the entries that are referenced by the index. 
+If the filter term has not been indexed, then the search must read every single
+ entry in the target scope and test to see if each entry matches the filter. 
+Obviously indexing can save a lot of work when it's used correctly.
+
+H3: What to index
+
+You should create indices to match the actual filter terms used in
+search queries. 
+
+>        index cn,sn,givenname,mail eq
+
+Each attribute index can be tuned further by selecting the set of index types to generate. For example, substring and approximate search for organizations (o) may make little sense (and isn't like done very often). And searching for {{userPassword}} likely makes no sense what so ever.
+
+General rule: don't go overboard with indexes. Unused indexes must be maintained and hence can only slow things down. 
+
+See {{slapd.conf}}(8) and {{slapdindex}}(8) for more information
+
+
+H3: Presence indexing
+
+If your client application uses presence filters and if the
+target attribute exists on the majority of entries in your target scope, then
+all of those entries are going to be read anyway, because they are valid
+members of the result set. In a subtree where 100% of the
+entries are going to contain the same attributes, the presence index does
+absolutely NOTHING to benefit the search, because 100% of the entries match
+that presence filter. 
+
+So the resource cost of generating the index is a
+complete waste of CPU time, disk, and memory. Don't do it unless you know
+that it will be used, and that the attribute in question occurs very
+infrequently in the target data. 
+
+Almost no applications use presence filters in their search queries. Presence
+indexing is pointless when the target attribute exists on the majority of
+entries in the database. In most LDAP deployments, presence indexing should
+not be done, it's just wasted overhead.
+
+See the {{Logging}} section below on what to watch our for if you have a frequently searched
+for attribute that is unindexed.
+
+
+H2: Logging
+
+H3: What log level to use
+
+The default of {{loglevel 256}} is really the best bet. There's a corollary to 
+this when problems *do* arise, don't try to trace them using syslog. 
+Use the debug flag instead, and capture slapd's stderr output. syslog is too 
+slow for debug tracing, and it's inherently lossy - it will throw away messages when it
+can't keep up.
+
+Contrary to popular belief, {{loglevel 0}} is not ideal for production as you 
+won't be able to track when problems first arise.
+
+H3: What to watch out for
+
+The most common message you'll see that you should pay attention to is:
+
+>  "<= bdb_equality_candidates: (foo) index_param failed (18)"
+
+That means that some application tried to use an equality filter ({{foo=<somevalue>}}) 
+and attribute {{foo}} does not have an equality index. If you see a lot of these
+messages, you should add the index. If you see one every month or so, it may
+be acceptable to ignore it.
+
+The default syslog level is 256 which logs the basic parameters of each
+request; it usually produces 1-3 lines of output. On Solaris and systems that
+only provide synchronous syslog, you may want to turn it off completely, but
+usually you want to leave it enabled so that you'll be able to see index
+messages whenever they arise. On Linux you can configure syslogd to run
+asynchronously, in which case the performance hit for moderate syslog traffic
+pretty much disappears.
+
+H3: Improving throughput
+
+You can improve logging performance on some systems by configuring syslog not 
+to sync the file system with every write ({{man syslogd/syslog.conf}}). In Linux, 
+you can prepend the log file name with a "-" in {{syslog.conf}}. For example, 
+if you are using the default LOCAL4 logging you could try:
+
+>   # LDAP logs
+>   LOCAL4.*         -/var/log/ldap
+
+For syslog-ng, add or modify the following line in {{syslog-ng.conf}}:
+
+>   options { sync(n); };
+
+where n is the number of lines which will be buffered before a write.
+
+
+H2: BDB/HDB Database Caching
+
+We all know what caching is, don't we? 
+
+In brief, "A cache is a block of memory for temporary storage of data likely 
+to be used again" - {{URL:http://en.wikipedia.org/wiki/Cache}}
+
+There are 3 types of caches, BerkeleyDB's own cache, {{slapd}}(8) 
+entry cache and {{TERM:IDL}} (IDL) cache.
+
+
+H3: Berkeley DB Cache
+
+BerkeleyDB's own data cache operates on page-sized blocks of raw data.
+
+Note that while the {{TERM:BDB}} cache is just raw chunks of memory and 
+configured as a memory size, the {{slapd}}(8) entry cache holds parsed entries, 
+and the size of each entry is variable. 
+
+There is also an IDL cache which is used for Index Data Lookups. 
+If you can fit all of your database into slapd's entry cache, and all of your 
+index lookups fit in the IDL cache, that will provide the maximum throughput. 
+
+If not, but you can fit the entire database into the BDB cache, then you 
+should do that and shrink the slapd entry cache as appropriate. 
+
+Failing that, you should balance the BDB cache against the entry cache.
+
+It is worth noting that it is not absolutely necessary to configure a BerkeleyDB 
+cache equal in size to your entire database. All that you need is a cache 
+that's large enough for your "working set." 
+
+That means, large enough to hold all of the most frequently accessed data, 
+plus a few less-frequently accessed items.
+
+ORACLE LINKS HERE
+
+H4: Calculating Cachesize
+
+The back-bdb database lives in two main files, {{F:dn2id.bdb}} and {{F:id2entry.bdb}}. 
+These are B-tree databases. We have never documented the back-bdb internal 
+layout before, because it didn't seem like something anyone should have to worry 
+about, nor was it necessarily cast in stone. But here's how it works today, 
+in OpenLDAP 2.4.
+
+A B-tree is a balanced tree; it stores data in its leaf nodes and bookkeeping 
+data in its interior nodes (If you don't know what tree data structures look
+ like in general, Google for some references, because that's getting far too 
+elementary for the purposes of this discussion).
+
+For decent performance, you need enough cache memory to contain all the nodes 
+along the path from the root of the tree down to the particular data item 
+you're accessing. That's enough cache for a single search. For the general case, 
+you want enough cache to contain all the internal nodes in the database. 
+
+>   db_stat -d
+
+will tell you how many internal pages are present in a database. You should 
+check this number for both dn2id and id2entry.
+
+Also note that {{id2entry}} always uses 16KB per "page", while {{dn2id}} uses whatever 
+the underlying filesystem uses, typically 4 or 8KB. To avoid thrashing the, 
+your cache must be at least as large as the number of internal pages in both 
+the {{dn2id}} and {{id2entry}} databases, plus some extra space to accommodate the actual 
+leaf data pages.
+
+For example, in my OpenLDAP 2.4 test database, I have an input LDIF file that's 
+about 360MB. With the back-hdb backend this creates a {{dn2id.bdb}} that's 68MB, 
+and an {{id2entry}} that's 800MB. db_stat tells me that {{dn2id}} uses 4KB pages, has 
+433 internal pages, and 6378 leaf pages. The id2entry uses 16KB pages, has 52 
+internal pages, and 45912 leaf pages. In order to efficiently retrieve any 
+single entry in this database, the cache should be at least
+
+>   (433+1) * 4KB + (52+1) * 16KB in size: 1736KB + 848KB =~ 2.5MB.
+
+This doesn't take into account other library overhead, so this is even lower 
+than the barest minimum. The default cache size, when nothing is configured, 
+is only 256KB. 
+
+This 2.5MB number also doesn't take indexing into account. Each indexed attribute 
+uses another database file of its own, using a Hash structure. 
+
+Unlike the B-trees, where you only need to touch one data page to find an entry 
+of interest, doing an index lookup generally touches multiple keys, and the 
+point of a hash structure is that the keys are evenly distributed across the 
+data space. That means there's no convenient compact subset of the database that 
+you can keep in the cache to insure quick operation, you can pretty much expect 
+references to be scattered across the whole thing. My strategy here would be to 
+provide enough cache for at least 50% of all of the hash data. 
+
+>   (Number of hash buckets + number of overflow pages + number of duplicate pages) * page size / 2.
+
+The objectClass index for my example database is 5.9MB and uses 3 hash buckets 
+and 656 duplicate pages. So:
+
+>   ( 3 + 656 ) * 4KB / 2 =~ 1.3MB.
+
+With only this index enabled, I'd figure at least a 4MB cache for this backend. 
+(Of course you're using a single cache shared among all of the database files, 
+so the cache pages will most likely get used for something other than what you 
+accounted for, but this gives you a fighting chance.)
+
+With this 4MB cache I can slapcat this entire database on my 1.3GHz PIII in 
+1 minute, 40 seconds. With the cache doubled to 8MB, it still takes the same 1:40s. 
+Once you've got enough cache to fit the B-tree internal pages, increasing it 
+further won't have any effect until the cache really is large enough to hold 
+100% of the data pages. I don't have enough free RAM to hold all the 800MB 
+id2entry data, so 4MB is good enough.
+
+With back-bdb and back-hdb you can use "db_stat -m" to check how well the 
+database cache is performing. 
+
+
+H3: {{slapd}}(8) Entry Cache
+
+The {{slapd}}(8) entry cache operates on decoded entries. The rationale - entries 
+in the entry cache can be used directly, giving the fastest response. If an entry 
+isn't in the entry cache but can be extracted from the BDB page cache, that will 
+avoid an I/O but it will still require parsing, so this will be slower. 
+
+If the entry is in neither cache then BDB will have to flush some of its current 
+cached pages and bring in the needed pages, resulting in a couple of expensive 
+I/Os as well as parsing.
+
+As far as balancing the entry cache vs the BDB cache - parsed entries in memory 
+are generally about twice as large as they are on disk. 
+
+As we have already mentioned, not having a proper database cache size will 
+cause performance issues. These issues are not an indication of corruption 
+occurring in the database. It is merely the fact that the cache is thrashing 
+itself that causes performance/response time to slowdown. 
+
+
+MOVE BELOW AROUND:
+
+
+If you want to setup the cache size, please read:
+
+ (Xref) How do I configure the BDB backend?
+ (Xref) What are the DB_CONFIG configuration directives?
+ http://www.sleepycat.com/docs/utility/db_recover.html
+
+A default config can be found in the answer:
+
+ (Xref) What are the DB_CONFIG configuration directives?
+
+just change the set_lg_dir to point to your .log directory or comment that line.
+
+Quick guide:
+* Create a DB_CONFIG file in your ldap home directory (/var/lib/ldap/DB_CONFIG) with the correct "set_cachesize" value
+* stop your ldap server and run db_recover -h /var/lib/ldap
+* start your ldap server and check the new cache size with:
+
+  db_stat -h /var/lib/ldap -m | head -n 2
+
+* this procedure is only needed if you use OpenLDAP 2.2 with the BDB or HDB backends; In OpenLDAP 2.3 DB recovery is performed automatically whenever the DB_CONFIG file is changed or when an unclean shutdown is detected.
+
+
+--On Tuesday, February 22, 2005 12:15 PM -0500 Dusty Doris <openldap at mail.doris.cc> wrote:
+
+    Few questions, if you change the cachesize and idlecachesize entries, do
+    you have to do anything special aside from restarting slapd, such as run
+    slapindex or db_recover?
+
+
+    Also, is there any way to tell how much memory these caches are taking up
+    to make sure they are not set too large?  What happens if you set your
+    cachesize too large and you don't have enough available memory to store
+    these?  Will that cause an issue with openldap, or will it just not cache
+    those entries that would make it exceed its available memory.  Will it
+    just use some sort of FIFO on those caches?
+
+
+It will consume the memory resources of your system, and likely cause issues.
+
+    Finally, what do most people try to achieve with these values?  Would the
+    goal be to make these as big as the directory?  So, if I have 400,000 dn's
+    in my directory, would it be safe to set these at 400000 or would
+    something like 20,000 be good enough to get a nice performance increase?
+
+
+I try to cache the most actively used entries. Unless you expect all 400,000 entries of your DB to be accessed regularly, there is no need to cache that many entries. My entry cache is set to 20,000 (out of a little over 400,000 entries).
+
+The idlcache has to do with how many unique result sets of searches you want to store in memory. Setting up this cache will allow your most frequently placed searches to get results much faster, but I doubt you want to try and cache the results of every search that hits your system. ;)
+
+--Quanah
+
+
+H3: {{TERM:IDL}} Cache
+
+
+http://www.openldap.org/faq/data/cache/1076.html

Copied: openldap/trunk/doc/guide/images/src (from rev 891, openldap/vendor/openldap-2.4.7/doc/guide/images/src)

Modified: openldap/trunk/doc/guide/plain.sdf
===================================================================
--- openldap/trunk/doc/guide/plain.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/plain.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/plain.sdf,v 1.10.2.2 2007/01/02 21:43:43 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/plain.sdf,v 1.11.2.2 2007/08/31 23:48:46 quanah Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -13,7 +13,7 @@
 !macro HTML_FOOTER
 {{INLINE:<FONT COLOR="#808080" FACE="Arial,Verdana,Helvetica" SIZE="1">}}
 {{INLINE:<B>________________<BR><SMALL>}}
-[[c]]  Copyright 2005,
+[[c]]  Copyright 2007,
 {{INLINE:<A HREF="/foundation/">OpenLDAP Foundation</A>}},
 {{EMAIL: info at OpenLDAP.org}}
 {{INLINE:</SMALL><BR></B></FONT>}}

Modified: openldap/trunk/doc/guide/preamble.sdf
===================================================================
--- openldap/trunk/doc/guide/preamble.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/preamble.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/preamble.sdf,v 1.63.2.5 2007/01/02 21:46:44 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/preamble.sdf,v 1.70.2.4 2007/08/31 23:48:46 quanah Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
  
@@ -6,14 +6,14 @@
 # Preamble for all OpenLDAP SDF documents
 #
 
-!default VERSION 2.3
+!default VERSION 2.4
 
 #
 # Paths are relative to the main subdirectories
 #
 
 !define DOC_AUTHOR	"The OpenLDAP Project <{{URL:http://www.openldap.org/}}>"
-!define DOC_NAME    "OpenLDAP Software 2.3"
+!define DOC_NAME    "OpenLDAP Software 2.4"
 !define DOC_TYPE    "Guide"
 
 !define DOC_LOGO	"../images/LDAPlogo.gif"
@@ -55,7 +55,7 @@
 <P>
 <FONT COLOR="#808080" FACE="Arial,Verdana,Helvetica" SIZE="1"><B>
 ________________<BR>
-<SMALL>&copy; Copyright 2006, <A HREF="http://www.OpenLDAP.org/foundation/">OpenLDAP Foundation</A>, <A HREF="mailto:info at OpenLDAP.org">info at OpenLDAP.org</A></SMALL></B></FONT>
+<SMALL>&copy; Copyright 2007, <A HREF="http://www.OpenLDAP.org/foundation/">OpenLDAP Foundation</A>, <A HREF="mailto:info at OpenLDAP.org">info at OpenLDAP.org</A></SMALL></B></FONT>
 
 	!endblock
 !endmacro
@@ -91,141 +91,219 @@
 <P>
 <FONT COLOR="#808080" FACE="Arial,Verdana,Helvetica" SIZE="1"><B>
 ________________<BR>
-<SMALL>&copy; Copyright 2006, <A HREF="http://www.OpenLDAP.org/foundation/">OpenLDAP Foundation</A>, <A HREF="mailto:info at OpenLDAP.org">info at OpenLDAP.org</A></SMALL></B></FONT>
+<SMALL>&copy; Copyright 2007, <A HREF="http://www.OpenLDAP.org/foundation/">OpenLDAP Foundation</A>, <A HREF="mailto:info at OpenLDAP.org">info at OpenLDAP.org</A></SMALL></B></FONT>
 
 	!endblock
 !endmacro
 
 
 # OpenLDAP related organization
-!block organisations; data
+!block organisations; data; sort='Name'
 Name|Long|Jump
 ANSI|American National Standards Institute|http://www.ansi.org/
-BSI|British Standards Institute|http://www.bsa-global.com/
-OpenLDAP|OpenLDAP|http://www.openldap.org/
-OLF|OpenLDAP Foundation|http://www.openldap.org/foundation/
-OLP|OpenLDAP Project|http://www.openldap.org/project/
-UM|University of Michigan|http://www.umich.edu/
-UMLDAP|University of Michigan LDAP|http://www.umich.edu/~dirsvcs/ldap/ldap.html
+BSI|British Standards Institute|http://www.bsi-global.com/
+COSINE|Co-operation and Open Systems Interconnection in Europe
+CPAN|Comprehensive Perl Archive Network|http://cpan.org/
+Cyrus|Project Cyrus|http://cyrusimap.web.cmu.edu/
+FSF|Free Software Foundation|http://www.fsf.org/
+GNU|GNU Not Unix Project|http://www.gnu.org/
+IAB|Internet Architecture Board|http://www.iab.org/
 IANA|Internet Assigned Numbers Authority|http://www.iana.org/
-IAB|Internet Architecture Board|http://www.iab.org/
+IEEE|Institute of Electrical and Electronics Engineers|http://www.ieee.org
+IESG|Internet Engineering Steering Group|http://www.ietf.org/iesg/
 IETF|Internet Engineering Task Force|http://www.ietf.org/
-IESG|Internet Engineering Steering Group|http://www.ietf.org/iesg/
 IRTF|Internet Research Task Force|http://www.irtf.org/
 ISO|International Standards Organisation|http://www.iso.org/
+ISOC|Internet Society|http://www.isoc.org/
 ITU|International Telephone Union|http://www.itu.int/
-RFC|RFC Editor|http://www.rfc-editor.org/
-OpenSSL|OpenSSL|http://www.openssl.org/
-Cyrus|Cyrus Electronic Mail Project|http://asg.web.cmu.edu/cyrus/
-Sleepycat|Sleepycat Software|http://www.sleepycat.com/
-FSF|Free Software Foundation|http://www.fsf.org/
-GNU|GNU Not Unix|http://www.gnu.org/
+OLF|OpenLDAP Foundation|http://www.openldap.org/foundation/
+OLP|OpenLDAP Project|http://www.openldap.org/project/
+OpenSSL|OpenSSL Project|http://www.openssl.org/
+RFC Editor|RFC Editor|http://www.rfc-editor.org/
+Oracle|Oracle Corporation|http://www.oracle.com/
+UM|University of Michigan|http://www.umich.edu/
+UMLDAP|University of Michigan LDAP Team|http://www.umich.edu/~dirsvcs/ldap/ldap.html
 !endblock
 
-!block products; data
+!block products; data; sort='Name'
 Name|Jump
-Berkeley DB|http://www.sleepycat.com/products/transactional.shtml
+Berkeley DB|http://www.oracle.com/database/berkeley-db/db/index.html
 CVS|http://www.cvshome.org/
-Cyrus|http://asg.web.cmu.edu/cyrus/
+Cyrus|http://cyrusimap.web.cmu.edu/generalinfo.html
+Cyrus SASL|http://asg.web.cmu.edu/sasl/sasl-library.html
 GNU|http://www.gnu.org/software/
-GDBM|http://www.gnu.org/software/gdbm/
+GnuTLS|http://www.gnu.org/software/gnutls/
 Heimdal|http://www.pdc.kth.se/heimdal/
+JLDAP|http://www.openldap.org/jldap/
 MIT Kerberos|http://web.mit.edu/kerberos/www/
-OpenLDAP|http://www.openldap.org/software/
+OpenLDAP|http://www.openldap.org/
+OpenLDAP FAQ|http://www.openldap.org/faq/
+OpenLDAP ITS|http://www.openldap.org/its/
+OpenLDAP Software|http://www.openldap.org/software/
 OpenSSL|http://www.openssl.org/
 Perl|http://www.perl.org/
-SASL|http://asg.web.cmu.edu/sasl/sasl-library.html
-SQL|http://www.jcc.com/SQLPages/jccs_sql.htm
-TCL|http://www.tcl.tk/
+SDF|http://search.cpan.org/src/IANC/sdf-2.001/doc/catalog.html
+UMLDAP|http://www.umich.edu/~dirsvcs/ldap/ldap.html
 !endblock
 
 # Internet and X.500 terms
-!block terms; data
+!block terms; data; sort='Term'
 Term|Definition
+3DES|Triple DES
+ABNF|Augmented Backus-Naur Form
+ACDF|Access Control Decision Function
+ACE|ASCII Compatible Encoding
+ASCII|American Standard Code for Information Interchange
+ACID|Atomicity, Consistency, Isolation, and Durability
+ACI|Access Control Information
+ACL|Access Control List
 AES|Advance Encryption Standard
+ABI|Application Binary Interface
 API|Application Program Interface
-ASN|Abstract Syntax Notation
-ASN.1|Abstract Syntax Notation 1
-BCP|Best Common Practice
-BDB|Berkeley DB
+ASN.1|Abstract Syntax Notation - One
+AVA|Attribute Value Assertion
+AuthcDN|Authentication DN
+AuthcId|Authentication Identity
+AuthzDN|Authorizaiton DN
+AuthzId|Authorization Identity
+BCP|Best Current Practice
+BDB|Berkeley DB (Backend)
 BER|Basic Encoding Rules
-BNF|BNF
+BNF|Backus-Naur Form
 C|The C Programming Language
 CA|Certificate Authority
+CER|Canonical Encoding Rules
 CLDAP|Connection-less LDAP
+CN|Common Name
+CRAM-MD5|SASL MD5 Challedge/Response Authentication Mechanism
+CRL|Certificate Revocation List
 DAP|Directory Access Protocol
+DC|Domain Component
 DER|Distinguished Encoding Rules
 DES|Data Encryption Standard
-3DES|Triple DES
+DIB|Directory Information Base
+DIGEST-MD5|SASL Digest MD5 Authentication Mechanism
+DISP|Directory Information Shadowing Protocol
 DIT|Directory Information Tree
+DNS|Domain Name System
 DN|Distinguished Name
-DNS|Domain Name System
+DOP|Directory Operational Binding Management Protocol
+DSAIT|DSA Information Tree
+DSA|Directory System Agent
+DSE|DSA-specific Entry
+DSP|Directory System Protocol
 DS|Draft Standard
-DSA|Directory Service Agent
-DSE|DSA-specific Entry
 DUA|Directory User Agent
+EXTERNAL|SASL External Authentication Mechanism
 FAQ|Frequently Asked Questions
 FTP|File Transfer Protocol
 FYI|For Your Information
-GSSAPI|Generic Security Services Application Program Interface
-HDB|Heirarchial Database
-I-D|Internet Draft
+GSER|Generic String Encoding Rules
+GSS-API|Generic Security Service Application Program Interface
+GSSAPI|SASL Kerberos V GSS-API Authentication Mechanism
+HDB|Hierarchical Database (Backend)
+I-D|Internet-Draft
+IA5|International Alphabet 5
+IDNA|Internationalized Domain Names in Applications
+IDN|Internationalized Domain Name
+ID|Identification
+ID|Identifier
+IDL|Index Data Lookups
 IP|Internet Protocol
-IPSEC|Internet Protocol Security
+IPC|Inter-process communication
+IPsec|Internet Protocol Security
+IPv4|Internet Protocol, version 4
+IPv6|Internet Protocol, version 6
 ITS|Issue Tracking System
+JPEG|Joint Photographic Experts Group
 Kerberos|Kerberos Authentication Service
 LBER|Lightweight BER
 LDAP|Lightweight Directory Access Protocol
+LDAP Sync|LDAP Content Sychronization
+LDAPv3|LDAP, version 3
 LDIF|LDAP Data Interchange Format
-LDBM|LDAP Database Manager
+MD5|Message Digest 5
 MIB|Management Information Base
+MODDN|Modify DN
+MODRDN|Modify RDN
+NSSR|Non-specific Subordinate Reference
 OID|Object Identifier
 OSI|Open Systems Interconnect
 OTP|One Time Password
+PDU|Protocol Data Unit
 PEM|Privacy Enhanced eMail
+PEN|Private Enterprise Number
+PKCS|Public Key Cryptosystem
+PKI|Public Key Infrastructure
+PKIX|Public Key Infrastructure (X.509)
+PLAIN|SASL Plaintext Password Authentication Mechanism
+POSIX|Portable Operating System Interface
 PS|Proposed Standard
 RDN|Relative Distinguished Name
 RFC|Request for Comments
+RPC|Remote Procedure Call
+RXER|Robust XML Encoding Rules
+SASL|Simple Authentication and Security Layer
+SDF|Simple Document Format
+SDSE|Shadowed DSE
+SHA1|Secure Hash Algorithm 1
+SLAPD|Standalone LDAP Daemon
+SLURPD|Standalone LDAP Update Replication Daemon
+SMTP|Simple Mail Transfer Protocol
+SNMP|Simple Network Management Protocol
+SQL|Structured Query Language
 SRP|Secure Remote Password
 SSF|Security Strength Factor
 SSL|Secure Socket Layer
 STD|Internet Standard
 TCP|Transmission Control Protocol
 TLS|Transport Layer Security
-SASL|Simple Authentication and Security Layer
-SMTP|Simple Mail Transfer Protocol
-SNMP|Simple Network Management Protocol
-STD|Internet Standard
+UCS|Universal Multiple-Octet Coded Character Set
 UDP|User Datagram Protocol
-UNIX|UNIX
+UID|User Identifier
+Unicode|The Unicode Standard
+UNIX|Unix
 URI|Uniform Resource Identifier
 URL|Uniform Resource Locator
+URN|Uniform Resource Name
+UTF-8|8-bit UCS/Unicode Transformation Format
+UTR|Unicode Technical Report
+UUID|Universally Unique Identifier
 WWW|World Wide Web
 X.500|X.500 Directory Services
 X.509|X.509 Public Key and Attribute Certificate Frameworks
+XED|XML Enabled Directory
+XER|XML Encoding Rules
+XML|Extensible Markup Language
+syncrepl|LDAP Sync-based Replication
 !endblock
 
-!block references; data
+!block references; data; sort=Reference; style=grid
 Reference|Status|Document|Jump
+UM-GUIDE|O|The SLAPD and SLURPD Administrators Guide|http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/guide.pdf
 RFC2079|PS|Definition of an X.500 Attribute Type and an Object Class to Hold Uniform Resource Identifers|http://www.rfc-editor.org/rfc/rfc2079.txt
-RFC2222|PS|Simple Authentication and Security Layer|http://www.rfc-editor.org/rfc/rfc2222.txt
-RFC2251|PS|Lightweight Directory Access Protocol (v3)|http://www.rfc-editor.org/rfc/rfc2251.txt
-RFC2252|PS|LDAPv3: Attribute Syntax Definitions|http://www.rfc-editor.org/rfc/rfc2252.txt
-RFC2253|PS|LDAPv3: UTF-8 String Representation of Distinguished Names|http://www.rfc-editor.org/rfc/rfc2253.txt
-RFC2254|PS|The String Representation of LDAP Search Filters|http://www.rfc-editor.org/rfc/rfc2254.txt
-RFC2255|PS|The LDAP URL Format|http://www.rfc-editor.org/rfc/rfc2255.txt
-RFC2256|PS|A Summary of the X.500(96) User Schema for use with LDAPv3|http://www.rfc-editor.org/rfc/rfc2256.txt
 RFC2296|PS|Use of Language Codes in LDAP|http://www.rfc-editor.org/rfc/rfc2296.txt
-RFC2798|INFO|Definition of the inetOrgPerson LDAP Object Class|http://www.rfc-editor.org/rfc/rfc2798.txt
-RFC2829|PS|Authentication Methods for LDAP|http://www.rfc-editor.org/rfc/rfc2829.txt
-RFC2830|PS|LDAPv3: Extension for Transport Layer Security|http://www.rfc-editor.org/rfc/rfc2830.txt
+RFC2307|X|An Approach for Using LDAP as a Network Information Service|http://www.rfc-editor.org/rfc/rfc2307.txt
+RFC2798|I|Definition of the inetOrgPerson LDAP Object Class|http://www.rfc-editor.org/rfc/rfc2798.txt
 RFC2831|PS|Using Digest Authentication as a SASL Mechanism|http://www.rfc-editor.org/rfc/rfc2831.txt
 RFC2849|PS|The LDAP Data Interchange Format|http://www.rfc-editor.org/rfc/rfc2849.txt
 RFC3088|X|OpenLDAP Root Service|http://www.rfc-editor.org/rfc/rfc3088.txt
 RFC3296|PS|Named Subordinate References in LDAP|http://www.rfc-editor.org/rfc/rfc3296.txt
-RFC3377|PS|Lightweight Directory Access Protocol (v3): Technical Specification|http://www.rfc-editor.org/rfc/rfc3377.txt
-RFC3383|BCP|Internet Assigned Numbers Authority (IANA) Considerations for the Lightweight Directory Access Protocol (LDAP)|http://www.rfc-editor.org/rfc/rfc3383.txt
-RFC3384|INFO|Lightweight Directory Access Protocol (version 3) Replication Requirements|http://www.rfc-editor.org/rfc/rfc3384.txt
-RFC3494|INFO|Lightweight Directory Access Protocol version 2 (LDAPv2) to Historic Status|http://www.rfc-editor.org/rfc/rfc3494.txt
-RFC4013|PS|SASLprep: Stringprep Profile for User Names and Passwords
+RFC3384|I|Lightweight Directory Access Protocol (version 3) Replication Requirements|http://www.rfc-editor.org/rfc/rfc3384.txt
+RFC3494|I|Lightweight Directory Access Protocol version 2 (LDAPv2) to Historic Status|http://www.rfc-editor.org/rfc/rfc3494.txt
+RFC4013|PS|SASLprep: Stringprep Profile for User Names and Passwords|http://www.rfc-editor.org/rfc/rfc4013.txt
+RFC4346|PS|The Transport Layer Security (TLS) Protocol, Version 1.1|http://www.rfc-editor.org/rfc/rfc4346.txt
+RFC4422|PS|Simple Authentication and Security Layer (SASL)|http://www.rfc-editor.org/rfc/rfc4422.txt
+RFC4510|PS|Lightweight Directory Access Protocol (LDAP) Technical Specification Roadmap|http://www.rfc-editor.org/rfc/rfc4510.txt
+RFC4511|PS|Lightweight Directory Access Protocol (LDAP): The Protocol|http://www.rfc-editor.org/rfc/rfc4512.txt
+RFC4512|PS|Lightweight Directory Access Protocol (LDAP): Directory Information Models|http://www.rfc-editor.org/rfc/rfc4512.txt
+RFC4513|PS|Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms|http://www.rfc-editor.org/rfc/rfc4513.txt
+RFC4514|PS|Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names|http://www.rfc-editor.org/rfc/rfc4514.txt
+RFC4515|PS|Lightweight Directory Access Protocol (LDAP): String Representation of Search Filters|http://www.rfc-editor.org/rfc/rfc4515.txt
+RFC4516|PS|Lightweight Directory Access Protocol (LDAP): Uniform Resource Locator|http://www.rfc-editor.org/rfc/rfc4516.txt
+RFC4517|PS|Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules|http://www.rfc-editor.org/rfc/rfc4517.txt
+RFC4518|PS|Lightweight Directory Access Protocol (LDAP): Internationalized String Preparation|http://www.rfc-editor.org/rfc/rfc4518.txt
+RFC4519|PS|Lightweight Directory Access Protocol (LDAP): Schema for User Applications|http://www.rfc-editor.org/rfc/rfc4519.txt
+RFC4520|BCP|IANA Considerations for LDAP|http://www.rfc-editor.org/rfc/rfc4520.txt
+RFC4533|X|The Lightweight Directory Access Protocol (LDAP) Content Synchronization Operation|http://www.rfc-editor.org/rfc/rfc4533.txt
 !endblock

Modified: openldap/trunk/doc/guide/release/copyright-plain.sdf
===================================================================
--- openldap/trunk/doc/guide/release/copyright-plain.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/release/copyright-plain.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/release/copyright-plain.sdf,v 1.9.4.2 2007/01/02 21:43:44 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/release/copyright-plain.sdf,v 1.10.2.2 2007/08/31 23:48:46 quanah Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 

Modified: openldap/trunk/doc/guide/release/copyright.sdf
===================================================================
--- openldap/trunk/doc/guide/release/copyright.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/release/copyright.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/release/copyright.sdf,v 1.20.2.4 2007/01/02 21:48:19 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/release/copyright.sdf,v 1.22.2.2 2007/08/31 23:48:46 quanah Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -55,9 +55,11 @@
 
 
 !block nofill
-Portions [[copyright]] 1999-2005 Howard Y.H. Chu.
-Portions [[copyright]] 1999-2005 Symas Corporation.
+Portions [[copyright]] 1999-2007 Howard Y.H. Chu.
+Portions [[copyright]] 1999-2007 Symas Corporation.
 Portions [[copyright]] 1998-2003 Hallvard B. Furuseth.
+Portions [[copyright]] 2007 Gavin Henry
+Portions [[copyright]] 2007 Suretec Systems
 {{All rights reserved.}}
 !endblock
 

Modified: openldap/trunk/doc/guide/release/install.sdf
===================================================================
--- openldap/trunk/doc/guide/release/install.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/release/install.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/release/install.sdf,v 1.21.2.2 2007/01/02 21:43:44 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/release/install.sdf,v 1.23.2.2 2007/08/31 23:48:46 quanah Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
@@ -80,7 +80,7 @@
 + Test the standalone system
 
 .This step requires the standalone LDAP server, {{slapd}}(8),
-with {{HDB}}, {{BDB}}, and/or {{LDBM}} support.
+with {{HDB}} and/or {{BDB}} support.
 
 E:	% make test
 

Modified: openldap/trunk/doc/guide/release/license-plain.sdf
===================================================================
--- openldap/trunk/doc/guide/release/license-plain.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/release/license-plain.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/release/license-plain.sdf,v 1.9.4.2 2007/01/02 21:43:44 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/release/license-plain.sdf,v 1.10.2.2 2007/08/31 23:48:46 quanah Exp $
 # Copyright 1999-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 

Modified: openldap/trunk/doc/guide/release/license.sdf
===================================================================
--- openldap/trunk/doc/guide/release/license.sdf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/guide/release/license.sdf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/openldap-guide/release/license.sdf,v 1.11.4.2 2007/01/02 21:43:44 kurt Exp $
+# $OpenLDAP: pkg/openldap-guide/release/license.sdf,v 1.12.2.2 2007/08/31 23:48:46 quanah Exp $
 # Copyright 2000-2007 The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 

Modified: openldap/trunk/doc/man/Makefile.in
===================================================================
--- openldap/trunk/doc/man/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # man Makefile.in for OpenLDAP
-# $OpenLDAP: pkg/ldap/doc/man/Makefile.in,v 1.8.2.4 2007/01/02 21:43:44 kurt Exp $
+# $OpenLDAP: pkg/ldap/doc/man/Makefile.in,v 1.11.2.2 2007/08/31 23:13:52 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Copied: openldap/trunk/doc/man/Project (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/Project)
===================================================================
--- openldap/trunk/doc/man/Project	                        (rev 0)
+++ openldap/trunk/doc/man/Project	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,5 @@
+.\" Shared Project Acknowledgement Text
+.B "OpenLDAP Software"
+is developed and maintained by The OpenLDAP Project <http://www.openldap.org/>.
+.B "OpenLDAP Software"
+is derived from University of Michigan LDAP 3.3 Release.  

Modified: openldap/trunk/doc/man/man1/Makefile.in
===================================================================
--- openldap/trunk/doc/man/man1/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man1/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # man1 Makefile.in for OpenLDAP
-# $OpenLDAP: pkg/ldap/doc/man/man1/Makefile.in,v 1.8.2.4 2007/01/02 21:43:44 kurt Exp $
+# $OpenLDAP: pkg/ldap/doc/man/man1/Makefile.in,v 1.11.2.2 2007/08/31 23:13:52 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/doc/man/man1/ldapcompare.1
===================================================================
--- openldap/trunk/doc/man/man1/ldapcompare.1	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man1/ldapcompare.1	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAPCOMPARE 1 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapcompare.1,v 1.8.2.5 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapcompare.1,v 1.12.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -56,7 +56,7 @@
 .SH DESCRIPTION
 .I ldapcompare
 is a shell-accessible interface to the
-.BR ldap_compare (3)
+.BR ldap_compare_ext (3)
 library call.
 .LP
 .B ldapcompare
@@ -108,6 +108,18 @@
 .BI \-y \ passwdfile
 Use complete contents of \fIpasswdfile\fP as the password for
 simple authentication.
+Note that \fIcomplete\fP means that any leading or trailing whitespaces,
+including newlines, will be considered part of the password and,
+unlike other software, they will not be stripped.
+As a consequence, passwords stored in files by commands like
+.BR echo (1)
+will not behave as expected, since
+.BR echo (1)
+by default appends a trailing newline to the echoed string.
+The recommended portable way to store a cleartext password in a file
+for use with this option is to use
+.BR slappasswd (8)
+with \fI{CLEARTEXT}\fP as hash and the option \fI\-n\fP.
 .TP
 .BI \-H \ ldapuri
 Specify URI(s) referring to the ldap server(s); only the protocol/host/port
@@ -176,11 +188,8 @@
 .BR ldap.conf (5),
 .BR ldif (5),
 .BR ldap (3),
-.BR ldap_compare (3)
+.BR ldap_compare_ext (3)
 .SH AUTHOR
 The OpenLDAP Project <http://www.openldap.org/>
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man1/ldapdelete.1
===================================================================
--- openldap/trunk/doc/man/man1/ldapdelete.1	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man1/ldapdelete.1	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAPDELETE 1 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapdelete.1,v 1.38.2.5 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapdelete.1,v 1.42.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -59,14 +59,14 @@
 .SH DESCRIPTION
 .I ldapdelete
 is a shell-accessible interface to the
-.BR ldap_delete (3)
+.BR ldap_delete_ext (3)
 library call.
 .LP
 .B ldapdelete
 opens a connection to an LDAP server, binds, and deletes one or more
 entries.  If one or more \fIDN\fP arguments are provided, entries with
 those Distinguished Names are deleted.  Each \fIDN\fP should be provided
-using the LDAPv3 string representation as defined in RFC 2253.
+using the LDAPv3 string representation as defined in RFC 4514.
 If no \fIdn\fP arguments
 are provided, a list of DNs is read from standard input (or from
 \fIfile\fP if the -f flag is used).
@@ -194,11 +194,8 @@
 .BR ldapmodrdn (1),
 .BR ldapsearch (1),
 .BR ldap (3),
-.BR ldap_delete (3)
+.BR ldap_delete_ext (3)
 .SH AUTHOR
 The OpenLDAP Project <http://www.openldap.org/>
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man1/ldapmodify.1
===================================================================
--- openldap/trunk/doc/man/man1/ldapmodify.1	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man1/ldapmodify.1	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAPMODIFY 1 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapmodify.1,v 1.44.2.6 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapmodify.1,v 1.49.2.5 2007/12/10 18:19:13 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -79,6 +79,8 @@
 [\c
 .BI \-y \ passwdfile\fR]
 [\c
+.BI \-H \ ldapuri\fR]
+[\c
 .BI \-h \ ldaphost\fR]
 [\c
 .BI \-p \ ldapport\fR]
@@ -107,9 +109,11 @@
 .SH DESCRIPTION
 .B ldapmodify
 is a shell-accessible interface to the
-.BR ldap_modify (3)
+.BR ldap_add_ext (3),
+.BR ldap_modify_ext (3),
+.BR ldap_delete_ext (3)
 and
-.BR ldap_add (3)
+.BR ldap_rename (3).
 library calls.
 .B ldapadd
 is implemented as a hard link to the ldapmodify tool.  When invoked as
@@ -324,6 +328,7 @@
     title: the world's most famous mythical manager
     mail: bjensen at example.com
     uid: bjensen
+.fi
 .LP
 the command:
 .LP
@@ -342,6 +347,7 @@
 .nf
     dn: cn=Barbara Jensen,dc=example,dc=com
     changetype: delete
+.fi
 .LP
 the command:
 .LP
@@ -360,16 +366,13 @@
 .BR ldapsearch (1),
 .BR ldap.conf (5),
 .BR ldap (3),
-.BR ldap_add (3),
-.BR ldap_delete (3),
-.BR ldap_modify (3),
-.BR ldap_modrdn (3),
+.BR ldap_add_ext (3),
+.BR ldap_delete_ext (3),
+.BR ldap_modify_ext (3),
+.BR ldap_modrdn_ext (3),
 .BR ldif (5),
 .BR slapd.replog (5)
 .SH AUTHOR
 The OpenLDAP Project <http://www.openldap.org/>
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man1/ldapmodrdn.1
===================================================================
--- openldap/trunk/doc/man/man1/ldapmodrdn.1	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man1/ldapmodrdn.1	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAPMODRDN 1 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapmodrdn.1,v 1.34.2.6 2007/04/06 04:31:49 quanah Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapmodrdn.1,v 1.38.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -61,7 +61,7 @@
 .SH DESCRIPTION
 .B ldapmodrdn
 is a shell-accessible interface to the
-.BR ldap_modrdn2 (3)
+.BR ldap_rename (3)
 library call.
 .LP
 .B ldapmodrdn
@@ -220,11 +220,8 @@
 .BR ldapsearch (1),
 .BR ldap.conf (5),
 .BR ldap (3),
-.BR ldap_modrdn2 (3)
+.BR ldap_rename (3)
 .SH AUTHOR
 The OpenLDAP Project <http://www.openldap.org/>
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man1/ldappasswd.1
===================================================================
--- openldap/trunk/doc/man/man1/ldappasswd.1	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man1/ldappasswd.1	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAPPASSWD 1 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldappasswd.1,v 1.36.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldappasswd.1,v 1.39.2.4 2007/12/10 18:19:13 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -47,14 +47,12 @@
 [\c
 .BI \-U \ authcid\fR]
 [\c
-.BI \-R \ authcid\fR]
+.BI \-R \ realm\fR]
 [\c
 .BR \-x ]
 [\c
 .BI \-X \ authzid\fR]
 [\c
-.BI \-R \ realm\fR]
-[\c
 .BI \-Y \ mech\fR]
 [\c
 .BR \-Z[Z] ]
@@ -185,7 +183,4 @@
 .SH AUTHOR
 The OpenLDAP Project <http://www.openldap.org/>
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man1/ldapsearch.1
===================================================================
--- openldap/trunk/doc/man/man1/ldapsearch.1	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man1/ldapsearch.1	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAPSEARCH 1 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapsearch.1,v 1.49.2.13 2007/08/06 15:44:51 ghenry Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapsearch.1,v 1.59.2.4 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -9,6 +9,8 @@
 [\c
 .BR \-n ]
 [\c
+.BR \-c ]
+[\c
 .BR \-u ]
 [\c
 .BR \-v ]
@@ -21,8 +23,6 @@
 [\c
 .BR \-A ]
 [\c
-.BR \-C ]
-[\c
 .BR \-L[L[L]] ]
 [\c
 .BR \-M[M] ]
@@ -108,6 +108,11 @@
 Show what would be done, but don't actually perform the search.  Useful for
 debugging in conjunction with -v.
 .TP
+.B \-c
+Continuous operation mode. Errors are reported, but ldapsearch will continue
+with searches. The default is to exit after reporting an error.  Only useful
+in conjunction with -f.
+.TP
 .B \-u
 Include the User Friendly Name form of the Distinguished Name (DN)
 in the output.
@@ -134,9 +139,6 @@
 see if an attribute is present in an entry and are not interested in the
 specific values.
 .TP
-.B \-C
-Chase referrals (anonymously).
-.TP
 .B \-L
 Search results are display in LDAP Data Interchange Format detailed in
 .BR ldif (5).
@@ -177,6 +179,9 @@
 the character should be encoded as \fB\\25\fP (see RFC 4515).
 If \fIfile\fP is a single
 \fI-\fP character, then the lines are read from standard input.
+.B ldapsearch
+will exit when the first non-successful search result is returned,
+unless -c is used.
 .TP
 .B \-x 
 Use simple authentication instead of SASL.
@@ -196,9 +201,14 @@
 simple authentication.
 .TP
 .BI \-H \ ldapuri
-Specify URI(s) referring to the ldap server(s); only the protocol/host/port
-fields are allowed; a list of URI, separated by whitespace or commas
-is expected.
+Specify URI(s) referring to the ldap server(s);
+a list of URI, separated by whitespace or commas is expected;
+only the protocol/host/port fields are allowed.
+As an exception, if no host/port is specified, but a DN is,
+the DN is used to look up the corresponding host(s) using the
+DNS SRV records, according to RFC 2782.  The DN must be a non-empty
+sequence of AVAs whose attribute type is "dc" (domain component),
+and must be escaped according to RFC 2396.
 .TP
 .BI \-h \ ldaphost
 Specify an alternate host on which the ldap server is running.
@@ -458,7 +468,4 @@
 .SH AUTHOR
 The OpenLDAP Project <http://www.openldap.org/>
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man1/ldapwhoami.1
===================================================================
--- openldap/trunk/doc/man/man1/ldapwhoami.1	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man1/ldapwhoami.1	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAPWHOAMI 1 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapwhoami.1,v 1.6.2.5 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man1/ldapwhoami.1,v 1.10.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -148,7 +148,4 @@
 .SH AUTHOR
 The OpenLDAP Project <http://www.openldap.org/>
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Copied: openldap/trunk/doc/man/man3/Deprecated (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/Deprecated)
===================================================================
--- openldap/trunk/doc/man/man3/Deprecated	                        (rev 0)
+++ openldap/trunk/doc/man/man3/Deprecated	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,7 @@
+Deprecated interfaces generally remain in the library.  The macro
+LDAP_DEPRECATED can be defined to a non-zero value
+(e.g., -DLDAP_DEPRECATED=1) when compiling program designed to use
+deprecated interfaces.  It is recommended that developers writing new
+programs, or updating old programs, avoid use of deprecated interfaces.
+Over time, it is expected that documentation (and, eventually, support) for
+deprecated interfaces to be eliminated.

Modified: openldap/trunk/doc/man/man3/Makefile.in
===================================================================
--- openldap/trunk/doc/man/man3/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # man3 Makefile.in for OpenLDAP
-# $OpenLDAP: pkg/ldap/doc/man/man3/Makefile.in,v 1.8.2.5 2007/01/02 21:43:44 kurt Exp $
+# $OpenLDAP: pkg/ldap/doc/man/man3/Makefile.in,v 1.11.2.2 2007/08/31 23:13:52 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/doc/man/man3/lber-decode.3
===================================================================
--- openldap/trunk/doc/man/man3/lber-decode.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/lber-decode.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,13 +1,9 @@
 .TH LBER_DECODE 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/lber-decode.3,v 1.21.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/lber-decode.3,v 1.23.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ber_get_next, ber_skip_tag, ber_peek_tag, ber_scanf, ber_get_int,
-ber_get_enum, ber_get_stringb, ber_get_stringa, ber_get_stringal,
-ber_get_stringbv, ber_get_null, ber_get_boolean, ber_get_bitstring,
-ber_first_element, ber_next_element
-\- LBER simplified Basic Encoding Rules library routines for decoding
+ber_get_next, ber_skip_tag, ber_peek_tag, ber_scanf, ber_get_int, ber_get_enum, ber_get_stringb, ber_get_stringa, ber_get_stringal, ber_get_stringbv, ber_get_null, ber_get_boolean, ber_get_bitstring, ber_first_element, ber_next_element \- OpenLDAP LBER simplified Basic Encoding Rules library routines for decoding
 .SH LIBRARY
 OpenLDAP LBER (liblber, -llber)
 .SH SYNOPSIS
@@ -104,6 +100,14 @@
 string using
 .BR ber_memfree ().
 .TP
+.B A
+Octet string.  A variant of "\fBa\fP".  A char ** should be supplied.
+Memory is allocated, filled with the contents of the octet string, 
+null-terminated, and returned in the parameter, unless a zero-length
+string would result; in that case, the arg is set to NULL.
+The caller should free the returned string using
+.BR ber_memfree ().
+.TP
 .B s
 Octet string.  A char * buffer should be supplied, followed by a pointer to a
 ber_len_t initialized to the size of the buffer.  Upon return, the
@@ -350,7 +354,4 @@
 .BR lber-sockbuf (3),
 .BR lber-types (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/lber-encode.3
===================================================================
--- openldap/trunk/doc/man/man3/lber-encode.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/lber-encode.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH LBER_ENCODE 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/lber-encode.3,v 1.19.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/lber-encode.3,v 1.21.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ber_alloc_t, ber_flush, ber_printf, ber_put_int, ber_put_enum, ber_put_ostring, ber_put_string, ber_put_null, ber_put_boolean, ber_put_bitstring, ber_start_seq, ber_start_set, ber_put_seq, ber_put_set \- LBER simplified Basic Encoding Rules library routines for encoding
+ber_alloc_t, ber_flush, ber_flush2, ber_printf, ber_put_int, ber_put_enum, ber_put_ostring, ber_put_string, ber_put_null, ber_put_boolean, ber_put_bitstring, ber_start_seq, ber_start_set, ber_put_seq, ber_put_set \- OpenLDAP LBER simplified Basic Encoding Rules library routines for encoding
 .SH LIBRARY
 OpenLDAP LBER (liblber, -llber)
 .SH SYNOPSIS
@@ -13,6 +13,8 @@
 .LP
 .BI "int ber_flush(Sockbuf *" sb ", BerElement *" ber ", int " freeit ");"
 .LP
+.BI "int ber_flush2(Sockbuf *" sb ", BerElement *" ber ", int " freeit ");"
+.LP
 .BI "int ber_printf(BerElement *" ber ", const char *" fmt ", ...);"
 .LP
 .BI "int ber_put_int(BerElement *" ber ", ber_int_t " num ", ber_tag_t " tag ");"
@@ -56,7 +58,7 @@
 to allocate a BER element for encoding,
 .BR ber_printf ()
 to do the actual encoding, and
-.BR ber_flush ()
+.BR ber_flush2 ()
 to actually write the element.  The other routines are provided for those
 applications that need more control than
 .BR ber_printf ()
@@ -70,7 +72,7 @@
 should be called with an argument of LBER_USE_DER.
 .LP
 The
-.BR ber_flush ()
+.BR ber_flush2 ()
 routine is used to actually write the element to a socket
 (or file) descriptor, once it has been fully encoded (using
 .BR ber_printf ()
@@ -78,7 +80,21 @@
 .BR lber-sockbuf (3)
 for more details on the Sockbuf implementation of the \fIsb\fP parameter.
 If the \fIfreeit\fP parameter is non-zero, the supplied \fIber\fP will
-be freed after its contents have been flushed.
+be freed.
+If \fILBER_FLUSH_FREE_ON_SUCCESS\fP is used, the \fIber\fP is only freed
+when successfully flushed, otherwise it is left intact;
+if \fILBER_FLUSH_FREE_ON_ERROR\fP is used, the \fIber\fP is only freed
+when an error occurs, otherwise it is left intact;
+if \fILBER_FLUSH_FREE_ALWAYS\fP is used, the \fIber\fP is freed anyway.
+This function differs from the original
+.BR ber_flush (3)
+function, whose behavior corresponds to that indicated
+for \fILBER_FLUSH_FREE_ON_SUCCESS\fP.
+Note that in the future, the behavior of
+.BR ber_flush (3)
+with \fIfreeit\fP non-zero might change into that of
+.BR ber_flush2 (3)
+with \fIfreeit\fP set to \fILBER_FLUSH_FREE_ALWAYS\fP.
 .LP
 The
 .BR ber_printf ()
@@ -269,7 +285,4 @@
 .BR lber-sockbuf (3),
 .BR lber-types (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/lber-memory.3
===================================================================
--- openldap/trunk/doc/man/man3/lber-memory.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/lber-memory.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH LBER_MEMORY 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/lber-memory.3,v 1.12.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/lber-memory.3,v 1.14.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ber_memalloc, ber_memcalloc, ber_memrealloc, ber_memfree, ber_memvfree \- LBER memory allocators
+ber_memalloc, ber_memcalloc, ber_memrealloc, ber_memfree, ber_memvfree \- OpenLDAP LBER memory allocators
 .SH LIBRARY
 OpenLDAP LBER (liblber, -llber)
 .SH SYNOPSIS
@@ -46,7 +46,4 @@
 .BR lber-types (3)
 .LP
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Copied: openldap/trunk/doc/man/man3/lber-sockbuf.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/lber-sockbuf.3)
===================================================================
--- openldap/trunk/doc/man/man3/lber-sockbuf.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/lber-sockbuf.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,199 @@
+.TH LBER_SOCKBUF 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/lber-sockbuf.3,v 1.2.2.2 2007/08/31 23:13:52 quanah Exp $
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ber_sockbuf_alloc, ber_sockbuf_free, ber_sockbuf_ctrl, ber_sockbuf_add_io, ber_sockbuf_remove_io, Sockbuf_IO \- OpenLDAP LBER I/O infrastructure
+.SH LIBRARY
+OpenLDAP LBER (liblber, -llber)
+.SH SYNOPSIS
+.B #include <lber.h>
+.LP
+.B Sockbuf *ber_sockbuf_alloc( void );
+.LP
+.BI "void ber_sockbuf_free(Sockbuf *" sb ");"
+.LP
+.BI "int ber_sockbuf_ctrl(Sockbuf *" sb ", int " opt ", void *" arg ");"
+.LP
+.BI "int ber_sockbuf_add_io(Sockbuf *" sb ", Sockbuf_IO *" sbio ", int " layer ", void *" arg ");"
+.LP
+.BI "int ber_sockbuf_remove_io(Sockbuf *" sb ", Sockbuf_IO *" sbio ", int " layer ");"
+.LP
+.nf
+.B typedef struct sockbuf_io_desc {
+.BI "int " sbiod_level ";"
+.BI "Sockbuf *" sbiod_sb ";"
+.BI "Sockbuf_IO *" sbiod_io ";"
+.BI "void *" sbiod_pvt ";"
+.BI "struct sockbuf_io_desc *" sbiod_next ";"
+.B } Sockbuf_IO_Desc;
+.LP
+.B typedef struct sockbuf_io {
+.BI "int (*" sbi_setup ")(Sockbuf_IO_Desc *" sbiod ", void *" arg ");"
+.BI "int (*" sbi_remove ")(Sockbuf_IO_Desc *" sbiod ");"
+.BI "int (*" sbi_ctrl ")(Sockbuf_IO_Desc *" sbiod ", int " opt ", void *" arg ");"
+.BI "ber_slen_t (*" sbi_read ")(Sockbuf_IO_Desc *" sbiod ", void *" buf ", ber_len_t " len ");"
+.BI "ber_slen_t (*" sbi_write ")(Sockbuf_IO_Desc *" sbiod ", void *" buf ", ber_len_t " len ");"
+.BI "int (*" sbi_close ")(Sockbuf_IO_Desc *" sbiod ");"
+.B } Sockbuf_IO;
+
+.SH DESCRIPTION
+.LP
+These routines are used to manage the low level I/O operations performed
+by the Lightweight BER library. They are called implicitly by the other
+libraries and usually do not need to be called directly from applications.
+The I/O framework is modularized and new transport layers can be supported
+by appropriately defining a
+.B Sockbuf_IO
+structure and installing it onto an existing
+.BR Sockbuf .
+.B Sockbuf
+structures are allocated and freed by
+.BR ber_sockbuf_alloc ()
+and
+.BR ber_sockbuf_free (),
+respectively. The
+.BR ber_sockbuf_ctrl ()
+function is used to get and set options related to a
+.B Sockbuf
+or to a specific I/O layer of the
+.BR Sockbuf .
+The
+.BR ber_sockbuf_add_io ()
+and
+.BR ber_sockbuf_remove_io ()
+functions are used to add and remove specific I/O layers on a
+.BR Sockbuf .
+
+Options for
+.BR ber_sockbuf_ctrl ()
+include:
+.TP
+.B LBER_SB_OPT_HAS_IO
+Takes a
+.B Sockbuf_IO *
+argument and returns 1 if the given handler is installed
+on the
+.BR Sockbuf ,
+otherwise returns 0.
+.TP
+.B LBER_SB_OPT_GET_FD
+Retrieves the file descriptor associated to the
+.BR Sockbuf ;
+.B arg
+must be a
+.BR "ber_socket_t *" .
+The return value will be 1 if a valid descriptor was present, -1 otherwise.
+.TP
+.B LBER_SB_OPT_SET_FD
+Sets the file descriptor of the
+.B Sockbuf
+to the descriptor pointed to by
+.BR arg ;
+.B arg
+must be a
+.BR "ber_socket_t *" .
+The return value will always be 1.
+.TP
+.B LBER_SB_OPT_SET_NONBLOCK
+Toggles the non-blocking state of the file descriptor associated to
+the
+.BR Sockbuf .
+.B arg
+should be NULL to disable and non-NULL to enable the non-blocking state.
+The return value will be 1 for success, -1 otherwise.
+.TP
+.B LBER_SB_OPT_DRAIN
+Flush (read and discard) all available input on the
+.BR Sockbuf .
+The return value will be 1.
+.TP
+.B LBER_SB_OPT_NEEDS_READ
+Returns non-zero if input is waiting to be read.
+.TP
+.B LBER_SB_OPT_NEEDS_WRITE
+Returns non-zero if the
+.B Sockbuf
+is ready to be written.
+.TP
+.B LBER_SB_OPT_GET_MAX_INCOMING
+Returns the maximum allowed size of an incoming message;
+.B arg
+must be a
+.BR "ber_len_t *" .
+The return value will be 1.
+.TP
+.B LBER_SB_OPT_SET_MAX_INCOMING
+Sets the maximum allowed size of an incoming message;
+.B arg
+must be a
+.BR "ber_len_t *" .
+The return value will be 1.
+
+.LP
+Options not in this list will be passed down to each
+.B Sockbuf_IO
+handler in turn until one of them processes it. If the option is not handled
+.BR ber_sockbuf_ctrl ()
+will return 0.
+
+.LP
+Multiple
+.B Sockbuf_IO
+handlers can be stacked in multiple layers to provide various functionality.
+Currently defined layers include
+.TP
+.B LBER_SBIOD_LEVEL_PROVIDER
+the lowest layer, talking directly to a network 
+.TP
+.B LBER_SBIOD_LEVEL_TRANSPORT
+an intermediate layer
+.TP
+.B LBER_SBIOD_LEVEL_APPLICATION
+a higher layer
+.LP
+Currently defined
+.B Sockbuf_IO
+handlers in liblber include
+.TP
+.B ber_sockbuf_io_tcp
+The default stream-oriented provider
+.TP
+.B ber_sockbuf_io_fd
+A stream-oriented provider for local IPC sockets
+.TP
+.B ber_sockbuf_io_dgram
+A datagram-oriented provider. This handler is only present if the liblber
+library was built with LDAP_CONNECTIONLESS defined.
+.TP
+.B ber_sockbuf_io_readahead
+A buffering layer, usually used with a datagram provider to hide the
+datagram semantics from upper layers.
+.TP
+.B ber_sockbuf_io_debug
+A generic handler that outputs hex dumps of all traffic. This handler
+may be inserted multiple times at arbitrary layers to show the flow
+of data between other handlers.
+.LP
+Additional handlers may be present in libldap if support for them was
+enabled:
+.TP
+.B ldap_pvt_sockbuf_io_sasl
+An application layer handler for SASL encoding/decoding.
+.TP
+.B sb_tls_sbio
+A transport layer handler for SSL/TLS encoding/decoding. Note that this
+handler is private to the library and is not exposed in the API.
+.LP
+The provided handlers are all instantiated implicitly by libldap, and
+applications generally will not need to directly manipulate them.
+
+.SH SEE ALSO
+.BR lber-decode (3),
+.BR lber-encode (3),
+.BR lber-types (3),
+.BR ldap_get_option (3)
+
+.LP
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Modified: openldap/trunk/doc/man/man3/lber-types.3
===================================================================
--- openldap/trunk/doc/man/man3/lber-types.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/lber-types.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,13 +1,9 @@
 .TH LBER_TYPES 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/lber-types.3,v 1.16.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/lber-types.3,v 1.19.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ber_int_t, ber_uint_t, ber_len_t, ber_slen_t, ber_tag_t,
-struct berval, BerValue, BerVarray, BerElement,
-ber_bvfree, ber_bvecfree, ber_bvecadd, ber_bvarray_free, ber_bvarray_add,
-ber_bvdup, ber_dupbv, ber_bvstr, ber_bvstrdup, ber_str2bv, ber_free
-\- LBER types and allocation functions
+ber_int_t, ber_uint_t, ber_len_t, ber_slen_t, ber_tag_t, struct berval, BerValue, BerVarray, BerElement, ber_bvfree, ber_bvecfree, ber_bvecadd, ber_bvarray_free, ber_bvarray_add, ber_bvdup, ber_dupbv, ber_bvstr, ber_bvstrdup, ber_str2bv, ber_alloc_t, ber_init, ber_init2, ber_free \- OpenLDAP LBER types and allocation functions
 .SH LIBRARY
 OpenLDAP LBER (liblber, -llber)
 .SH SYNOPSIS
@@ -50,6 +46,12 @@
 .LP
 .BI "struct berval *ber_str2bv(const char *" str ", ber_len_t " len ", int " dup ", struct berval *" bv ");"
 .LP
+.BI "BerElement *ber_alloc_t(int " options ");"
+.LP
+.BI "BerElement *ber_init(struct berval *" bv ");"
+.LP
+.BI "void ber_init2(BerElement *" ber ", struct berval *" bv ", int " options ");"
+.LP
 .BI "void ber_free(BerElement *" ber ", int " freebuf ");"
 .SH DESCRIPTION
 .LP
@@ -88,7 +90,7 @@
 .B bv_len
 octets.
 .B bv_val
-is not necessarily terminated by a NUL (zero) octet.
+is not necessarily terminated by a NULL (zero) octet.
 .BR ber_bvfree ()
 frees a BerValue, pointed to by \fIbv\fP, returned from this API.  If \fIbv\fP
 is NULL, the routine does nothing.
@@ -151,10 +153,29 @@
 .LP
 .B BerElement
 is an opaque structure used to maintain state information used in
-encoding and decoding.  BerElement structures are created using
-.BR ber_alloc_t (3)
-and
-.BR ber_init (3).
+encoding and decoding.
+.BR ber_alloc_t ()
+is used to create an empty BerElement structure. If
+.B LBER_USE_DER
+is specified for the
+.I options
+parameter then data lengths for data written to the BerElement will be
+encoded in the minimal number of octets required, otherwise they will
+always be written as four byte values. 
+.BR ber_init ()
+creates a BerElement structure that is initialized with a copy of the
+data in its
+.I bv
+parameter.
+.BR ber_init2 ()
+initializes an existing BerElement
+.I ber
+using the data in the
+.I bv
+parameter. The data is referenced directly, not copied. The
+.I options
+parameter is the same as for
+.BR ber_alloc_t ().
 .BR ber_free ()
 frees a BerElement pointed to by \fIber\fP.  If \fIber\fP is NULL, the routine
 does nothing.  If \fIfreebuf\fP is zero, the internal buffer is not freed.
@@ -164,7 +185,4 @@
 .BR lber-memory (3)
 .LP
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH LDAP 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap.3,v 1.34.2.6 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap.3,v 1.40.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap - OpenLDAP Lightweight Directory Access Protocol API
+ldap \- OpenLDAP Lightweight Directory Access Protocol API
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
@@ -14,12 +14,12 @@
 .fi
 .SH DESCRIPTION
 .LP
-The Lightweight Directory Access Protocol (LDAP) (RFC 3377) provides
+The Lightweight Directory Access Protocol (LDAP) (RFC 4510) provides
 access to X.500 directory services.  These services may be stand\-alone
 or part of a distributed directory service.  This client API supports
-LDAP over TCP (RFC2251), LDAP over TLS/SSL, and LDAP over IPC (UNIX
-domain sockets).  This API supports SASL (RFC2829) and Start TLS
-(RFC2830) as well as a number of protocol extensions.  This API is
+LDAP over TCP (RFC 4511), LDAP over TLS/SSL, and LDAP over IPC (UNIX
+domain sockets).  This API supports SASL (RFC 4513) and Start TLS
+(RFC 4513) as well as a number of protocol extensions.  This API is
 loosely based upon IETF/LDAPEXT C LDAP API draft specification, a (orphaned)
 work in progress.
 .LP
@@ -39,16 +39,21 @@
 and set the protocol version to 3 by calling
 .BR ldap_set_option (3).
 The underlying session is established first operation is
-issued.  This would generally be a Start TLS or Bind operation.
+issued.  This would generally be a Start TLS or Bind operation,
+or a Search operation to read attributes of the Root DSE.
 A Start TLS operation is performed by calling
 .BR ldap_start_tls_s (3).
 A LDAP bind operation is performed by calling
 .BR ldap_sasl_bind (3)
-or one of its friends.  Subsequently, other operations are performed
+or one of its friends.
+A Search operation is performed by calling ldap_search_ext_s(3)
+or one of its friends.
+
+Subsequently, additional operations are performed
 by calling one of the synchronous or asynchronous routines (e.g.,
-.BR ldap_search_ext_s (3)
+.BR ldap_compare_ext_s (3)
 or
-.BR ldap_search_ext (3)
+.BR ldap_compare_ext (3)
 followed by
 .BR ldap_result (3)).
 Results returned from these routines are interpreted by calling the
@@ -60,9 +65,9 @@
 .BR ldap_err2string (3).
 .SH LDAP versions
 This library supports version 3 of the Lightweight Directory Access
-Protocol (LDAPv3) as defined in RFC 3377.  It also supports a variant
+Protocol (LDAPv3) as defined in RFC 4510.  It also supports a variant
 of version 2 of LDAP as defined by U-Mich LDAP and, to some degree,
-RFC 1777.  Version 2 (all variants) should be viewed as obsolete.
+RFC 1777.  Version 2 (all variants) are considered obsolete.
 Version 3 should be used instead.
 .LP
 For backwards compatibility reasons, the library defaults to version 2.
@@ -76,17 +81,21 @@
 encoded Unicode (version 3.2). 
 .LP
 Distinguished names (DN) (and relative distinguished names (RDN) to
-be passed to the LDAP routines should conform to RFC 2253 UTF\-8
+be passed to the LDAP routines should conform to RFC 4514 UTF\-8
 string representation. 
 .LP
 Search filters to be passed to the search routines are to be
-constructed by hand and should conform to RFC 2254 UTF\-8
+constructed by hand and should conform to RFC 4515 UTF\-8
 string representation.
 .LP
-LDAP URL are to be passed to routines are expected to conform
-to RFC 2255 syntax.  The
+LDAP URLs to be passed to routines are expected to conform
+to RFC 4516 format.  The
 .BR ldap_url (3)
 routines can be used to work with LDAP URLs.
+.LP
+LDAP controls to be passed to routines can be manipulated using the
+.BR ldap_controls (3)
+routines.
 .SH DISPLAYING RESULTS
 Results obtained from the search routines can be output by hand,
 by calling
@@ -107,6 +116,10 @@
 .BR ldap_sort (3)
 routines are used to sort the entries and values returned via
 the ldap search routines. 
+.SH DEPRECATED INTERFACES
+A number of interfaces are now considered deprecated.  For instance,
+ldap_add(3) is deprecated in favor of ldap_add_ext(3).
+.so Deprecated
 .SH BER LIBRARY
 Also included in the distribution is a set of lightweight Basic
 Encoding Rules routines.  These routines are used by the LDAP library
@@ -175,6 +188,12 @@
 .SM ldap_err2string(3)
 convert LDAP error indication to a string
 .TP
+.SM ldap_extended_operation(3)
+asynchronously perform an arbitrary extended operation
+.TP
+.SM ldap_extended_operation_s(3)
+synchronously perform an arbitrary extended operation
+.TP
 .SM ldap_first_attribute(3)
 return first attribute name in an entry
 .TP
@@ -251,10 +270,7 @@
 .BR slapd (8),
 .BR draft-ietf-ldapext-ldap-c-api-xx.txt \ <http://www.ietf.org>
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project
 .LP
 These API manual pages are loosely based upon descriptions provided
 in the IETF/LDAPEXT C LDAP API Internet Draft, a (orphaned) work

Modified: openldap/trunk/doc/man/man3/ldap_abandon.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_abandon.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_abandon.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,68 +1,69 @@
 .TH LDAP_ABANDON 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_abandon.3,v 1.15.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_abandon.3,v 1.17.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_abandon, ldap_abandon_ext \- Abandon an LDAP operation in progress
+ldap_abandon_ext \- Abandon an LDAP operation in progress
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
 .nf
-.B #include <ldap.h>
-.sp
-.BI "int ldap_abandon(LDAP *" ld ", int " msgid ");"
-.sp
-.BI "int ldap_abandon_ext(LDAP *" ld ", int " msgid ","
+.B
+#include <ldap.h>
+.LP
+.ft B
+int ldap_abandon_ext(
 .RS
-.BI "LDAPControl *" sctrls "[], LDAPControl *" cctrls "[]);"
+.ft B
+LDAP *\fIld\fB,
+Bint \fImsgid\fB,
+LDAPControl **\fIsctrls\fB,
+LDAPControl **\fIcctrls\fB );
 .RE
 .fi
 .SH DESCRIPTION
 The
-.B ldap_abandon()
-routine is used to abandon or cancel an LDAP
+.B ldap_abandon_ext()
+routine is used to send a LDAP Abandon request for an
 operation in progress.  The \fImsgid\fP passed should be the
-message id of an outstanding LDAP operation, as returned by
-.BR ldap_search (3),
-.BR ldap_modify (3),
-etc.
+message id of an outstanding LDAP operation, such as returned by
+.BR ldap_search_ext (3).
 .LP
-.BR ldap_abandon ()
+.BR ldap_abandon_ext ()
 checks to see if the result of the operation has already come in.  If it
 has, it deletes it from the queue of pending messages.  If not,
-it sends an LDAP abandon operation to the the LDAP server.
+it sends an LDAP abandon request to the LDAP server.
 .LP
 The caller can expect that the result of an abandoned operation
 will not be returned from a future call to
 .BR ldap_result (3).
 .LP
 .B ldap_abandon_ext()
-is equivalent to
-.B ldap_abandon()
-except that it allows server and client controls to be passed
-in
+allows server and client controls to be passed in via the
 .I sctrls
 and
-.IR cctrls ,
-respectively.
-.SH ERRORS
-.B ldap_abandon()
-returns 0 if everything goes ok, -1 otherwise,
-setting \fIld_errno\fP with an appropriate LDAP error code.
+.I cctrls
+parameters, respectively.
 .LP
 .B ldap_abandon_ext()
-directly returns an LDAP error code indicating success or failure of the
-operation.
-.LP
-See
+returns a code indicating success or, in the case of failure, the
+nature of the failure.  See
 .BR ldap_error (3)
 for details.
+.SH DEPRECATED INTERFACES
+The
+.B ldap_abandon()
+routine is deprecated in favor of the
+.B ldap_abandon_ext()
+routine. 
+.LP
+.so Deprecated
+
 .SH SEE ALSO
 .BR ldap (3),
+.BR ldap_error (3),
 .BR ldap_result (3),
-.BR ldap_error (3)
+.BR ldap_search_ext (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project
+

Modified: openldap/trunk/doc/man/man3/ldap_add.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_add.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_add.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,90 +1,81 @@
 .TH LDAP_ADD 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_add.3,v 1.15.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_add.3,v 1.17.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_add, ldap_add_s, ldap_add_ext, ldap_add_ext_s \- Perform an LDAP add operation
+ldap_add_ext, ldap_add_ext_s \- Perform an LDAP add operation
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
+.ft B
+#include <ldap.h>
+.LP
+.ft B
 .nf
-.B #include <ldap.h>
-.sp
-.BI "int ldap_add(LDAP *" ld ", const char *" dn ", LDAPMod *" attrs "[]);"
-.sp
-.BI "int ldap_add_s(LDAP *" ld ", const char *" dn ", LDAPMod *" attrs "[]);"
-.sp
-.BI "int ldap_add_ext(LDAP *" ld ", const char *" dn ", LDAPMod *" attrs "[],"
+int ldap_add_ext(
 .RS
-.BI "LDAPControl *" sctrls "[], LDAPControl *" cctrls "[], int *" msgidp ");"
+.ft B
+LDAP *\fIld,
+const char *\fIdn\fB,
+LDAPMod **\fIattrs\fB,
+LDAPControl **\fIsctrls\fB,
+LDAPControl **\fIcctrls\fB,
+int *\fImsgidp\fB );
 .RE
-.sp
-.BI "int ldap_add_ext_s(LDAP *" ld ", const char *" dn ", LDAPMod *" attrs "[],"
+.LP
+.ft B
+.nf
+int ldap_add_ext_s(
 .RS
-.BI "LDAPControl *" sctrls "[], LDAPControl *" cctrls "[]);"
+LDAP *\fIld\fB,
+const char *\fIdn\fB,
+LDAPMod **\fIattrs\fB,
+LDAPControl *\fIsctrls\fB,
+LDAPControl *\fIcctrls\fB );
 .RE
 .fi
 .SH DESCRIPTION
 The
-.B ldap_add_s()
+.B ldap_add_ext_s()
 routine is used to perform an LDAP add operation.
 It takes \fIdn\fP, the DN of the entry to add, and \fIattrs\fP, a
 null-terminated array of the entry's attributes.  The LDAPMod structure
 is used to represent attributes, with the \fImod_type\fP and
 \fImod_values\fP fields being used as described under
-.BR ldap_modify (3),
+.BR ldap_modify_ext (3),
 and the \fIldap_op\fP field being used only if you need to specify
 the LDAP_MOD_BVALUES option. Otherwise, it should be set to zero.
 .LP
 Note that all entries except that
 specified by the last component in the given DN must already exist.
-.B ldap_add_s()
-returns an LDAP error code indicating success or failure
-of the operation.  See
+.B ldap_add_ext_s()
+returns an code indicating success or, in the case of failure,
+indicating the nature of failure of the operation.  See
 .BR ldap_error (3)
 for more details.
 .LP
 The
-.B ldap_add()
+.B ldap_add_ext()
 routine works just like
-.BR ldap_add_s() ,
+.BR ldap_add_ext_s() ,
 but it is asynchronous.  It returns the message id of the request it
 initiated.  The result of this operation can be obtained by calling
 .BR ldap_result (3).
-.LP
+.SH DEPRECATED INTERFACES
 The
-.B ldap_add_ext()
-routine allows server and client controls to be specified to extend
-the add request. This routine is asynchronous like
-.BR ldap_add() ,
-but its return value is an LDAP error code.  It stores the message id
-of the request in the integer pointed to
-by
-.IR msgidp .
-.LP
-The
-.B ldap_add_ext_s()
-routine is the synchronous version of
-.BR ldap_add_ext() .
-It also returns an LDAP error code indicating success or failure
-of the operation.
-.SH ERRORS
-.B ldap_add()
-returns -1 in case of error initiating the request, and
-will set the \fIld_errno\fP field in the \fIld\fP parameter
-to indicate the error.
-.B ldap_add_s()
-will return an LDAP error code
-directly (LDAP_SUCCESS if everything went ok, some error otherwise).
-.B ldap_add_ext()
+.BR ldap_add ()
 and
-.B ldap_add_ext_s()
-also directly return LDAP error codes.
+.BR ldap_add_s ()
+routines are deprecated in favor of the
+.BR ldap_add_ext ()
+and
+.BR ldap_add_ext_s ()
+routines, respectively.
+.LP
+.so Deprecated
 .SH SEE ALSO
 .BR ldap (3),
+.BR ldap_error (3),
 .BR ldap_modify (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_bind.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_bind.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_bind.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH LDAP_BIND 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_bind.3,v 1.16.2.5 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_bind.3,v 1.20.2.4 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_bind, ldap_bind_s, ldap_simple_bind, ldap_simple_bind_s, ldap_sasl_bind, ldap_sasl_bind_s, ldap_sasl_interactive_bind_s, ldap_parse_sasl_bind_result, ldap_unbind, ldap_unbind_s \- LDAP bind routines
+ldap_bind, ldap_bind_s, ldap_simple_bind, ldap_simple_bind_s, ldap_sasl_bind, ldap_sasl_bind_s, ldap_sasl_interactive_bind_s, ldap_parse_sasl_bind_result, ldap_unbind, ldap_unbind_s, ldap_unbind_ext, ldap_unbind_ext_s, ldap_set_rebind_proc \- LDAP bind routines
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
@@ -49,15 +49,25 @@
 .BI "void *" defaults ");"
 .RE
 .LP
+.BI "int (LDAP_SASL_INTERACT_PROC)(LDAP *" ld ", unsigned " flags ", void *" defaults ", void *" sasl_interact ");"
+.LP
 .BI "int ldap_unbind(LDAP *" ld ");"
 .LP
 .BI "int ldap_unbind_s(LDAP *" ld ");"
-.\" .LP
-.\" .ft B
-.\" void ldap_set_rebind_proc( ld, rebindproc )
-.\" .ft
-.\" LDAP *ld;
-.\" int (*rebindproc)();
+.LP
+.BI "int ldap_unbind_ext(LDAP *" ld ", LDAPControl *" sctrls "[],"
+.RS
+.BI "LDAPControl *" cctrls "[]);"
+.RE
+.LP
+.BI "int ldap_unbind_ext_s(LDAP *" ld ", LDAPControl *" sctrls "[],"
+.RS
+.BI "LDAPControl *" cctrls "[]);"
+.RE
+.LP
+.BI "int ldap_set_rebind_proc (LDAP *" ld ", LDAP_REBIND_PROC *" ldap_proc ", void *" params ");"
+.LP
+.BI "int (LDAP_REBIND_PROC)(LDAP *" ld ", LDAP_CONST char *" url ", ber_tag_t " request ", ber_int_t " msgid ", void *" params ");"
 .SH DESCRIPTION
 .LP
 These routines provide various interfaces to the LDAP bind operation.
@@ -79,7 +89,6 @@
 call are provided.  All routines
 take \fIld\fP as their first parameter, as returned from
 .BR ldap_init (3).
-.LP
 .SH SIMPLE AUTHENTICATION
 The simplest form of the bind call is
 .BR ldap_simple_bind_s() .
@@ -109,7 +118,136 @@
 .B ldap_bind_s()
 returns an LDAP error indication.
 .SH SASL AUTHENTICATION
-Description still under construction...
+For SASL binds the server always ignores any provided DN, so the
+.I dn
+parameter should always be NULL.
+.BR ldap_sasl_bind_s ()
+sends a single SASL bind request with the given SASL
+.I mechanism
+and credentials in the
+.I cred
+parameter. The format of the credentials depends on the particular
+SASL mechanism in use. For mechanisms that provide mutual authentication
+the server's credentials will be returned in the
+.I servercredp
+parameter.
+The routine returns an LDAP error indication (see
+.BR ldap_error (3)).
+The
+.BR ldap_sasl_bind ()
+call is asynchronous, taking the same parameters but only sending the
+request and returning the message id of the request it sent. The result of
+the operation can be obtained by a subsequent
+call to
+.BR ldap_result (3).
+The result must be additionally parsed by
+.BR ldap_parse_sasl_bind_result ()
+to obtain any server credentials sent from the server.
+.LP
+Many SASL mechanisms require multiple message exchanges to perform a
+complete authentication. Applications should generally use
+.BR ldap_sasl_interactive_bind_s ()
+rather than calling the basic
+.BR ldap_sasl_bind ()
+functions directly. The
+.I mechs
+parameter should contain a space-separated list of candidate mechanisms
+to use. If this parameter is NULL or empty the library will query
+the supportedSASLMechanisms attribute from the server's rootDSE
+for the list of SASL mechanisms the server supports. The
+.I flags
+parameter controls the interaction used to retrieve any necessary
+SASL authentication parameters and should be one of:
+.TP
+LDAP_SASL_AUTOMATIC
+use defaults if available, prompt otherwise
+.TP
+LDAP_SASL_INTERACTIVE
+always prompt
+.TP
+LDAP_SASL_QUIET
+never prompt
+.LP
+The
+.I interact
+function uses the provided
+.I defaults
+to handle requests from the SASL library for particular authentication
+parameters. There is no defined format for the
+.I defaults
+information;
+it is up to the caller to use whatever format is appropriate for the
+supplied
+.I interact
+function.
+The
+.I sasl_interact
+parameter comes from the underlying SASL library. When used with Cyrus SASL
+this is an array of
+.B sasl_interact_t
+structures. The Cyrus SASL library will prompt for a variety of inputs,
+including:
+.TP
+SASL_CB_GETREALM
+the realm for the authentication attempt
+.TP
+SASL_CB_AUTHNAME
+the username to authenticate
+.TP
+SASL_CB_PASS
+the password for the provided username
+.TP
+SASL_CB_USER
+the username to use for proxy authorization
+.TP
+SASL_CB_NOECHOPROMPT
+generic prompt for input with input echoing disabled
+.TP
+SASL_CB_ECHOPROMPT
+generic prompt for input with input echoing enabled
+.TP
+SASL_CB_LIST_END
+indicates the end of the array of prompts
+.LP
+See the Cyrus SASL documentation for more details.
+.SH REBINDING
+.LP
+The
+.B ldap_set_rebind_proc
+function() sets the process to use for binding when an operation returns a
+referral. This function is used when an application needs to bind to another server
+in order to follow a referral or search continuation reference.
+.LP
+The function takes \fIld\fP, the \fIrebind\fP function, and the \fIparams\fP,
+the arbitrary data like state information which the client might need to properly rebind.
+The LDAP_OPT_REFERRALS option in the \fIld\fP must be set to ON for the libraries
+to use the rebind function. Use the
+.BR ldap_set_option
+function to set the value.
+.LP
+The rebind function parameters are as follows:
+.LP
+The \fIld\fP parameter must be used by the application when binding to the
+referred server if the application wants the libraries to follow the referral.
+.LP
+The \fIurl\fP parameter points to the URL referral string received from the LDAP server.
+The LDAP application can use the 
+.BR ldap_url_parse (3)
+function to parse the string into its components.
+.LP
+The \fIrequest\fP parameter specifies the type of request that generated the referral. 
+.LP
+The \fImsgid\fP parameter specifies the message ID of the request generating the referral.
+.LP
+The \fIparams\fP parameter is the same value as passed originally to the
+.BR ldap_set_rebind_proc ()
+function.
+.LP
+The LDAP libraries set all the parameters when they call the rebind function. The application
+should not attempt to free either the ld or the url structures in the rebind function.
+.LP
+The application must supply to the rebind function the required authentication information such as,
+user name, password, and certificates. The rebind function must use a synchronous bind method.
 .SH UNBINDING
 The
 .B ldap_unbind()
@@ -122,54 +260,35 @@
 call is just another name for
 .BR ldap_unbind() ;
 both of these calls are synchronous in nature.
-.\" .SH RE-BINDING WHILE FOLLOWING REFERRALS
-.\" The
-.\" .B ldap_set_rebind_proc()
-.\" call is used to set a routine that will be called back to obtain bind
-.\" credentials used when a new server is contacted during the following of
-.\" an LDAP referral.  Note that this function is only available when the
-.\" LDAP libraries are compiled with LDAP_REFERRALS defined and is only
-.\" used when the ld_options field in the LDAP structure has
-.\" LDAP_OPT_REFERRALS set (this is the default).  If
-.\" .B ldap_set_rebind_proc()
-.\" is never called, or if it is called with a NULL \fIrebindproc\fP
-.\" parameter, an unauthenticated simple LDAP bind will always be done
-.\" when chasing referrals.
-.\" .LP
-.\" \fIrebindproc\fP should be a function that is declared like this:
-.\" .LP
-.\" .nf
-.\" int rebindproc( LDAP *ld, char **whop, char **credp,
-.\" int *methodp, int freeit );
-.\" .fi
-.\" .LP
-.\" The LDAP library will first call the rebindproc to obtain the
-.\" referral bind credentials, and the \fIfreeit\fP parameter will be
-.\" zero.  The \fIwhop\fP, \fIcredp\fP, and \fImethodp\fP should be
-.\" set as appropriate.  If the rebindproc returns LDAP_SUCCESS, referral
-.\" processing continues, and the rebindproc will be called a second
-.\" time with \fIfreeit\fP non-zero to give your application a chance to
-.\" free any memory allocated in the previous call.
-.\" .LP
-.\" If anything but LDAP_SUCCESS is returned by the first call to
-.\" the rebindproc, then referral processing is stopped and that error code
-.\" is returned for the original LDAP operation.
+.LP
+The
+.B ldap_unbind_ext()
+and
+.B ldap_unbind_ext_s()
+allows the operations to specify  controls.
 .SH ERRORS
 Asynchronous routines will return -1 in case of error, setting the
 \fIld_errno\fP parameter of the \fIld\fP structure.  Synchronous
 routines return whatever \fIld_errno\fP is set to.  See
 .BR ldap_error (3)
 for more information.
+.SH NOTES
+If an anonymous bind is sufficient for the application, the rebind process
+need not be provided. The LDAP libraries with the LDAP_OPT_REFERRALS option
+set to ON (default value) will automatically follow referrals using an anonymous bind.
+.LP
+If the application needs stronger authentication than an anonymous bind,
+you need to provide a rebind process for that authentication method.
+The bind method must be synchronous.
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_error (3),
 .BR ldap_open (3),
-.B RFC 2222
-(http://www.ietf.org),
+.BR ldap_set_option (3),
+.BR ldap_url_parse (3)
+.B RFC 4422
+(http://www.rfc-editor.org),
 .B Cyrus SASL
 (http://asg.web.cmu.edu/sasl/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_bind.3.links
===================================================================
--- openldap/trunk/doc/man/man3/ldap_bind.3.links	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_bind.3.links	2007-12-15 10:25:31 UTC (rev 892)
@@ -7,3 +7,4 @@
 ldap_unbind_ext.3
 ldap_unbind_s.3
 ldap_unbind_ext_s.3
+ldap_set_rebind_proc.3

Modified: openldap/trunk/doc/man/man3/ldap_compare.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_compare.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_compare.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH LDAP_COMPARE 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_compare.3,v 1.13.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_compare.3,v 1.16.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_compare, ldap_compare_s \- Perform an LDAP compare operation
+ldap_compare, ldap_compare_s, ldap_compare_ext, ldap_compare_ext_s \- Perform an LDAP compare operation.
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
@@ -12,49 +12,68 @@
 #include <ldap.h>
 .LP
 .ft B
-int ldap_compare_s(ld, dn, attr, value)
-.ft
-LDAP *ld;
-char *dn, *attr, *value;
+int ldap_compare_ext(
+.RS
+.ft B
+LDAP *\fIld\fB,
+char *\fIdn\fB,
+char *\fIattr\fB,
+const struct berval *\fIbvalue\fB,
+LDAPControl **\fIserverctrls\fB,
+LDAPControl **\fIclientctrls\fB,
+int *\fImsgidp\fB );
+.RE
 .LP
 .ft B
-int ldap_compare(ld, dn, attr, value)
-.ft
-LDAP *ld;
-char *dn, *attr, *value;
+int ldap_compare_ext_s(
+.RS
+.ft B
+LDAP *\fIld\fB,
+char *\fIdn\fB,
+char *\fIattr\fB,
+const struct berval *\fIbvalue\fB,
+LDAPControl **\fIserverctrls\fB,
+LDAPControl **\fIclientctrls\fB );
+.RE
 .SH DESCRIPTION
 The
-.B ldap_compare_s()
-routine is used to perform an LDAP compare operation
-synchronously.  It takes \fIdn\fP, the DN of the entry upon which to perform
-the compare, and \fIattr\fP and \fIvalue\fP, the attribute type and value to
-compare to those found in the entry.  It returns an LDAP error code, which
+.B ldap_compare_ext_s()
+routine is used to perform an LDAP compare operation synchronously.
+It takes \fIdn\fP, the DN of the entry upon which to perform the
+compare, and \fIattr\fP and \fIvalue\fP, the attribute description and
+value to compare to those found in the entry.  It returns a code, which
 will be LDAP_COMPARE_TRUE if the entry contains the attribute value and
-LDAP_COMPARE_FALSE if it does not.  Otherwise, some error code is returned.
+LDAP_COMPARE_FALSE if it does not.  Otherwise, an error code is
+returned that indicates the nature of the problem.  See
+.BR ldap (3)
+for details.
 .LP
 The
-.B ldap_compare()
+.B ldap_compare_ext()
 routine is used to perform an LDAP compare operation
 asynchronously.  It takes the same parameters as
-.BR ldap_compare_s() ,
-but returns the message id of the request it initiated.  The result of
+.BR ldap_compare_ext_s() ,
+but provides the message id of the request it initiated in the
+integer pointed to \fImsgidp\fP.  The result of
 the compare can be obtained by a subsequent call to
 .BR ldap_result (3).
-.SH ERRORS
-.B ldap_compare_s()
-returns an LDAP error code which can be interpreted
-by calling one of
-.BR ldap_perror (3)
-and friends.  ldap_compare() returns
--1 if something went wrong initiating the request.  It returns the
-non-negative message id of the request if things went ok.
-.SH BUGS
-There is no way to compare binary values, but there should be.
+.LP
+Both routines allow server and client controls to be specified to
+extend the compare request.
+.SH DEPRECATED INTERFACES
+The routines
+.BR ldap_compare ()
+and
+.BR ldap_compare_s ()
+are deprecated in favor of
+.BR ldap_compare_ext ()
+and
+.BR ldap_compare_ext_s (),
+respectively.
+.LP
+.so Deprecated
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_error (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_controls.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_controls.3)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_controls.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_controls.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,84 @@
+.TH LDAP_CONTROLS 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_controls.3,v 1.1.2.2 2007/08/31 23:13:52 quanah Exp $
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldap_control_create, ldap_control_find, ldap_control_dup,
+ldap_controls_dup, ldap_control_free, ldap_controls_free
+\- LDAP control manipulation routines
+.SH LIBRARY
+OpenLDAP LDAP (libldap, -lldap)
+.SH SYNOPSIS
+.B #include <ldap.h>
+.LP
+.BI "int ldap_control_create(const char *" oid ", int " iscritical ", struct berval *" value ", int " dupval ", LDAPControl **" ctrlp ");"
+.LP
+.BI "LDAPControl *ldap_control_find( const char *" oid ", LDAPControl **" ctrls ", LDAPControl ***" nextctrlp ");"
+.LP
+.BI "LDAPControl *ldap_control_dup(LDAPControl *" ctrl ");"
+.LP
+.BI "LDAPControl **ldap_controls_dup(LDAPControl **" ctrls ");"
+.LP
+.BI "void ldap_control_free(LDAPControl *" ctrl ");"
+.LP
+.BI "void ldap_controls_free(LDAPControl **" ctrls ");"
+.SH DESCRIPTION
+These routines are used to manipulate structures used for LDAP controls.
+
+.BR ldap_control_create ()
+creates a control with the specified
+.I OID
+using the contents of the
+.I value
+parameter for the control value, if any.  The content of
+.I value 
+is duplicated if
+.I dupval
+is non-zero.  The
+.I iscritical
+parameter must be non-zero for a critical control. The created control
+is returned in the
+.I ctrlp
+parameter.  The routine returns
+.B LDAP_SUCCESS
+on success or some other error code on failure.
+The content of
+.IR value ,
+for supported control types, can be prepared using helpers provided
+by this implementation of libldap, usually in the form
+.BR "ldap_create_<control name>_control_value" ().
+Otherwise, it can be BER-encoded using the functionalities of liblber.
+
+.BR ldap_control_find ()
+searches the NULL-terminated
+.I ctrls
+array for a control whose OID matches the
+.I oid
+parameter.  The routine returns a pointer to the control if found,
+NULL otherwise.
+If the parameter
+.I nextctrlp
+is not NULL, on return it will point to the next control
+in the array, and can be passed to the
+.BR ldap_control_find ()
+routine for subsequent calls, to find further occurrences of the same 
+control type.
+The use of this function is discouraged; the recommended way of handling
+controls in responses consists in going through the array of controls,
+dealing with each of them in the returned order, since it could matter.
+
+.BR ldap_control_dup ()
+duplicates an individual control structure, and
+.BR ldap_controls_dup ()
+duplicates a NULL-terminated array of controls.
+
+.BR ldap_control_free ()
+frees an individual control structure, and
+.BR ldap_controls_free ()
+frees a NULL-terminated array of controls.
+
+.SH SEE ALSO
+.BR ldap (3),
+.BR ldap_error (3)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_controls.3.links (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_controls.3.links)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_controls.3.links	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_controls.3.links	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,6 @@
+ldap_control_create.3
+ldap_control_find.3
+ldap_control_dup.3
+ldap_controls_dup.3
+ldap_control_free.3
+ldap_controls_free.3

Modified: openldap/trunk/doc/man/man3/ldap_delete.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_delete.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_delete.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH LDAP_DELETE 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_delete.3,v 1.13.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_delete.3,v 1.16.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_delete, ldap_delete_s \- Perform an LDAP delete operation
+ldap_delete, ldap_delete_s, ldap_delete_ext, ldap_delete_ext_s \- Perform an LDAP delete operation.
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
@@ -22,22 +22,51 @@
 .ft
 LDAP *ld;
 char *dn;
+.LP
+.ft B
+int ldap_delete_ext(ld, dn, serverctrls, clientctrls, msgidp)
+.ft
+LDAP *ld;
+char *dn;
+LDAPControl **serverctrls, **clientctrls;
+int *msgidp;
+.LP
+.ft B
+int ldap_delete_ext_s(ld, dn, serverctrls, clientctrls)
+.ft
+LDAP *ld;
+char *dn;
+LDAPControl **serverctrls, **clientctrls;
 .SH DESCRIPTION
 The
 .B ldap_delete_s()
 routine is used to perform an LDAP delete operation
-synchronously.  It takes \fIdn\fP, the DN of the entry to be deleted.
+synchronously. It takes \fIdn\fP, the DN of the entry to be deleted.
 It returns an LDAP error code, indicating the success or failure of the
 operation.
 .LP
 The
 .B ldap_delete()
 routine is used to perform an LDAP delete operation
-asynchronously.  It takes the same parameters as
-.BR ldap_delete_s() ,
-but returns the message id of the request it initiated.  The result of
+asynchronously. It takes the same parameters as
+.BR ldap_delete_s(),
+but returns the message id of the request it initiated. The result of
 the delete can be obtained by a subsequent call to
 .BR ldap_result (3).
+.LP
+The
+.B ldap_delete_ext()
+routine  allows  server  and client controls to be 
+specified to extend the delete request. This routine is asynchronous like 
+ldap_delete(), but its return value is an LDAP error code. It stores the 
+message id of the request in the integer pointed to by msgidp.
+.LP
+The
+.B ldap_delete_ext_s()
+routine is the synchronous version of
+.BR ldap_delete_ext().
+It also returns an LDAP error code indicating success 
+or failure of the operation.
 .SH ERRORS
 .B ldap_delete_s()
 returns an LDAP error code which can be interpreted
@@ -45,13 +74,16 @@
 .BR ldap_perror (3)
 and friends.
 .B ldap_delete()
-returns -1 if something went wrong initiating the request.  It returns the
+returns -1 if something went wrong initiating the request. It returns the
 non-negative message id of the request if things went ok.
+.LP
+.B ldap_delete_ext()
+and
+.B ldap_delete_ext_s()
+return some Non-zero value if
+something  went wrong initiating the request, else return 0.
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_error (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_error.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_error.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_error.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAP_ERROR 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_error.3,v 1.19.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_error.3,v 1.21.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -12,18 +12,20 @@
 #include <ldap.h>
 .LP
 .ft B
-char *ldap_err2string( int err );
-.LP
-.ft B
-void ldap_perror( LDAP *ld, const char *s )
-.LP
-.ft B
-int ldap_result2error( LDAP *ld, LDAPMessage *res, int freeit )
+char *ldap_err2string( int \fIerr\fB );
 .SH DESCRIPTION
-These routines provide interpretation of the various error codes
-returned by the LDAP protocol and LDAP library routines or associated
-with an LDAP session.  The error code associated with an LDAP session
-is accessible using
+The
+.B ldap_err2string()
+routine provides short description of the various codes returned by
+routines in this library.  The returned string is a pointer to a
+static area that should not be modified.
+
+These codes are either negative,
+indicating an API error code; positive, indicating an LDAP resultCode
+other than \'success' (0), or - zero, indicating both successful use
+of the API and the LDAP resultCode \'success' (0).
+
+The code associated with an LDAP session is accessible using
 .BR ldap_get_option (3)
 and
 .BR ldap_set_option (3)
@@ -31,39 +33,16 @@
 .B LDAP_OPT_RESULT_CODE
 option (previously called
 .BR LDAP_OPT_ERROR_NUMBER ).
+
+.SH PROTOCOL RESULT CODES
+
+This section provides a partial list of protocol codes recognized
+by the library.  As LDAP is extensible, additional values may be
+returned.  A complete listing of \fIregistered\fP LDAP result codes
+can be obtained from the \fIInternet Assigned Numbers Authority\fP
+<http://www.iana.org>.
+
 .LP
-The
-.B ldap_result2error()
-routine takes \fIres\fP, a result as produced by
-.BR ldap_result (3)
-or
-.BR ldap_search_s (3),
-and returns
-the corresponding error code.  Possible error codes are listed
-below.  If the \fIfreeit\fP parameter is non zero it indicates that the
-\fIres\fP parameter should be freed by a call to
-.BR ldap_msgfree (3)
-after the error code has been extracted.  The
-.B ld_errno
-field in \fIld\fP is set and returned.
-.LP
-The returned value can be passed to
-.B ldap_err2string()
-to get a text description of the message.  The string
-returned from
-.B ldap_err2string()
-is a pointer to a static area that
-should not be modified.
-.LP
-The
-.B ldap_perror()
-routine can be called to print an indication of
-the error on standard error, similar to the way
-.BR perror (3)
-works.
-.SH ERRORS
-The possible values for an ldap error code are:
-.LP
 .TP 20
 .SM LDAP_SUCCESS
 The request was successful.
@@ -172,7 +151,17 @@
 .TP
 .SM LDAP_OTHER
 An unknown error occurred.
-.TP
+
+.SH API ERROR CODES
+
+This section provides a complete list of API error codes recognized
+by the library.   Note that LDAP_SUCCESS indicates success of an
+API call in addition to representing the return of the LDAP
+\'success' resultCode.
+
+
+.LP
+.TP 20
 .SM LDAP_SERVER_DOWN
 The LDAP library can't contact the LDAP server.
 .TP
@@ -200,13 +189,36 @@
 .TP
 .SM LDAP_NO_MEMORY
 An memory allocation (e.g., malloc(3) or other dynamic memory
-allocator) call failed in an ldap
-library routine.
+allocator) call failed in an ldap library routine.
+.TP
+.SM LDAP_USER_CANCELED
+Indicates the user cancelled the operation.
+.TP
+.SM LDAP_CONNECT_ERROR
+Indicates a connection problem.
+.TP
+.SM LDAP_NOT_SUPPORTED
+Indicates the routine was called in a manner not supported by the library.
+.TP
+.SM LDAP_CONTROL_NOT_FOUND
+Indicates the control provided is unknown to the client library.
+.TP
+.SM LDAP_NO_RESULTS_RETURNED
+Indicates no results returned.
+.TP
+.SM LDAP_MORE_RESULTS_TO_RETURN
+Indicates more results could be returned.
+.TP
+.SM LDAP_CLIENT_LOOP
+Indicates the library has detected a loop in its processing.
+.TP
+.SM LDAP_REFERRAL_LIMIT_EXCEEDED
+Indicates the referral limit has been exceeded.
+
+.SH DEPRECATED
+.so Deprecated
+
 .SH SEE ALSO
 .BR ldap (3),
-.BR perror (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_extended_operation.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_extended_operation.3)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_extended_operation.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_extended_operation.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,75 @@
+.TH LDAP_EXTENDED_OPERATION 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_extended_operation.3,v 1.1.2.5 2007/11/14 09:04:34 ghenry Exp $
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldap_extended_operation, ldap_extended_operation_s \- Extends the LDAP operations to the LDAP server.
+.SH LIBRARY
+OpenLDAP LDAP (libldap, -lldap)
+.SH SYNOPSIS
+.nf
+.ft B
+#include <ldap.h>
+.LP
+.ft B
+int ldap_extended_operation(
+.RS
+.ft B
+LDAP *\fIld\fB,
+const char *\fIrequestoid\fB,
+const struct berval *\fIrequestdata\fB,
+LDAPControl **\fIsctrls\fB,
+LDAPControl **\fIcctrls\fB,
+int *\fImsgidp\fB );
+.RE
+.LP
+.ft B
+int ldap_extended_operation_s(
+.RS
+.ft B
+LDAP *\fIld\fB,
+const char *\fIrequestoid\fB,
+const struct berval *\fIrequestdata\fB,
+LDAPControl **\fIsctrls\fB,
+LDAPControl **\fIcctrls\fB,
+char **\fIretoidp\fB,
+struct berval **\fIretdatap\fB );
+.RE
+.SH DESCRIPTION
+The
+.B ldap_extended_operation_s()
+routine is used to synchronously perform an LDAP extended operation.
+It takes \fIrequestoid\fP, which points to a dotted-decimal OID string
+identifying the extended operation to perform. \fIrequestdata\fP is the
+data required for the request, \fIsctrls\fP is an array of LDAPControl
+structures to use with this extended operation, \fIcctrls\fP is an array
+of LDAPControl structures that list the client controls to use with
+this extended operation.
+.LP
+The output parameter \fIretoidp\fP points to a dotted-decimal OID
+string returned by the LDAP server.  The memory used by the string
+should be freed with the
+.BR ldap_memfree (3)
+function.
+The output parameter \fIretdatap\fP points to a pointer to a berval
+structure that contains the returned data.  If no data is returned
+by the server, the pointer is set this to NULL.  The memory used by
+this structure should be freed with the
+.BR ber_bvfree (3)
+function.
+.LP
+The
+.B ldap_extended_operation()
+works just like
+.BR ldap_extended_operation_s() ,
+but the operation is asynchronous.  It provides the message id of
+the request it initiated in the integer pointed to be \fImsgidp\fP.
+The result of this operation can be obtained by calling
+.BR ldap_result(3).
+.SH SEE ALSO
+.BR ber_bvfree (3),
+.BR ldap_memfree (3),
+.BR ldap_parse_extended_result (3),
+.BR ldap_result (3)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_extended_operation.3.links (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_extended_operation.3.links)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_extended_operation.3.links	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_extended_operation.3.links	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,2 @@
+ldap_extended_operation_s.3
+

Modified: openldap/trunk/doc/man/man3/ldap_first_attribute.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_first_attribute.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_first_attribute.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAP_FIRST_ATTRIBUTE 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_first_attribute.3,v 1.18.2.6 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_first_attribute.3,v 1.21.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -39,7 +39,7 @@
 allocated to keep track of its current position.  This pointer should
 be passed to subsequent calls to
 .B ldap_next_attribute()
-and is used used
+and is used
 to effectively step through the entry's attributes.  The caller is
 solely responsible for freeing the BerElement pointed to by \fIberptr\fP
 when it is no longer needed by calling
@@ -70,7 +70,4 @@
 .BR ldap_get_values (3),
 .BR ldap_error (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_first_entry.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_first_entry.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_first_entry.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAP_FIRST_ENTRY 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_first_entry.3,v 1.14.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_first_entry.3,v 1.16.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -77,7 +77,4 @@
 .BR ldap_get_values (3),
 .BR ldap_get_dn (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_first_message.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_first_message.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_first_message.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,10 +1,9 @@
 .TH LDAP_FIRST_MESSAGE 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_first_message.3,v 1.9.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_first_message.3,v 1.11.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_first_message, ldap_next_message, ldap_count_messages \- Stepping
-through messages in a result chain
+ldap_first_message, ldap_next_message, ldap_count_messages \- Stepping through messages in a result chain
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
@@ -80,7 +79,4 @@
 .BR ldap_first_entry (3),
 .BR ldap_first_reference (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_first_reference.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_first_reference.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_first_reference.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,10 +1,9 @@
 .TH LDAP_FIRST_REFERENCE 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_first_reference.3,v 1.9.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_first_reference.3,v 1.11.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_first_reference, ldap_next_reference, ldap_count_references \- Stepping
-through continuation references in a result chain
+ldap_first_reference, ldap_next_reference, ldap_count_references \- Stepping through continuation references in a result chain
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
@@ -69,7 +68,4 @@
 .BR ldap_search (3),
 .BR ldap_parse_reference (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_get_dn.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_get_dn.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_get_dn.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAP_GET_DN 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_get_dn.3,v 1.25.2.4 2007/01/02 21:43:44 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_get_dn.3,v 1.28.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -41,8 +41,8 @@
 These routines allow LDAP entry names (Distinguished Names, or DNs)
 to be obtained, parsed, converted to a user-friendly form, and tested.
 A DN has the form described in
-RFC 2253 "Lightweight Directory Access Protocol (v3):
-UTF-8 String Representation of Distinguished Names".
+RFC 4414 "Lightweight Directory Access Protocol (LDAP):
+String Representation of Distinguished Names".
 .LP
 The
 .B ldap_get_dn()
@@ -91,7 +91,7 @@
 or
 .B LDAP_AVA_BINARY,
 the latter meaning that the value is BER/DER encoded and thus must
-be represented as, quoting from RFC 2253, " ... an
+be represented as, quoting from RFC 4514, " ... an
 octothorpe character ('#' ASCII 35) followed by the hexadecimal
 representation of each of the bytes of the BER encoding of the X.500
 AttributeValue."
@@ -107,7 +107,7 @@
 	LDAP_DN_FORMAT_DCE
 
 .fi
-which defines what DN syntax is expected (according to RFC 2253, 
+which defines what DN syntax is expected (according to RFC 4514, 
 RFC 1779 and DCE, respectively).
 The format can be \fIOR\fPed to the flags
 .LP
@@ -234,7 +234,4 @@
 .BR ldap_memfree (3),
 .BR ldap_value_free (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_get_option.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_get_option.3)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_get_option.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_get_option.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,337 @@
+.TH LDAP_GET_OPTION 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_get_option.3,v 1.3.2.4 2007/10/17 14:34:48 ando Exp $
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldap_get_option, ldap_set_option \- LDAP option handling routines
+.SH LIBRARY
+OpenLDAP LDAP (libldap, -lldap)
+.SH SYNOPSIS
+.nf
+.B #include <ldap.h>
+.LP
+.BI "int ldap_get_option(LDAP *" ld ", int " option ", void *" outvalue ");"
+.LP
+.BI "int ldap_set_option(LDAP *" ld ", int " option ", const void *" invalue ");"
+.SH DESCRIPTION
+.LP
+These routines provide access to options stored either in a LDAP handle
+or as global options, where applicable.
+They make use of a neutral interface, where the type of the value
+either retrieved by 
+.BR ldap_get_option (3)
+or set by
+.BR ldap_set_option (3)
+is cast to 
+.BR "void *" .
+The actual type is determined based on the value of the
+.B option
+argument.
+Global options are set/retrieved by passing a NULL LDAP handle.
+.TP
+.B LDAP_OPT_API_INFO
+Fills-in a 
+.BR "struct ldapapiinfo" ;
+.BR outvalue 
+must be a 
+.BR "struct ldapapiinfo *" ,
+pointing to an already allocated struct.
+This is a read-only option.
+.TP
+.B LDAP_OPT_DESC
+Returns the file descriptor associated to the socket buffer
+of the LDAP handle passed in as 
+.BR ld ;
+.BR outvalue
+must be a 
+.BR "int *" .
+This is a read-only, handler-specific option.
+.TP
+.B LDAP_OPT_SOCKBUF
+Returns a pointer to the socket buffer of the LDAP handle passed in as
+.BR ld ;
+.BR outvalue
+must be a 
+.BR "Sockbuf **" .
+This is a read-only, handler-specific option.
+.TP
+.B LDAP_OPT_TIMEOUT
+Sets/gets a timeout value for the synchronous API calls.
+.B outvalue
+must be a 
+.BR "struct timeval **"
+(the caller has to free
+.BR *outvalue ) ,
+and
+.B invalue
+must be a 
+.BR "struct timeval *" ,
+and they cannot be NULL. Using a struct with seconds set to -1 results
+in an infinite timeout, which is the default.
+.TP
+.B LDAP_OPT_NETWORK_TIMEOUT
+Sets/gets the network timeout value after which
+.BR poll (2)/ select (2) 
+following a 
+.BR connect (2) 
+returns in case of no activity.
+.B outvalue
+must be a 
+.BR "struct timeval **"
+(the caller has to free
+.BR *outvalue ) ,
+and
+.B invalue
+must be a 
+.BR "struct timeval *" ,
+and they cannot be NULL. Using a struct with seconds set to -1 results
+in an infinite timeout, which is the default.
+.TP
+.B LDAP_OPT_DEREF
+Sets/gets the value that defines when alias dereferencing must occur.
+.BR outvalue 
+and 
+.BR invalue
+must be
+.BR "int *" ,
+and they cannot be NULL.
+.TP
+.B LDAP_OPT_SIZELIMIT
+Sets/gets the value that defines the maximum number of entries
+to be returned by a search operation.
+.BR outvalue 
+and 
+.BR invalue
+must be
+.BR "int *" ,
+and they cannot be NULL.
+.TP
+.B LDAP_OPT_TIMELIMIT
+Sets/gets the value that defines the time limit after which
+a search operation should be terminated by the server.
+.BR outvalue 
+and 
+.BR invalue
+must be
+.BR "int *" ,
+and they cannot be NULL.
+.TP
+.B LDAP_OPT_REFERRALS
+Determines whether the library should implicitly chase referrals or not.
+.BR outvalue
+and
+.BR invalue
+must be 
+.BR "int *" ;
+their value should either be
+.BR LDAP_OPT_OFF
+or
+.BR LDAP_OPT_ON .
+.TP
+.B LDAP_OPT_RESTART
+Determines whether the library should implicitly restart connections (FIXME).
+.BR outvalue
+and
+.BR invalue
+must be 
+.BR "int *" ;
+their value should either be
+.BR LDAP_OPT_OFF
+or
+.BR LDAP_OPT_ON .
+.TP
+.B LDAP_OPT_PROTOCOL_VERSION
+Sets/gets the protocol version.
+.BR outvalue
+and
+.BR invalue
+must be 
+.BR "int *" .
+.TP
+.B LDAP_OPT_SERVER_CONTROLS
+Sets/gets the server-side controls to be used for all operations.
+This is now deprecated as modern LDAP C API provides replacements
+for all main operations which accepts server-side controls as
+explicit arguments; see for example
+.BR ldap_search_ext (3),
+.BR ldap_add_ext (3),
+.BR ldap_modify_ext (3)
+and so on.
+.BR outvalue
+must be 
+.BR "LDAPControl ***" ,
+and the caller is responsible of freeing the returned controls, if any,
+by calling 
+.BR ldap_controls_free (3),
+while
+.BR invalue
+must be 
+.BR "LDAPControl **" ;
+the library duplicates the controls passed via
+.BR invalue .
+.TP
+.B LDAP_OPT_CLIENT_CONTROLS
+Sets/gets the client-side controls to be used for all operations.
+This is now deprecated as modern LDAP C API provides replacements
+for all main operations which accepts client-side controls as
+explicit arguments; see for example
+.BR ldap_search_ext (3),
+.BR ldap_add_ext (3),
+.BR ldap_modify_ext (3)
+and so on.
+.BR outvalue
+must be 
+.BR "LDAPControl ***" ,
+and the caller is responsible of freeing the returned controls, if any,
+by calling 
+.BR ldap_controls_free (3),
+while
+.BR invalue
+must be 
+.BR "LDAPControl **" ;
+the library duplicates the controls passed via
+.BR invalue .
+.TP
+.B LDAP_OPT_HOST_NAME
+Sets/gets a space-separated list of hosts to be contacted by the library 
+when trying to establish a connection.
+This is now deprecated in favor of
+.BR LDAP_OPT_URI .
+.BR outvalue
+must be a 
+.BR "char **" ,
+and the caller is responsible of freeing the resulting string by calling
+.BR ldap_memfree (3),
+while
+.BR invalue
+must be a 
+.BR "char *" ;
+the library duplicates the corresponding string.
+.TP
+.B LDAP_OPT_URI
+Sets/gets a space-separated list of URIs to be contacted by the library 
+when trying to establish a connection.
+.BR outvalue
+must be a 
+.BR "char **" ,
+and the caller is responsible of freeing the resulting string by calling
+.BR ldap_memfree (3),
+while
+.BR invalue
+must be a 
+.BR "char *" ;
+the library parses the string into a list of 
+.BR LDAPURLDesc
+structures, so the invocation of 
+.BR ldap_set_option (3)
+may fail if URL parsing fails.
+.TP
+.B LDAP_OPT_DEFBASE
+Sets/gets a string containing the DN to be used as default base
+for search operations.
+.BR outvalue
+must be a
+.BR "char **" ,
+and the caller is responsible of freeing the returned string by calling
+.BR ldap_memfree (3),
+while
+.BR invalue
+must be a 
+.BR "char *" ;
+the library duplicates the corresponding string.
+.TP
+.B LDAP_OPT_RESULT_CODE
+Sets/gets the LDAP result code associated to the handle.
+This option was formerly known as
+.BR LDAP_OPT_ERROR_NUMBER .
+Both
+.BR outvalue
+and
+.BR invalue
+must be a 
+.BR "int *" .
+.TP
+.B LDAP_OPT_DIAGNOSTIC_MESSAGE
+Sets/gets a string containing the error string associated to the LDAP handle.
+This option was formerly known as 
+.BR LDAP_OPT_ERROR_STRING .
+.BR outvalue
+must be a
+.BR "char **" ,
+and the caller is responsible of freeing the returned string by calling
+.BR ldap_memfree (3),
+while
+.BR invalue
+must be a 
+.BR "char *" ;
+the library duplicates the corresponding string.
+.TP
+.B LDAP_OPT_MATCHED_DN
+Sets/gets a string containing the matched DN associated to the LDAP handle.
+.BR outvalue
+must be a
+.BR "char **" ,
+and the caller is responsible of freeing the returned string by calling
+.BR ldap_memfree (3),
+while
+.BR invalue
+must be a 
+.BR "char *" ;
+the library duplicates the corresponding string.
+.TP
+.B LDAP_OPT_REFERRAL_URLS
+Sets/gets an array containing the referral URIs associated to the LDAP handle.
+.BR outvalue
+must be a
+.BR "char ***" ,
+and the caller is responsible of freeing the returned string by calling
+.BR ber_memvfree (3),
+while
+.BR invalue
+must be a NULL-terminated
+.BR "char **" ;
+the library duplicates the corresponding string.
+.TP
+.B LDAP_OPT_API_FEATURE_INFO
+Fills-in a 
+.BR "LDAPAPIFeatureInfo" ;
+.BR outvalue 
+must be a 
+.BR "LDAPAPIFeatureInfo *" ,
+pointing to an already allocated struct.
+This is a read-only option.
+.TP
+.B LDAP_OPT_DEBUG_LEVEL
+Sets/gets the debug level of the client library.
+Both
+.BR outvalue
+and
+.BR invalue
+must be a 
+.BR "int *" .
+.SH ERRORS
+On success, the functions return
+.BR LDAP_OPT_SUCCESS ,
+while they may return
+.B LDAP_OPT_ERROR
+to indicate a generic option handling error.
+Occasionally, more specific errors can be returned, like
+.B LDAP_NO_MEMORY
+to indicate a failure in memory allocation.
+.SH NOTES
+The LDAP libraries with the
+.B LDAP_OPT_REFERRALS 
+option set to
+.B LDAP_OPT_ON
+(default value) automatically follow referrals using an anonymous bind.
+Application developers are encouraged to either implement consistent
+referral chasing features, or explicitly disable referral chasing
+by setting that option to
+.BR LDAP_OPT_OFF .
+.SH SEE ALSO
+.BR ldap (3),
+.BR ldap_error (3),
+.B RFC 4422
+(http://www.rfc-editor.org),
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_get_option.3.links (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_get_option.3.links)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_get_option.3.links	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_get_option.3.links	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1 @@
+ldap_set_option.3

Modified: openldap/trunk/doc/man/man3/ldap_get_values.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_get_values.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_get_values.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAP_GET_VALUES 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_get_values.3,v 1.15.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_get_values.3,v 1.17.2.3 2007/11/14 09:04:34 ghenry Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -17,32 +17,32 @@
 .ft
 LDAP *ld;
 LDAPMessage *entry;
-char *attr
+char *attr;
 .LP
 .ft B
 struct berval **ldap_get_values_len(ld, entry, attr)
 .ft
 LDAP *ld;
 LDAPMessage *entry;
-char *attr
+char *attr;
 .LP
 .ft B
-ldap_count_values(vals)
+int ldap_count_values(vals)
 .ft
 char **vals;
 .LP
 .ft B
-ldap_count_values_len(vals)
+int ldap_count_values_len(vals)
 .ft
 struct berval **vals;
 .LP
 .ft B
-ldap_value_free(vals)
+void ldap_value_free(vals)
 .ft
 char **vals;
 .LP
 .ft B
-ldap_value_free_len(vals)
+void ldap_value_free_len(vals)
 .ft
 struct berval **vals;
 .SH DESCRIPTION
@@ -99,7 +99,4 @@
 .BR ldap_first_attribute (3),
 .BR ldap_error (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_memory.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_memory.3)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_memory.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_memory.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,50 @@
+.TH LDAP_MEMORY 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_memory.3,v 1.1.2.2 2007/08/31 23:13:52 quanah Exp $
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldap_memfree, ldap_memvfree, ldap_memalloc, ldap_memcalloc, ldap_memrealloc, ldap_strdup \- LDAP memory allocation routines
+.SH LIBRARY
+OpenLDAP LDAP (libldap, -lldap)
+.SH SYNOPSIS
+.B #include <ldap.h>
+.LP
+.BI "void ldap_memfree(void *" p ");"
+.LP
+.BI "void ldap_memvfree(void **" v ");"
+.LP
+.BI "void *ldap_memalloc(ber_len_t " s ");"
+.LP
+.BI "void *ldap_memcalloc(ber_len_t " n ", ber_len_t " s ");"
+.LP
+.BI "void *ldap_memrealloc(void *" p ", ber_len_t " s ");"
+.LP
+.BI "char *ldap_strdup(LDAP_CONST char *" p ");"
+.SH DESCRIPTION
+These routines are used to allocate/deallocate memory used/returned
+by the LDAP library.
+.BR ldap_memalloc (),
+.BR ldap_memcalloc (),
+.BR ldap_memrealloc (),
+and
+.BR ldap_memfree ()
+are used exactly like the standard
+.BR malloc (3),
+.BR calloc (3),
+.BR realloc (3),
+and
+.BR free (3)
+routines, respectively.
+The
+.BR ldap_memvfree ()
+routine is used to free a dynamically allocated array of pointers to
+arbitrary dynamically allocated objects.
+The
+.BR ldap_strdup ()
+routine is used exactly like the standard
+.BR strdup (3)
+routine.
+.SH SEE ALSO
+.BR ldap (3)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_memory.3.links (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_memory.3.links)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_memory.3.links	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_memory.3.links	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,6 @@
+ldap_memfree.3
+ldap_memvfree.3
+ldap_memalloc.3
+ldap_memcalloc.3
+ldap_memrealloc.3
+ldap_strdup.3

Modified: openldap/trunk/doc/man/man3/ldap_modify.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_modify.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_modify.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH LDAP_MODIFY 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_modify.3,v 1.12.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_modify.3,v 1.14.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_modify, ldap_modify_s \- Perform an LDAP modify operation
+ldap_modify_ext, ldap_modify_ext_s \- Perform an LDAP modify operation
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
@@ -12,30 +12,40 @@
 #include <ldap.h>
 .LP
 .ft B
+int ldap_modify_ext(
+.RS
+.ft B
+LDAP *\fIld\fB,
+char *\fIdn\fB,
+LDAPMod *\fImods[]\fB,
+LDAPControl **\fIsctrls\fB,
+LDAPControl **\fIcctrls\fB,
+int **\fImsgidp\fB );
+.RE
+.LP
 .nf
-int ldap_modify(ld, dn, mods)
-.ft
-LDAP *ld;
-char *dn;
-LDAPMod *mods[];
+.ft B
+int ldap_modify_ext_s(
+.RS
+.ft B
+LDAP *\fIld\fB,
+char *\fIdn\fB,
+LDAPMod *\fImods[]\fB,
+LDAPControl **\fIsctrls\fB,
+LDAPControl **\fIcctrls\fB );
+.RE
 .LP
-.ft B
 .nf
-int ldap_modify_s(ld, dn, mods)
-.ft
-LDAP *ld;
-char *dn;
-LDAPMod *mods[];
-.LP
 .ft B
-.nf
-void ldap_mods_free( mods, freemods )
-.ft
-LDAPMod **mods;
-int freemods;
+void ldap_mods_free(
+.RS
+.ft B
+LDAPMod **\fImods\fB,
+int \fIfreemods\fB );
+.RE
 .SH DESCRIPTION
 The routine
-.B ldap_modify_s()
+.B ldap_modify_ext_s()
 is used to perform an LDAP modify operation.
 \fIdn\fP is the DN of the entry to modify, and \fImods\fP is a
 null-terminated array of modifications to make to the entry.  Each element
@@ -43,7 +53,6 @@
 defined below.
 .LP
 .nf
-.ft B
 	typedef struct ldapmod {
 	    int mod_op;
 	    char *mod_type;
@@ -82,41 +91,47 @@
 modification, having been created if necessary.  All modifications are
 performed in the order in which they are listed.
 .LP
-.B
-ldap_modify_s()
-returns the LDAP error code resulting from the
-modify operation.  This code can be interpreted by
-.BR ldap_perror (3)
-and friends.
+.B ldap_mods_free()
+can be used to free each element of a NULL-terminated
+array of mod structures.  If \fIfreemods\fP is non-zero, the
+\fImods\fP pointer itself is freed as well.
 .LP
+.B ldap_modify_ext_s()
+returns a code indicating success or, in the case of failure,
+indicating the nature of the failure.  See
+.BR ldap_error (3)
+for details
+.LP
 The
-.B ldap_modify()
+.B ldap_modify_ext()
 operation works the same way as
-.BR ldap_modify_s() ,
-except that it is asynchronous, returning the message id of the
-request it initiates, or -1 on error.  The result of the operation
-can be obtained by calling
+.BR ldap_modify_ext_s() ,
+except that it is asynchronous. The integer that \fImsgidp\fP points
+to is set to the message id of the modify request.  The result of
+the operation can be obtained by calling
 .BR ldap_result (3).
 .LP
-.B ldap_mods_free()
-can be used to free each element of a NULL-terminated
-array of mod structures.  If \fIfreemods\fP is non-zero, the
-\fImods\fP pointer itself is freed as well.
-.SH ERRORS
+Both
+.B ldap_modify_ext() 
+and
+.B ldap_modify_ext_s() 
+allows server and client controls to be passed in
+via the sctrls and cctrls parameters, respectively.
+.SH DEPRECATED INTERFACES
+The
+.B ldap_modify()
+and
 .B ldap_modify_s()
-returns an ldap error code, either LDAP_SUCCESS or
-an error if there was trouble.
-.B ldap_modify()
-returns -1 in case
-of trouble, setting the
-.B ld_errno
-field of \fIld\fP.
+routines are deprecated in favor of the
+.B ldap_modify_ext()
+and
+.B ldap_modify_ext_s()
+routines, respectively.
+.LP
+.so Deprecated
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_error (3),
-.BR ldap_add (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project
+

Modified: openldap/trunk/doc/man/man3/ldap_modrdn.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_modrdn.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_modrdn.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAP_MODRDN 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_modrdn.3,v 1.12.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_modrdn.3,v 1.14.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -78,7 +78,4 @@
 .BR ldap (3),
 .BR ldap_error (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_open.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_open.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_open.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH LDAP_OPEN 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_open.3,v 1.13.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_open.3,v 1.16.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_init, ldap_open \- Initialize the LDAP library and open a connection to an LDAP server
+ldap_init, ldap_initialize, ldap_open \- Initialize the LDAP library and open a connection to an LDAP server
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
@@ -22,6 +22,23 @@
 .ft
 char *host;
 int port;
+.LP
+.ft B
+int ldap_initialize(ldp, uri)
+.ft
+LDAP **ldp;
+char *uri;
+.LP
+.ft B
+#include <ldap_pvt.h>
+.LP
+.ft B
+int ldap_init_fd(fd, proto, uri, ldp)
+.ft
+ber_socket_t fd;
+int proto;
+char *uri;
+LDAP **ldp;
 .SH DESCRIPTION
 .LP
 .B ldap_open()
@@ -29,8 +46,14 @@
 structure which is used to identify
 the connection and to maintain per-connection information.
 .B ldap_init()
-allocates an LDAP structure but does not open an initial connection.  One
-of these two routines must be called before any operations are attempted.
+allocates an LDAP structure but does not open an initial connection.
+.B ldap_initialize()
+allocates an LDAP structure but does not open an initial connection.
+.B ldap_init_fd()
+allocates an LDAP structure using an existing connection on the
+provided socket.
+One
+of these routines must be called before any operations are attempted.
 .LP
 .B ldap_open()
 takes \fIhost\fP, the hostname on which the LDAP server is
@@ -44,79 +67,87 @@
 Upon successfully making a connection to an
 LDAP server,
 .B ldap_open()
-returns a pointer to an LDAP structure (defined below), which
-should be passed to subsequent calls to
+returns a pointer to an opaque LDAP structure, which should be passed
+to subsequent calls to
 .BR ldap_bind() ,
 .BR ldap_search() ,
 etc. Certain fields in the LDAP structure can be set to indicate size limit,
-time limit, and how aliases are handled during operations.  See <ldap.h>
-for more details.
+time limit, and how aliases are handled during operations; read and write access 
+to those fields must occur by calling
+.BR ldap_get_option (3) 
+and
+.BR ldap_set_option (3)
+respectively, whenever possible.
 .LP
-.nf
-.ft tt
-	typedef struct ldap {
-		/* ... other stuff you should not mess with ... */
-		char		ld_lberoptions;
-		int		ld_deref;
-	#define LDAP_DEREF_NEVER	0
-	#define LDAP_DEREF_SEARCHING	1
-	#define LDAP_DEREF_FINDING	2
-	#define LDAP_DEREF_ALWAYS	3
-		int		ld_timelimit;
-		int		ld_sizelimit;
-	#define LDAP_NO_LIMIT		0
-		int		ld_errno;
-		char		*ld_error;
-		char		*ld_matched;
-		int		ld_refhoplimit;
-		unsigned long	ld_options;
-	#define LDAP_OPT_REFERRALS      0x00000002 /* set by default */
-	#define LDAP_OPT_RESTART	0x00000004
-		/* ... other stuff you should not mess with ... */
-	} LDAP;
-.ft
-.fi
-.LP
 .B
 ldap_init()
 acts just like
 .BR ldap_open() ,
 but does not open a connection
 to the LDAP server.  The actual connection open will occur when the
-first operation is attempted.  At this time,
+first operation is attempted.
+.LP
+.B ldap_initialize()
+acts like
+.BR ldap_init() ,
+but it returns an integer indicating either success or the failure reason,
+and it allows to specify details for the connection in the schema portion
+of the URI.
+.LP
+At this time,
+.B ldap_open()
+and 
 .B ldap_init()
-is preferred.  
-.B ldap_open() will be depreciated in a later release.
+are deprecated in favor of
+.BR ldap_initialize() ,
+essentially because the latter allows to specify a schema in the URI
+and it explicitly returns an error code.
+.LP
+.B ldap_init_fd()
+allows an LDAP structure to be initialized using an already-opened
+connection. The
+.I proto
+parameter should be one of LDAP_PROTO_TCP, LDAP_PROTO_UDP,
+or LDAP_PROTO_IPC
+for a connection using TCP, UDP, or IPC, respectively. The value
+LDAP_PROTO_EXT
+may also be specified if user-supplied sockbuf handlers are going to
+be used. Note that support for UDP is not implemented unless libldap
+was built with LDAP_CONNECTIONLESS defined.
+The
+.I uri
+parameter may optionally be provided for informational purposes.
+
+Note: the first call into the LDAP library also initializes the global
+options for the library. As such the first call should be single-threaded
+or otherwise protected to insure that only one call is active. It is
+recommended that
+.BR ldap_get_option ()
+or
+.BR ldap_set_option ()
+be used in the program's main thread before any additional threads are created.
+See
+.BR ldap_get_option (3).
+
 .SH ERRORS
-If an error occurs, these routines will return NULL and errno should be
-set appropriately.
-.SH OPTIONS
-Options that affect a particular LDAP instance may be set by modifying
-the \fIld_options\fP field in the LDAP structure.  This field is set
-to \fILDAP_OPT_REFERRALS\fP in
-.B ldap_open() and
-.B ldap_init(),
-which causes the library to automatically follow referrals
-to other servers that may be returned in response to an LDAP operation.
-.LP
-The other supported option is \fILDAP_OPT_RESTART\fP, which if set will
-cause the LDAP library to restart the
-.BR select (2)
-system call when it is interrupted by the system (i.e., errno is set to
-EINTR).  This option is not supported on the Macintosh and under MS-DOS.
-.LP
-An option can be turned off by clearing the appropriate bit in the
-\fIld_options\fP field.
-.SH NOTES
-There are other elements in the LDAP structure that you should not
-change. You should not make any assumptions about the order of elements
-in the LDAP structure.
+If an error occurs,
+.B ldap_open()
+and
+.B ldap_init()
+will return NULL and errno should be set appropriately.
+.B ldap_initialize()
+and
+.B ldap_init_fd()
+will directly return the LDAP code associated to the error (or
+.I LDAP_SUCCESS
+in case of success);
+errno should be set as well whenever appropriate.
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_bind (3),
+.BR ldap_get_option (3),
+.BR ldap_set_option (3),
+.BR lber-sockbuf (3),
 .BR errno (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_open.3.links
===================================================================
--- openldap/trunk/doc/man/man3/ldap_open.3.links	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_open.3.links	2007-12-15 10:25:31 UTC (rev 892)
@@ -1 +1,2 @@
 ldap_init.3
+ldap_initialize.3

Modified: openldap/trunk/doc/man/man3/ldap_parse_reference.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_parse_reference.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_parse_reference.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAP_PARSE_REFERENCE 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_parse_reference.3,v 1.10.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_parse_reference.3,v 1.12.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -58,7 +58,4 @@
 .BR ldap_get_values (3),
 .BR ldap_controls_free (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_parse_result.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_parse_result.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_parse_result.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAP_PARSE_RESULT 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_parse_result.3,v 1.9.2.5 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_parse_result.3,v 1.11.2.2 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -99,11 +99,9 @@
 .BR ldap_result (3),
 .BR ldap_search (3),
 .BR ldap_memfree (3),
+.BR ldap_memvfree (3),
 .BR ldap_get_values (3),
 .BR ldap_controls_free (3),
 .BR lber-types (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_parse_sort_control.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_parse_sort_control.3)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_parse_sort_control.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_parse_sort_control.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,40 @@
+.TH LDAP_PARSE_SORT-CONTROL 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_parse_sort_control.3,v 1.1.2.2 2007/08/31 23:13:52 quanah Exp $
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldap_parse_sort_control \- Decode the information returned from a search operation that used a server-side sort control
+.SH LIBRARY
+OpenLDAP LDAP (libldap, -lldap)
+.SH SYNOPSIS
+.nf
+.ft B
+#include <ldap.h>
+.LP
+.ft B
+int ldap_parse_sort_control(ld, ctrls, returnCode, attribute)
+.ft
+LDAP *ld;
+LDAPControl **ctrls;
+unsigned long *returnCode;
+char **attribute;
+.SH DESCRIPTION
+This function is used to parse the results returned in a search operation
+that uses a server-side sort control.
+.LP
+It takes a null terminated array of LDAPControl structures usually obtained
+by a call to the 
+.BR ldap_parse_result
+function. A returncode which points to the sort control result code,and an array
+of LDAPControl structures that list the client controls to use with the search.
+The function also takes an out parameter \fIattribute\fP and if the sort operation
+fails, the server may return a string that indicates the first attribute in the
+sortKey list that caused the failure. If this parameter is NULL, no string is
+returned. If a string is returned, the memory should be freed by calling the
+ldap_memfree function.
+.SH NOTES
+.SH SEE ALSO
+.BR ldap_result (3),
+.BR ldap_controls_free (3)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_parse_vlv_control.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_parse_vlv_control.3)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_parse_vlv_control.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_parse_vlv_control.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,49 @@
+.TH LDAP_PARSE_VLV_CONTROL 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_parse_vlv_control.3,v 1.1.2.3 2007/11/14 09:04:34 ghenry Exp $
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldap_parse_vlv_control \- Decode the information returned from a search operation that used a VLV (virtual list view) control
+.SH LIBRARY
+OpenLDAP LDAP (libldap, -lldap)
+.SH SYNOPSIS
+.nf
+.ft B
+#include <ldap.h>
+.LP
+.ft B
+int ldap_parse_vlv_control( ld, ctrlp, target_posp, list_countp, contextp, errcodep )
+.ft
+LDAP *ld;
+LDAPControl **ctrlp;
+unsigned long *target_posp, *list_countp;
+struct berval **contextp;
+int *errcodep;
+.SH DESCRIPTION
+The
+.B ldap_parse_vlv_control
+is used to decode the information returned from a search operation that used a
+VLV (virtual list view)control. It takes a null terminated array of LDAPControl
+structures, usually obtained by a call to the 
+.BR ldap_parse_result function,
+a \fItarget_pos\fP which points to the list index of the target entry. If
+this parameter is NULL, the target position is not returned. The index returned 
+is an approximation of the position of the target entry. It is
+not guaranteed to be exact. The parameter \fIlist_countp\fP points to 
+the server's estimate of the size of the list. If this parameter is NULL, the
+size is not returned. \fIcontextp\fP is a pointer to the address of a berval
+structure that contains a server-generated context identifier if server returns
+one. If server does not return a context identifier, the server returns a NULL
+in this parameter. If this parameter is set to NULL, the context identifier is
+not returned. You should use this returned context in the next call to
+create a VLV control. When the berval structure is no longer needed, you should
+free the memory by calling the \fIber_bvfree function.e\fP
+\fIerrcodep\fP is an output parameter, which points to the result code returned
+by the server. If this parameter is NULL, the result code is not returned.
+.LP 
+See
+ldap.h for a list of possible return codes.
+.SH SEE ALSO
+.BR ldap_search (3)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_rename.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_rename.3)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_rename.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_rename.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,66 @@
+.TH LDAP_RENAME 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_rename.3,v 1.1.2.2 2007/08/31 23:13:52 quanah Exp $
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldap_rename, ldap_rename_s \- Renames the specified entry.
+.SH LIBRARY
+OpenLDAP LDAP (libldap, -lldap)
+.SH SYNOPSIS
+.nf
+.ft B
+#include <ldap.h>
+.LP
+.ft B
+int ldap_rename( ld, dn, newrdn, newparent, deleteoldrdn, sctrls[], cctrls[], msgidp );
+.ft
+LDAP *ld;
+const char *dn, *newrdn, *newparent;
+int deleteoldrdn;
+LDAPControl *sctrls[], *cctrls[];
+int *msgidp);
+.LP
+.ft B
+int ldap_rename_s( ld, dn, newrdn, newparent, deleteoldrdn, sctrls[], cctrls[] );
+.ft
+LDAP *ld;
+const char *dn, *newrdn, *newparent;
+int deleteoldrdn;
+LDAPControl *sctrls[], *cctrls[];
+.SH DESCRIPTION
+These routines are used to perform a LDAP rename operation.
+The function changes the leaf component of an entry's distinguished
+name and  optionally moves the entry to a new parent container. The 
+.B ldap_rename_s
+performs a rename operation synchronously.
+The method takes \fIdn\fP, which points to the distinguished name of
+the entry whose attribute is being compared, \fInewparent\fP,the distinguished
+name of the entry's new parent. If this parameter is NULL, only the RDN is changed.
+The root DN is specified by passing a zero length string, "". 
+\fIdeleteoldrdn\fP specifies whether the old RDN should be retained or deleted.
+Zero indicates that the old RDN should be retained. If you choose this option,
+the attribute will contain both names (the old and the new).
+Non-zero indicates that the old RDN should be deleted.
+\fIserverctrls\fP points to an array of LDAPControl structures that list the
+client controls to use with this extended operation. Use NULL to specify
+no client controls. \fIclientctrls\fP points to an array of LDAPControl 
+structures that list the client controls to use with the search.
+.LP
+.B ldap_rename
+works just like
+.B ldap_rename_s,
+but the operation is asynchronous. It returns the message id of the request
+it initiated. The result of this operation can be obtained by calling
+.BR ldap_result(3).
+.SH ERRORS
+.B ldap_rename()
+returns -1 in case of error initiating the request, and
+will set the \fIld_errno\fP field in the \fIld\fP parameter to
+indicate the error.
+.BR ldap_rename_s()
+returns the LDAP error code resulting from the rename operation.
+.SH SEE ALSO
+.BR ldap (3),
+.BR ldap_modify (3)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_rename.3.links (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_rename.3.links)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_rename.3.links	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_rename.3.links	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1 @@
+ldap_rename_s.3

Modified: openldap/trunk/doc/man/man3/ldap_result.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_result.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_result.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDAP_RESULT 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_result.3,v 1.16.2.5 2007/04/06 04:35:09 quanah Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_result.3,v 1.20.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -27,8 +27,8 @@
 routine is used to wait for and return the result of
 an operation previously initiated by one of the LDAP asynchronous
 operation routines (e.g.,
-.BR ldap_search (3),
-.BR ldap_modify (3),
+.BR ldap_search_ext (3),
+.BR ldap_modify_ext (3),
 etc.).  Those routines all return -1 in case of error, and an
 invocation identifier upon successful initiation of the operation. The
 invocation identifier is picked by the library and is guaranteed to be
@@ -43,7 +43,10 @@
 of the \fItimeout\fP parameter.
 If timeout is not a NULL pointer,  it  specifies  a  maximum
 interval  to wait for the selection to complete.  If timeout
-is a NULL  pointer,  the  select  blocks  indefinitely.   To
+is a NULL  pointer, the LDAP_OPT_TIMEOUT value set by
+.BR ldap_set_option (3)
+is used. With the default setting,
+the  select  blocks  indefinitely.   To
 effect  a  poll,  the  timeout argument should be a non-NULL
 pointer, pointing to a zero-valued timeval structure.  See
 .BR select (2)
@@ -72,7 +75,8 @@
 result have been received.
 .LP
 Upon success, the type of the result received is returned and the
-\fIresult\fP parameter will contain the result of the operation.  This
+\fIresult\fP parameter will contain the result of the operation;
+otherwise, the \fIresult\fP parameter is undefined.  This
 result should be passed to the LDAP parsing routines,
 .BR ldap_first_message (3)
 and friends, for interpretation.
@@ -99,7 +103,7 @@
 result(s) by
 .B ldap_result()
 or
-.BR ldap_search_s (3)
+.BR ldap_search_ext_s (3)
 and friends.
 It takes a pointer to the result or result chain to be freed and returns
 the type of the last message in the chain.
@@ -122,11 +126,7 @@
 return -1 on error.
 .SH SEE ALSO
 .BR ldap (3),
-.BR ldap_search (3),
 .BR ldap_first_message (3),
 .BR select (2)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_schema.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_schema.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_schema.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,16 +1,9 @@
 .TH LDAP_SCHEMA 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_schema.3,v 1.12.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_schema.3,v 1.15.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 2000-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_str2syntax, ldap_syntax2str, ldap_syntax2name, ldap_syntax_free,
-ldap_str2matchingrule, ldap_matchingrule2str, ldap_matchingrule2name,
-ldap_matchingrule_free,
-ldap_str2attributetype, ldap_attributetype2str,
-ldap_attributetype2name, ldap_attributetype_free,
-ldap_str2objectclass, ldap_objectclass2str, ldap_objectclass2name,
-ldap_objectclass_free,
-ldap_scherr2str \- Schema definition handling routines
+ldap_str2syntax, ldap_syntax2str, ldap_syntax2name, ldap_syntax_free, ldap_str2matchingrule, ldap_matchingrule2str, ldap_matchingrule2name, ldap_matchingrule_free, ldap_str2attributetype, ldap_attributetype2str, ldap_attributetype2name, ldap_attributetype_free, ldap_str2objectclass, ldap_objectclass2str, ldap_objectclass2name, ldap_objectclass_free, ldap_scherr2str \- Schema definition handling routines
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
@@ -117,13 +110,13 @@
 int code;
 .SH DESCRIPTION
 These routines are used to parse schema definitions in the syntax
-defined in RFC 2252 into structs and handle these structs.  These
+defined in RFC 4512 into structs and handle these structs.  These
 routines handle four kinds of definitions: syntaxes, matching rules,
 attribute types and object classes.  For each definition kind, four
 routines are provided.
 .LP
 .B ldap_str2xxx()
-takes a definition in RFC 2252 format in argument
+takes a definition in RFC 4512 format in argument
 .IR s
 as a NUL-terminated string and returns, if possible, a pointer to a
 newly allocated struct of the appropriate kind.  The caller is
@@ -145,7 +138,7 @@
 syntax recognized.  The following values are defined:
 .TP
 .B LDAP_SCHEMA_ALLOW_NONE
-strict parsing according to RFC 2252.
+strict parsing according to RFC 4512.
 .TP
 .B LDAP_SCHEMA_ALLOW_NO_OID
 permit definitions that do not contain an initial OID.
@@ -278,7 +271,7 @@
 .LP
 Routines
 .B ldap_xxx2str()
-return a string representation in the format described by RFC 2252 of
+return a string representation in the format described by RFC 4512 of
 the struct passed in the argument.  The string is a newly allocated
 string that must be freed by the caller.  These routines may return
 NULL if no memory can be allocated for the string.
@@ -324,8 +317,4 @@
 .SH SEE ALSO
 .BR ldap (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
-
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_search.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_search.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_search.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,131 +1,136 @@
 .TH LDAP_SEARCH 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_search.3,v 1.17.2.6 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_search.3,v 1.22.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_search, ldap_search_s, ldap_search_st \- Perform an LDAP search operation
+ldap_search, ldap_search_s, ldap_search_st, ldap_search_ext, ldap_search_ext_s \- Perform an LDAP search operation
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
 .nf
 .ft B
-#include <sys/time.h> /* for struct timeval definition */
+#include <sys/types.h>
 #include <ldap.h>
 .LP
 .ft B
-int ldap_search(ld, base, scope, filter, attrs, attrsonly)
-.ft
-LDAP *ld;
-char *base;
-int scope;
-char *filter, *attrs[];
-int attrsonly;
+int ldap_search_ext(
+.RS
+LDAP *\fIld\fB,
+char *\fIbase\fB,
+int \fIscope\fB,
+char *\fIfilter\fB,
+char *\fIattrs\fB[],
+int \fIattrsonly\fB,
+LDAPControl **\fIserverctrls\fB,
+LDAPControl **\fIclientctrls\fB,
+struct timeval *\fItimeout\fB,
+int \fIsizelimit\fB,
+int *\fImsgidp\fB );
+.RE
 .LP
 .ft B
-int ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res)
-.ft
-LDAP *ld;
-char *base;
-int scope;
-char *filter, *attrs[]
-int attrsonly;
-LDAPMessage **res;
-.LP
-.ft B
-int ldap_search_st(ld, base, scope, filter, attrs, attrsonly, timeout, res)
-.ft
-LDAP *ld;
-char *base;
-int scope;
-char *filter, *attrs[]
-int attrsonly;
-struct timeval *timeout;
-LDAPMessage **res;
+int ldap_search_ext_s(
+.RS
+LDAP *\fIld\fB,
+char *\fIbase\fB,
+int \fIscope\fB,
+char *\fIfilter\fB,
+char *\fIattrs\fB[],
+int \fIattrsonly\fB,
+LDAPControl **\fIserverctrls\fB,
+LDAPControl **\fIclientctrls\fB,
+struct timeval *\fItimeout\fB,
+int \fIsizelimit\fB,
+LDAPMessage **\fIres\fB );
+.RE
 .SH DESCRIPTION
 These routines are used to perform LDAP search operations.
-.B ldap_search_s()
+The
+.B ldap_search_ext_s()
+routine
 does the search synchronously (i.e., not
-returning until the operation completes).
-.B ldap_search_st()
-does
-the same, but allows a \fItimeout\fP to be specified.
-.B ldap_search()
-is the asynchronous version, initiating the search and returning
-the message id of the operation it initiated.
-\fIBase\fP is the DN of the entry at which to start the search.
-\fIScope\fP is the scope of the search and should be one of LDAP_SCOPE_BASE,
-to search the object itself,
-LDAP_SCOPE_ONELEVEL, to search the object's immediate children,
-or LDAP_SCOPE_SUBTREE, to search the object and all its descendants.
+returning until the operation completes), providing a pointer
+to the resulting LDAP messages at the location pointed to by
+the \fIres\fP parameter.
 .LP
-\fIFilter\fP is a string
-representation of the filter to apply in the search.  Simple filters
-can be specified as \fI(attributetype=attributevalue)\fP.  More complex
-filters are specified using a prefix notation according to the following
-BNF:
+The
+.B ldap_search_ext()
+routine is the asynchronous version, initiating the search and returning
+the message id of the operation it initiated in the integer
+pointed to by the \fImsgidp\fP parameter.
 .LP
-.nf
-        <filter> ::= '(' <filtercomp> ')'
-        <filtercomp> ::= <and> | <or> | <not> | <simple>
-        <and> ::= '&' <filterlist>
-        <or> ::= '|' <filterlist>
-        <not> ::= '!' <filter>
-        <filterlist> ::= <filter> | <filter> <filterlist>
-        <simple> ::= <attributetype> <filtertype> <attributevalue>
-        <filtertype> ::= '=' | '~=' | '<=' | '>='
-.fi
+The \fIbase\fP parameter is the DN of the entry at which to start the search.
 .LP
-The '~=' construct is used to specify approximate matching.  The
-representation for <attributetype> and <attributevalue> are as
-described in RFC 2254.  In addition, <attributevalue> can be a single *
-to achieve an attribute existence test, or can contain text and *'s
-interspersed to achieve substring matching.
+The \fIscope\fP parameter is the scope of the search and should be one
+of LDAP_SCOPE_BASE, to search the object itself, LDAP_SCOPE_ONELEVEL,
+to search the object's immediate children, LDAP_SCOPE_SUBTREE, to
+search the object and all its descendants, or LDAP_SCOPE_CHILDREN,
+to search all of the descendants.   Note that the latter requires
+the server support the LDAP Subordinates Search Scope extension.
 .LP
-For example, the filter "(mail=*)" will find any entries that have a mail
-attribute.  The filter "(mail=*@terminator.rs.itd.umich.edu)" will find
-any entries that have a mail attribute ending in the specified string.
-To put parentheses in a filter, escape them with a backslash '\\'
-character.  See RFC 2254 for a more complete description of allowable
-filters. 
+The \fIfilter\fP is a string representation of the filter to
+apply in the search.  The string should conform to the format
+specified in RFC 4515 as extended by RFC 4526.  For instance,
+"(cn=Jane Doe)".  Note that use of the extension requires the
+server to support the LDAP Absolute True/False Filter extension.
+NULL may be specified to indicate the library should send the
+filter (objectClass=*).
 .LP
-\fIAttrs\fP is a null-terminated array of attribute types to return
-from entries that match \fIfilter\fP.
+The \fIattrs\fP parameter is a null-terminated array of attribute
+descriptions to return from matching entries.
 If NULL is specified, the return of all user attributes is requested.
-The type "*" (LDAP_ALL_USER_ATTRIBUTES) may be used to request
+The description "*" (LDAP_ALL_USER_ATTRIBUTES) may be used to request
 all user attributes to be returned.
-The type "+"(LDAP_ALL_OPERATIONAL_ATTRIBUTES) may be used to request
-all operational attributes to be returned.
-To request no attributes, the type "1.1" (LDAP_NO_ATTRS)
+The description "+"(LDAP_ALL_OPERATIONAL_ATTRIBUTES) may be used to
+request all operational attributes to be returned.  Note that this
+requires the server to support the LDAP All Operational Attribute
+extension.
+To request no attributes, the description "1.1" (LDAP_NO_ATTRS)
 should be listed by itself.
 .LP
-\fIAttrsonly\fP should be set to 1 if
-only attribute types are wanted.  It should be set to 0 if both
-attributes types and attribute values are wanted.
-.SH ERRORS
-.B ldap_search_s()
-and
-.B ldap_search_st()
-will return the LDAP error code resulting from the search operation.
-See
+The \fIattrsonly\fP parameter should be set to a non-zero value
+if only attribute descriptions are wanted.  It should be set to zero (0)
+if both attributes descriptions and attribute values are wanted.
+.LP
+The \fIserverctrls\fP and \fIclientctrls\fP parameters may be used
+to specify server and client controls, respectively.
+.LP
+The
+.B ldap_search_ext_s()
+routine is the synchronous version of
+.BR ldap_search_ext().
+.LP
+It also returns a code indicating success or, in the
+case of failure, indicating the nature of the failure
+of the operation.  See
 .BR ldap_error (3)
 for details.
-.B ldap_search()
-returns -1 in case of trouble.
 .SH NOTES
 Note that both read
 and list functionality are subsumed by these routines,
 by using a filter like "(objectclass=*)" and a scope of LDAP_SCOPE_BASE (to
 emulate read) or LDAP_SCOPE_ONELEVEL (to emulate list).
 .LP
-These routines may dynamically allocate memory.  The caller is
+These routines may dynamically allocate memory. The caller is
 responsible for freeing such memory using supplied deallocation
-routines.  Return values are contained in <ldap.h>.
+routines. Return values are contained in <ldap.h>.
+.SH DEPRECATED INTERFACES
+The 
+.B ldap_search()
+routine is deprecated in favor of the
+.B ldap_search_ext()
+routine.  The 
+.B ldap_search_s()
+and
+.B ldap_search_st()
+routines are deprecated in favor of the
+.B ldap_search_ext_s()
+routine.
+.LP
+.so Deprecated
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldap_result (3),
 .BR ldap_error (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man3/ldap_sort.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_sort.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_sort.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,116 +1,21 @@
 .TH LDAP_SORT 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_sort.3,v 1.13.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_sort.3,v 1.15.2.3 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_sort_entries, ldap_sort_values, ldap_sort_strcasecmp \- LDAP sorting routines
+ldap_sort_entries, ldap_sort_values, ldap_sort_strcasecmp \- LDAP sorting routines (deprecated)
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
-.SH SYNOPSIS
-.nf
-.ft B
-#include <ldap.h>
-.LP
-.ft B
-ldap_sort_entries(ld, chain, attr, cmp)
-.ft
-LDAP *ld;
-LDAPMessage **chain;
-char *attr;
-int (*cmp)();
-.LP
-.ft B
-ldap_sort_values(ld, vals, cmp)
-.ft
-LDAP *ld;
-char **vals;
-int (*cmp)();
-.LP
-.ft B
-ldap_sort_strcasecmp(a, b)
-.ft
-char *a;
-char *b;
 .SH DESCRIPTION
-These routines are used to sort lists of entries and values retrieved
-from an LDAP server.
-.B ldap_sort_entries()
-is used to sort a chain
-of entries retrieved from an LDAP search call either by DN or by some
-arbitrary attribute in the entries.  It takes \fIld\fP, the LDAP
-structure, which is only used for error reporting, \fIchain\fP, the
-list of entries as returned by
-.BR ldap_search_s (3)
-or
-.BR ldap_result (3).
-\fIattr\fP is the attribute to use as a key in the sort
-or NULL to sort by DN, and \fIcmp\fP is the comparison function to use
-when comparing values (or individual DN components if sorting by DN).
-In this case, \fIcmp\fP should be a function taking two single values
-of the \fIattr\fP to sort by, and returning a value less than zero,
-equal to zero, or greater than zero, depending on whether the first
-argument is less than, equal to, or greater than the second argument.
-The convention is the same as used by
-.BR qsort (3),
-which is called to do the actual sorting.
-.LP
-.B ldap_sort_values()
-is used to sort an array of values from an entry,
-as returned by
-.BR ldap_get_values (3).
-It takes the LDAP connection
-structure \fIld\fP, the array of values
-to sort \fIvals\fP, and \fIcmp\fP, the comparison
-function to use during the sort.
-Note that \fIcmp\fP will be passed a pointer to each element in the
-\fIvals\fP array, so if you pass the normal char ** for this parameter,
-\fIcmp\fP should take two char **'s as arguments (i.e., you cannot
-pass \fIstrcasecmp\fP or its friends for \fIcmp\fP).  You can, however,
-pass the function
-.B ldap_sort_strcasecmp()
-for this purpose.
-.LP
-For example:
-.LP
-.nf
-.ft tt
-	LDAP *ld;
-	LDAPMessage *res;
-
-	/*
-	 * ... call to ldap_search_s(), fill in res,
-	 * retrieve sn attr ...
-	 */
-
-	/* now sort the entries on surname attribute */
-	if ( ldap_sort_entries( ld, &res, "sn",
-			ldap_sort_strcasecmp ) != 0 )
-		ldap_perror( ld, "ldap_sort_entries" );
-.ft
-.fi
-.SH NOTES
-.LP
 The
-.B ldap_sort_entries()
-routine applies the comparison function to
-each value of the attribute in the array as returned by a call to
-.BR ldap_get_values (3),
-until a mismatch is found.
-This works fine for single-valued attributes, but
-may produce unexpected results for multi-valued attributes.
-When sorting by DN, the comparison function is
-applied to an exploded version of the DN, without types.
-The return values for all of these functions are declared in the
-<ldap.h> header file.  Some routines may dynamically allocate memory.
-Callers are responsible for freeing such memory using the supplied
-deallocation routines.
+.BR ldap_sort_entries (),
+.BR ldap_sort_values (),
+and
+.BR ldap_sort_strcasecmp ()
+are deprecated.  
+.LP
+.so Deprecated
 .SH SEE ALSO
-.BR ldap (3),
-.BR ldap_search (3),
-.BR ldap_result (3),
-.BR qsort (3)
+.BR ldap (3)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_sync.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_sync.3)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_sync.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_sync.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,326 @@
+.TH LDAP_SYNC 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_sync.3,v 1.1.2.2 2007/08/31 23:13:52 quanah Exp $
+.\" Copyright 2006 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldap_sync_init, ldap_sync_init_refresh_only, ldap_sync_init_refresh_and_persist, ldap_sync_poll \- LDAP sync routines
+.SH LIBRARY
+OpenLDAP LDAP (libldap, -lldap)
+.SH SYNOPSIS
+.nf
+.B #include <ldap_sync.h>
+.LP
+.BI "int ldap_sync_init(ldap_sync_t *" ls ", int " mode ");"
+.LP
+.BI "int ldap_sync_init_refresh_only(ldap_sync_t *" ls ");"
+.LP
+.BI "int ldap_sync_init_refresh_and_persist(ldap_sync_t *" ls  ");"
+.LP
+.BI "int ldap_sync_poll(ldap_sync_t *" ls ");"
+.LP
+.BI "ldap_sync_t * ldap_sync_initialize(ldap_sync_t *" ls ");"
+.LP
+.BI "int ldap_sync_destroy(ldap_sync_t *" ls ", int " freeit ");"
+.LP
+.BI "typedef int (*" ldap_sync_search_entry_f ")(ldap_sync_t *" ls ","
+.RS
+.BI "LDAPMessage *" msg ", struct berval *" entryUUID ","
+.BI "ldap_sync_refresh_t " phase ");"
+.RE
+.LP
+.BI "typedef int (*" ldap_sync_search_reference_f ")(ldap_sync_t *" ls ","
+.RS
+.BI "LDAPMessage *" msg ");"
+.RE
+.LP
+.BI "typedef int (*" ldap_sync_intermediate_f ")(ldap_sync_t *" ls ","
+.RS
+.BI "LDAPMessage *" msg ", BerVarray " syncUUIDs ","
+.BI "ldap_sync_refresh_t " phase ");"
+.RE
+.LP
+.BI "typedef int (*" ldap_sync_search_result_f ")(ldap_sync_t *" ls ","
+.RS
+.BI "LDAPMessage *" msg ", int " refreshDeletes ");"
+.RE
+.SH DESCRIPTION
+.LP
+These routines provide an interface to the LDAP Content Synchronization 
+operation (RFC 4533).
+They require an
+.BR ldap_sync_t
+structure to be set up with parameters required for various phases
+of the operation; this includes setting some handlers for special events.
+All handlers take a pointer to the \fBldap_sync_t\fP structure as the first
+argument, and a pointer to the \fBLDAPMessage\fP structure as received
+from the server by the client library, plus, occasionally, other specific
+arguments.
+
+The members of the \fBldap_sync_t\fP structure are:
+.TP
+.BI "char *" ls_base
+The search base; by default, the
+.B BASE
+option in
+.BR ldap.conf (5).
+.TP
+.BI "int " ls_scope
+The search scope (one of 
+.BR LDAP_SCOPE_BASE ,
+.BR LDAP_SCOPE_ONELEVEL ,
+.BR LDAP_SCOPE_SUBORDINATE
+or
+.BR LDAP_SCOPE_SUBTREE ;
+see
+.B ldap.h
+for details).
+.TP
+.BI "char *" ls_filter
+The filter (RFC 4515); by default, 
+.BR (objectClass=*) .
+.TP
+.BI "char **" ls_attrs
+The requested attributes; by default
+.BR NULL ,
+indicating all user attributes.
+.TP
+.BI "int " ls_timelimit
+The requested time limit (in seconds); by default
+.BR 0 ,
+to indicate no limit.
+.TP
+.BI "int " ls_sizelimit
+The requested size limit (in entries); by default
+.BR 0 ,
+to indicate no limit.
+.TP
+.BI "int " ls_timeout
+The desired timeout during polling with
+.BR ldap_sync_poll (3).
+A value of
+.BR -1
+means that polling is blocking, so 
+.BR ldap_sync_poll (3)
+will not return until a message is received; a value of
+.BR 0
+means that polling returns immediately, no matter if any response
+is available or not; a positive value represents the timeout the
+.BR ldap_sync_poll (3)
+function will wait for response before returning, unless a message
+is received; in that case, 
+.BR ldap_sync_poll (3)
+returns as soon as the message is available.
+.TP
+.BI "ldap_sync_search_entry_f " ls_search_entry
+A function that is called whenever an entry is returned.
+The
+.BR msg
+argument is the
+.BR LDAPMessage
+that contains the searchResultEntry; it can be parsed using the regular 
+client API routines, like 
+.BR ldap_get_dn (3),
+.BR ldap_first_attribute (3),
+and so on.
+The
+.BR entryUUID
+argument contains the entryUUID of the entry.
+The
+.BR phase
+argument indicates the type of operation: one of
+.BR LDAP_SYNC_CAPI_PRESENT ,
+.BR LDAP_SYNC_CAPI_ADD ,
+.BR LDAP_SYNC_CAPI_MODIFY ,
+.BR LDAP_SYNC_CAPI_DELETE ;
+in case of
+.BR LDAP_SYNC_CAPI_PRESENT
+or
+.BR LDAP_SYNC_CAPI_DELETE ,
+only the DN is contained in the 
+.IR LDAPMessage ;
+in case of 
+.BR LDAP_SYNC_CAPI_MODIFY ,
+the whole entry is contained in the 
+.IR LDAPMessage ,
+and the application is responsible of determining the differences
+between the new view of the entry provided by the caller and the data
+already known.
+.TP
+.BI "ldap_sync_search_reference_f " ls_search_reference
+A function that is called whenever a search reference is returned.
+The
+.BR msg
+argument is the
+.BR LDAPMessage
+that contains the searchResultReference; it can be parsed using 
+the regular client API routines, like 
+.BR ldap_parse_reference (3).
+.TP
+.BI "ldap_sync_intermediate_f " ls_intermediate
+A function that is called whenever something relevant occurs during 
+the refresh phase of the search, which is marked by
+an \fIintermediateResponse\fP message type.
+The
+.BR msg
+argument is the
+.BR LDAPMessage
+that contains the intermediate response; it can be parsed using 
+the regular client API routines, like 
+.BR ldap_parse_intermediate (3).
+The
+.BR syncUUIDs
+argument contains an array of UUIDs of the entries that depends
+on the value of the
+.BR phase
+argument.
+In case of
+.BR LDAP_SYNC_CAPI_PRESENTS ,
+the "present" phase is being entered;
+this means that the following sequence of results will consist
+in entries in "present" sync state.
+In case of
+.BR LDAP_SYNC_CAPI_DELETES ,
+the "deletes" phase is being entered;
+this means that the following sequence of results will consist
+in entries in "delete" sync state.
+In case of
+.BR LDAP_SYNC_CAPI_PRESENTS_IDSET ,
+the message contains a set of UUIDs of entries that are present;
+it replaces a "presents" phase.
+In case of
+.BR LDAP_SYNC_CAPI_DELETES_IDSET ,
+the message contains a set of UUIDs of entries that have been deleted;
+it replaces a "deletes" phase.
+In case of
+.BR LDAP_SYNC_CAPI_DONE,
+a "presents" phase with "refreshDone" set to "TRUE" has been returned
+to indicate that the refresh phase of refreshAndPersist is over, and
+the client should start polling.
+Except for the
+.BR LDAP_SYNC_CAPI_PRESENTS_IDSET
+and
+.BR LDAP_SYNC_CAPI_DELETES_IDSET
+cases,
+.BR syncUUIDs
+is NULL.
+.BR
+.TP
+.BI "ldap_sync_search_result_f " ls_search_result
+A function that is called whenever a searchResultDone is returned.
+In refreshAndPersist this can only occur when the server decides
+that the search must be interrupted.
+The
+.BR msg
+argument is the
+.BR LDAPMessage
+that contains the response; it can be parsed using 
+the regular client API routines, like 
+.BR ldap_parse_result (3).
+The
+.BR refreshDeletes
+argument is not relevant in this case; it should always be -1.
+.TP
+.BI "void *" ls_private
+A pointer to private data.  The client may register here
+a pointer to data the handlers above may need.
+.TP
+.BI "LDAP *" ls_ld
+A pointer to a LDAP structure that is used to connect to the server.
+It is the responsibility of the client to initialize the structure
+and to provide appropriate authentication and security in place.
+
+.SH "GENERAL USE"
+A
+.B ldap_sync_t
+structure is initialized by calling
+.BR ldap_sync_initialize(3).
+This simply clears out the contents of an already existing
+.B ldap_sync_t
+structure, and sets appropriate values for some members.
+After that, the caller is responsible for setting up the
+connection (member
+.BR ls_ld ),
+eventually setting up transport security (TLS),
+for binding and any other initialization.
+The caller must also fill all the documented search-related fields
+of the
+.B ldap_sync_t
+structure.
+
+At the end of a session, the structure can be cleaned up by calling
+.BR ldap_sync_destroy (3),
+which takes care of freeing all data assuming it was allocated by
+.BR ldap_mem* (3)
+routines.
+Otherwise, the caller should take care of destroying and zeroing out
+the documented search-related fields, and call
+.BR ldap_sync_destroy (3)
+to free undocumented members set by the API.
+
+.SH "REFRESH ONLY"
+The
+.BR refreshOnly
+functionality is obtained by periodically calling
+.BR ldap_sync_init (3)
+with mode set to
+.BR LDAP_SYNC_REFRESH_ONLY ,
+or, which is equivalent, by directly calling
+.BR ldap_sync_init_refresh_only (3).
+The state of the search, and the consistency of the search parameters,
+is preserved across calls by passing the 
+.B ldap_sync_t
+structure as left by the previous call.
+
+.SH "REFRESH AND PERSIST"
+The
+.BR refreshAndPersist
+functionality is obtained by calling
+.BR ldap_sync_init (3)
+with mode set to
+.BR LDAP_SYNC_REFRESH_AND_PERSIST ,
+or, which is equivalent, by directly calling
+.BR ldap_sync_init_refresh_and_persist (3)
+and, after a successful return, by repeatedly polling with
+.BR ldap_sync_poll (3)
+according to the desired pattern.
+
+A client may insert a call to 
+.BR ldap_sync_poll (3)
+into an external loop to check if any modification was returned;
+in this case, it might be appropriate to set
+.BR ls_timeout
+to 0, or to set it to a finite, small value.
+Otherwise, if the client's main purpose consists in waiting for
+responses, a timeout of -1 is most suitable, so that the function
+only returns after some data has been received and handled.
+
+.SH ERRORS
+All routines return any LDAP error resulting from a lower-level error
+in the API calls they are based on, or LDAP_SUCCESS in case of success.
+.BR ldap_sync_poll (3) 
+may return 
+.BR LDAP_SYNC_REFRESH_REQUIRED
+if a full refresh is requested by the server.
+In this case, it is appropriate to call
+.BR ldap_sync_init (3)
+again, passing the same
+.B ldap_sync_t
+structure as resulted from any previous call.
+.SH NOTES
+.SH SEE ALSO
+.BR ldap (3),
+.BR ldap_search_ext (3),
+.BR ldap_result (3) ;
+.B RFC 4533
+(http://www.rfc-editor.org),
+.SH AUTHOR
+Designed and implemented by Pierangelo Masarati, based on RFC 4533
+and loosely inspired by syncrepl code in
+.BR slapd (8).
+.SH ACKNOWLEDGEMENTS
+Initially developed by
+.BR "SysNet s.n.c."
+.B OpenLDAP
+is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
+.B OpenLDAP
+is derived from University of Michigan LDAP 3.3 Release.  

Copied: openldap/trunk/doc/man/man3/ldap_tls.3 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_tls.3)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_tls.3	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_tls.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,41 @@
+.TH LDAP_TLS 3 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_tls.3,v 1.1.2.2 2007/08/31 23:13:52 quanah Exp $
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldap_start_tls, ldap_start_tls_s, ldap_tls_inplace, ldap_install_tls \- LDAP TLS initialization routines
+.SH LIBRARY
+OpenLDAP LDAP (libldap, -lldap)
+.SH SYNOPSIS
+.B #include <ldap.h>
+.LP
+.BI "int ldap_start_tls(LDAP *" ld ");"
+.LP
+.BI "int ldap_start_tls_s(LDAP *" ld ", LDAPControl **" serverctrls ", LDAPControl **" clientctrls ");"
+.LP
+.BI "int ldap_tls_inplace(LDAP *" ld ");"
+.LP
+.BI "int ldap_install_tls(LDAP *" ld ");"
+.SH DESCRIPTION
+These routines are used to initiate TLS processing on an LDAP session.
+.BR ldap_start_tls_s ()
+sends a StartTLS request to a server, waits for the reply, and then installs
+TLS handlers on the session if the request succeeded. The routine returns
+.B LDAP_SUCCESS
+if everything succeeded, otherwise it returns an LDAP error code.
+.BR ldap_start_tls ()
+sends a StartTLS request to a server and does nothing else. It returns
+.B LDAP_SUCCESS
+if the request was sent successfully.
+.BR ldap_tls_inplace ()
+returns 1 if TLS handlers have been installed on the specified session, 0
+otherwise.
+.BR ldap_install_tls ()
+installs the TLS handlers on the given session. It returns
+.B LDAP_LOCAL_ERROR
+if TLS is already installed.
+.SH SEE ALSO
+.BR ldap (3),
+.BR ldap_error (3)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Copied: openldap/trunk/doc/man/man3/ldap_tls.3.links (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man3/ldap_tls.3.links)
===================================================================
--- openldap/trunk/doc/man/man3/ldap_tls.3.links	                        (rev 0)
+++ openldap/trunk/doc/man/man3/ldap_tls.3.links	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,4 @@
+ldap_start_tls.3
+ldap_start_tls_s.3
+ldap_tls_inplace.3
+ldap_install_tls.3

Modified: openldap/trunk/doc/man/man3/ldap_url.3
===================================================================
--- openldap/trunk/doc/man/man3/ldap_url.3	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man3/ldap_url.3	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,18 +1,15 @@
 .TH LDAP_URL 3 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_url.3,v 1.16.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man3/ldap_url.3,v 1.18.2.4 2007/11/14 09:04:34 ghenry Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-ldap_is_ldap_url,
-ldap_url_parse,
-ldap_free_urldesc \- LDAP Uniform Resource Locator routines
+ldap_is_ldap_url, ldap_url_parse, ldap_free_urldesc \- LDAP Uniform Resource Locator routines
 .SH LIBRARY
 OpenLDAP LDAP (libldap, -lldap)
 .SH SYNOPSIS
 .nf
 .ft B
 #include <ldap.h>
-.ft
 .LP
 .ft B
 int ldap_is_ldap_url( const char *url )
@@ -34,10 +31,10 @@
 } LDAPURLDesc;
 .LP
 .ft B
-ldap_free_urldesc( LDAPURLDesc *ludp )
+void ldap_free_urldesc( LDAPURLDesc *ludp );
 .SH DESCRIPTION
 These routines support the use of LDAP URLs (Uniform Resource Locators)
-as detailed in RFC 2255.  LDAP URLs look like this:
+as detailed in RFC 4516.  LDAP URLs look like this:
 .nf
 
   \fBldap://\fP\fIhostport\fP\fB/\fP\fIdn\fP[\fB?\fP\fIattrs\fP[\fB?\fP\fIscope\fP[\fB?\fP\fIfilter\fP[\fB?\fP\fIexts\fP]]]]
@@ -57,7 +54,7 @@
 .fi
 .LP
 URLs that are wrapped in angle-brackets and/or preceded by "URL:" are also
-tolerated.  Alternative schemes such as ldaps:// and ldapi:// may be
+tolerated.  Alternative LDAP schemes such as ldaps:// and ldapi:// may be
 parsed using the below routines as well.
 .LP
 .B ldap_is_ldap_url()
@@ -78,12 +75,9 @@
 a call to
 .B ldap_url_parse().
 .SH SEE ALSO
+.nf
 .BR ldap (3)
-.LP
-.B The LDAP URL Format, RFC 2255,
-Tim Howes and Mark Smith, December 1997.
+.BR "RFC 4516" " <http://www.rfc-editor.org/rfc/rfc4516.txt>"
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.fi
+.so ../Project

Modified: openldap/trunk/doc/man/man5/Makefile.in
===================================================================
--- openldap/trunk/doc/man/man5/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # man5 Makefile.in for OpenLDAP
-# $OpenLDAP: pkg/ldap/doc/man/man5/Makefile.in,v 1.8.2.5 2007/01/02 21:43:45 kurt Exp $
+# $OpenLDAP: pkg/ldap/doc/man/man5/Makefile.in,v 1.11.2.2 2007/08/31 23:13:52 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/doc/man/man5/ldap.conf.5
===================================================================
--- openldap/trunk/doc/man/man5/ldap.conf.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/ldap.conf.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,8 +1,7 @@
 .TH LDAP.CONF 5 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/ldap.conf.5,v 1.28.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/ldap.conf.5,v 1.33.2.5 2007/08/31 23:13:52 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.UC 6
 .SH NAME
 ldap.conf, .ldaprc \- ldap configuration file
 .SH SYNOPSIS
@@ -49,21 +48,65 @@
 .SH OPTIONS
 The configuration options are case-insensitive;
 their value, on a case by case basis, may be case-sensitive.
+.LP
+Blank lines and lines beginning with a hash mark (`#')
+are ignored up to their end.
+.LP
+Valid lines are made of an option's name (a sequence of non-blanks,
+conventionally written in uppercase, although not required), 
+followed by a value.
+The value starts with the first non-blank character after 
+the option's name, and terminates at the end of the line, 
+or at the last sequence of blanks before the end of the line.
+The tokenization of the value, if any, is delegated to the handler(s)
+for that option, if any.  Quoting values that contain blanks 
+may be incorrect, as the quotes would become part of the value.
+For example,
+
+	URI	"ldap:// ldaps://"
+
+is incorrect, while
+
+	URI	ldap:// ldaps://
+
+is correct (note the absence of the double quotes).
+.LP
+A line cannot be longer than LINE_MAX, which should be more than 2000 bytes
+on all platforms.
+There is no mechanism to split a long line on multiple lines, either for
+beautification or to overcome the above limit.
+.LP
 The different configuration options are:
 .TP
-.B URI <ldap[s]://[name[:port]] ...>
+.B URI <ldap[si]://[name[:port]] ...>
 Specifies the URI(s) of an LDAP server(s) to which the
 .I LDAP 
-library should connect.  The URI scheme may be either
-.B ldap
+library should connect.  The URI scheme may be any of
+.BR ldap ,
+.B ldaps 
 or
-.B ldaps 
-which refer to LDAP over TCP and LDAP over SSL (TLS) respectively.
+.BR ldapi ,
+which refer to LDAP over TCP, LDAP over SSL (TLS) and LDAP
+over IPC (UNIX domain sockets), respectively.
 Each server's name can be specified as a
 domain-style name or an IP address literal.  Optionally, the
 server's name can followed by a ':' and the port number the LDAP
 server is listening on.  If no port number is provided, the default
 port for the scheme is used (389 for ldap://, 636 for ldaps://).
+For LDAP over IPC,
+.B name 
+is the name of the socket, and no
+.B port
+is required, nor allowed; note that directory separators must be 
+URL-encoded, like any other characters that are special to URLs; 
+so the socket
+
+	/usr/local/var/ldapi
+
+must be specified as
+
+	ldapi://%2Fusr%2Flocal%2Fvar%2Fldapi
+
 A space separated list of URIs may be provided.
 .TP
 .B BASE <base>
@@ -73,8 +116,30 @@
 .B BINDDN <dn>
 Specifies the default bind DN to use when performing ldap operations.
 The bind DN must be specified as a Distinguished Name in LDAP format.
-This is a user\-only option.
+.B This is a user\-only option.
 .TP
+.B DEREF <when>
+Specifies how alias dereferencing is done when performing a search. The
+.B <when>
+can be specified as one of the following keywords:
+.RS
+.TP
+.B never
+Aliases are never dereferenced. This is the default.
+.TP
+.B searching
+Aliases are dereferenced in subordinates of the base object, but
+not in locating the base object of the search.
+.TP
+.B finding
+Aliases are only dereferenced when locating the base object of the search.
+.TP
+.B always
+Aliases are dereferenced both in searching and in locating the base object
+of the search.
+.RE
+.TP
+.TP
 .B HOST <name[:port] ...>
 Specifies the name(s) of an LDAP server(s) to which the
 .I LDAP 
@@ -86,6 +151,10 @@
 is deprecated in favor of
 .BR URI .
 .TP
+.B NETWORK_TIMEOUT <integer>
+Specifies the timeout (in seconds) after which the poll(2)/select(2)
+following a connect(2) returns in case of no activity.
+.TP
 .B PORT <port>
 Specifies the default port used when connecting to LDAP servers(s).
 The port may be specified as a number.
@@ -100,6 +169,10 @@
 Note that the command line tools
 .BR ldapsearch (1)
 &co always override this option.
+.\" This should only be allowed via ldap_set_option(3)
+.\".TP
+.\".B RESTART <on/true/yes/off/false/no>
+.\"Determines whether the library should implicitly restart connections (FIXME).
 .TP
 .B SIZELIMIT <integer>
 Specifies a size limit to use when performing searches.  The
@@ -110,46 +183,33 @@
 Specifies a time limit to use when performing searches.  The
 number should be a non-negative integer.  \fITIMELIMIT\fP of zero (0)
 specifies unlimited search time to be used.
+.B VERSION {2|3}
+Specifies what version of the LDAP protocol should be used.
 .TP
-.B DEREF <when>
-Specifies how alias dereferencing is done when performing a search. The
-.B <when>
-can be specified as one of the following keywords:
-.RS
-.TP
-.B never
-Aliases are never dereferenced. This is the default.
-.TP
-.B searching
-Aliases are dereferenced in subordinates of the base object, but
-not in locating the base object of the search.
-.TP
-.B finding
-Aliases are only dereferenced when locating the base object of the search.
-.TP
-.B always
-Aliases are dereferenced both in searching and in locating the base object
-of the search.
-.RE
+.B TIMEOUT <integer>
+Specifies a timeout (in seconds) after which calls to synchronous LDAP
+APIs will abort if no response is received.  Also used for any
+.BR ldap_result (3)
+calls where a NULL timeout parameter is supplied.
 .SH SASL OPTIONS
 If OpenLDAP is built with Simple Authentication and Security Layer support,
 there are more options you can specify.
 .TP
 .B SASL_MECH <mechanism>
 Specifies the SASL mechanism to use.
-This is a user\-only option.
+.B This is a user\-only option.
 .TP
 .B SASL_REALM <realm>
 Specifies the SASL realm.
-This is a user\-only option.
+.B This is a user\-only option.
 .TP
 .B SASL_AUTHCID <authcid>
 Specifies the authentication identity.
-This is a user\-only option.
+.B This is a user\-only option.
 .TP
 .B SASL_AUTHZID <authcid>
 Specifies the proxy authorization identity.
-This is a user\-only option.
+.B This is a user\-only option.
 .TP
 .B SASL_SECPROPS <properties>
 Specifies Cyrus SASL security properties. The 
@@ -206,7 +266,7 @@
 are more options you can specify.  These options are used when an
 .B ldaps:// URI
 is selected (by default or otherwise) or when the application
-negotiates TLS by issuing the LDAP Start TLS operation.
+negotiates TLS by issuing the LDAP StartTLS operation.
 .TP
 .B TLS_CACERT <filename>
 Specifies the file that contains certificates for all of the Certificate
@@ -218,18 +278,19 @@
 .B TLS_CACERT
 is always used before
 .B TLS_CACERTDIR.
+This parameter is ignored with GNUtls.
 .TP
 .B TLS_CERT <filename>
 Specifies the file that contains the client certificate.
-This is a user\-only option.
+.B This is a user\-only option.
 .TP
 .B TLS_KEY <filename>
 Specifies the file that contains the private key that matches the certificate
 stored in the
 .B TLS_CERT
 file. Currently, the private key must not be protected with a password, so
-it is of critical importance that the key file is protected carefully. This
-is a user\-only option.
+it is of critical importance that the key file is protected carefully.
+.B This is a user\-only option.
 .TP
 .B TLS_CIPHER_SUITE <cipher-suite-spec>
 Specifies acceptable cipher suite and preference order.
@@ -240,6 +301,7 @@
 Specifies the file to obtain random bits from when /dev/[u]random is
 not available. Generally set to the name of the EGD/PRNGD socket.
 The environment variable RANDFILE can also be used to specify the filename.
+This parameter is ignored with GNUtls.
 .TP
 .B TLS_REQCERT <level>
 Specifies what checks to perform on server certificates in a TLS session,
@@ -272,7 +334,7 @@
 used to verify if the server certificates have not been revoked. This
 requires
 .B TLS_CACERTDIR
-parameter to be set.
+parameter to be set. This parameter is ignored with GNUtls.
 .B <level>
 can be specified as one of the following keywords:
 .RS
@@ -286,6 +348,11 @@
 .B all
 Check the CRL for a whole certificate chain
 .RE
+.TP
+.B TLS_CRLFILE <filename>
+Specifies the file containing a Certificate Revocation List to be used
+to verify if the server certificates have not been revoked. This
+parameter is only supported with GNUtls.
 .SH "ENVIRONMENT VARIABLES"
 .TP
 LDAPNOINIT
@@ -311,12 +378,11 @@
 local ldap configuration file
 .SH "SEE ALSO"
 .BR ldap (3),
+.BR ldap_set_option (3),
+.BR ldap_result (3),
 .BR openssl (1),
 .BR sasl (3)
 .SH AUTHOR
 Kurt Zeilenga, The OpenLDAP Project
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man5/ldif.5
===================================================================
--- openldap/trunk/doc/man/man5/ldif.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/ldif.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH LDIF 5 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/ldif.5,v 1.18.2.5 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/ldif.5,v 1.22.2.2 2007/08/31 23:13:53 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -7,8 +7,13 @@
 .SH DESCRIPTION
 The LDAP Data Interchange Format (LDIF) is used to represent LDAP
 entries and change records in text form. LDAP tools, such as
-.BR ldapadd (1) and .BR ldapsearch (1), read and write LDIF entry
-records.  ldapmodify(1) reads LDIF change records.
+.BR ldapadd (1)
+and
+.BR ldapsearch (1),
+read and write LDIF entry
+records.
+.BR ldapmodify (1)
+reads LDIF change records.
 .LP
 This manual page provides a basic description of LDIF.  A
 formal specification of LDIF is published in RFC 2849.
@@ -228,16 +233,46 @@
 	changetype: delete
 .fi
 
+.SH INCLUDE STATEMENT
+The LDIF parser has been extended to support an
+.B include
+statement for referencing other LDIF files.  The
+.B include
+statement must be separated from other records by a blank line.
+The referenced file is specified using a file: URI and all of its
+contents are incorporated as if they were part of the original
+LDIF file. As above, other URI schemes may be supported. For example:
+.LP
+.nf
+	dn: dc=example,dc=com
+	objectclass: domain
+	dc: example
+
+	include: file:///tmp/example.com.ldif
+
+	dn: dc=example,dc=org
+	objectclass: domain
+	dc: example
+.fi
+This feature is not part of the LDIF specification in RFC 2849 but
+is expected to appear in a future revision of this spec. It is supported
+by the
+.BR ldapadd (1),
+.BR ldapmodify (1),
+and
+.BR slapadd (8)
+commands.
+
 .SH SEE ALSO
 .BR ldap (3),
 .BR ldapsearch (1),
 .BR ldapadd (1),
 .BR ldapmodify (1),
+.BR slapadd (8),
+.BR slapcat (8),
+.BR slapd-ldif (5),
 .BR slapd.replog (5).
 .LP
 "LDAP Data Interchange Format," Good, G., RFC 2849.
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.
+.so ../Project

Modified: openldap/trunk/doc/man/man5/slapd-bdb.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-bdb.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-bdb.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH SLAPD-BDB 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-bdb.5,v 1.20.2.12 2007/09/26 16:18:24 quanah Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-bdb.5,v 1.31.2.3 2007/09/26 15:54:28 quanah Exp $
 .SH NAME
-\fBslapd-bdb\fP, \fBslapd-hdb\fP \- Berkeley DB backends to \fBslapd\fP
+slapd-bdb, slapd-hdb \- Berkeley DB backends to slapd
 .SH SYNOPSIS
 .B ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -108,6 +108,11 @@
 In this case, the modified data is discarded and a subsequent search
 will return a different result.
 .TP
+.BI dncachesize \ <integer>
+Specify the maximum number of DNs in the in-memory DN cache. The
+default is twice the \fBcachesize\fP. Ideally this cache should be
+large enough to contain the DNs of every entry in the database.
+.TP
 .BI idlcachesize \ <integer>
 Specify the size of the in-memory index cache, in index slots. The
 default is zero. A larger value will speed up frequent searches of
@@ -224,3 +229,8 @@
 .BR slapcat (8),
 .BR slapindex (8),
 Berkeley DB documentation.
+.SH ACKNOWLEDGEMENTS
+.so ../Project
+Originally begun by Kurt Zeilenga. Caching mechanisms originally designed
+by Jong-Hyuk Choi. Completion and subsequent work, as well as
+back-hdb, by Howard Chu.

Copied: openldap/trunk/doc/man/man5/slapd-config.5 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man5/slapd-config.5)
===================================================================
--- openldap/trunk/doc/man/man5/slapd-config.5	                        (rev 0)
+++ openldap/trunk/doc/man/man5/slapd-config.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,1908 @@
+.TH SLAPD-CONFIG 5 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-config.5,v 1.13.2.6 2007/12/03 17:47:41 quanah Exp $
+.SH NAME
+slapd-config \- configuration backend to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.d
+.SH DESCRIPTION
+The
+.B config
+backend manages all of the configuration information for the
+.BR slapd (8)
+daemon.  This configuration information is also used by the SLAPD tools
+.BR slapacl (8),
+.BR slapadd (8),
+.BR slapauth (8),
+.BR slapcat (8),
+.BR slapdn (8),
+.BR slapindex (8),
+and
+.BR slaptest (8).
+.LP
+The
+.B config
+backend is backward compatible with the older
+.BR slapd.conf (5)
+file but provides the ability to change the configuration dynamically
+at runtime. If slapd is run with only a
+.B slapd.conf
+file dynamic changes will be allowed but they will not persist across
+a server restart. Dynamic changes are only saved when slapd is running
+from a
+.B slapd.d
+configuration directory.
+.LP
+
+Unlike other backends, there can only be one instance of the
+.B config
+backend, and most of its structure is predefined. The root of the
+database is hardcoded to
+.B "cn=config"
+and this root entry contains
+global settings for slapd. Multiple child entries underneath the
+root entry are used to carry various other settings:
+.RS
+.TP
+.B cn=Module
+dynamically loaded modules
+.TP
+.B cn=Schema
+schema definitions
+.TP
+.B olcBackend=xxx
+backend-specific settings
+.TP
+.B olcDatabase=xxx
+database-specific settings
+.RE
+
+The
+.B cn=Module
+entries will only appear in configurations where slapd
+was built with support for dynamically loaded modules. There can be
+multiple entries, one for each configured module path. Within each
+entry there will be values recorded for each module loaded on a
+given path. These entries have no children.
+
+The
+.B cn=Schema
+entry contains all of the hardcoded schema elements.
+The children of this entry contain all user-defined schema elements.
+In schema that were loaded from include files, the child entry will
+be named after the include file from which the schema was loaded.
+Typically the first child in this subtree will be
+.BR cn=core,cn=schema,cn=config .
+
+.B olcBackend
+entries are for storing settings specific to a single
+backend type (and thus global to all database instances of that type).
+At present there are no backends that implement settings of this
+nature, so usually there will not be any olcBackend entries.
+
+.B olcDatabase
+entries store settings specific to a single database
+instance. These entries may have
+.B olcOverlay
+child entries corresponding
+to any overlays configured on the database. The olcDatabase and
+olcOverlay entries may also have miscellaneous child entries for
+other settings as needed. There are two special database entries
+that are predefined - one is an entry for the config database itself,
+and the other is for the "frontend" database. Settings in the
+frontend database are inherited by the other databases, unless
+they are explicitly overridden in a specific database.
+.LP
+The specific configuration options available are discussed below in the
+Global Configuration Options, General Backend Options, and General Database
+Options. Options are set by defining LDAP attributes with specific values.
+In general the names of the LDAP attributes are the same as the corresponding
+.B slapd.conf
+keyword, with an "olc" prefix added on.
+
+The parser for many of these attributes is the same as used for parsing
+the slapd.conf keywords. As such, slapd.conf keywords that allow multiple
+items to be specified on one line, separated by whitespace, will allow
+multiple items to be specified in one attribute value. However, when
+reading the attribute via LDAP, the items will be returned as individual
+attribute values.
+
+Backend-specific options are discussed in the
+.B slapd-<backend>(5)
+manual pages.  Refer to the "OpenLDAP Administrator's Guide" for more
+details on configuring slapd.
+.SH GLOBAL CONFIGURATION OPTIONS
+Options described in this section apply to the server as a whole.
+Arguments that should be replaced by 
+actual text are shown in brackets <>.
+
+These options may only be specified in the
+.B cn=config
+entry. This entry must have an objectClass of
+.BR olcGlobal .
+
+.TP
+.B olcAllows: <features>
+Specify a set of features to allow (default none).
+.B bind_v2
+allows acceptance of LDAPv2 bind requests.  Note that
+.BR slapd (8)
+does not truly implement LDAPv2 (RFC 1777), now Historic (RFC 3494).
+.B bind_anon_cred
+allows anonymous bind when credentials are not empty (e.g.
+when DN is empty).
+.B bind_anon_dn
+allows unauthenticated (anonymous) bind when DN is not empty.
+.B update_anon
+allows unauthenticated (anonymous) update operations to be processed
+(subject to access controls and other administrative limits).
+.B proxy_authz_anon
+allows unauthenticated (anonymous) proxy authorization control to be processed
+(subject to access controls, authorization and other administrative limits).
+.TP
+.B olcArgsFile: <filename>
+The ( absolute ) name of a file that will hold the 
+.B slapd
+server's command line options
+if started without the debugging command line option.
+.TP
+.B olcAttributeOptions: <option-name>...
+Define tagging attribute options or option tag/range prefixes.
+Options must not end with `-', prefixes must end with `-'.
+The `lang-' prefix is predefined.
+If you use the
+.B olcAttributeOptions
+directive, `lang-' will no longer be defined and you must specify it
+explicitly if you want it defined.
+
+An attribute description with a tagging option is a subtype of that
+attribute description without the option.
+Except for that, options defined this way have no special semantics.
+Prefixes defined this way work like the `lang-' options:
+They define a prefix for tagging options starting with the prefix.
+That is, if you define the prefix `x-foo-', you can use the option
+`x-foo-bar'.
+Furthermore, in a search or compare, a prefix or range name (with
+a trailing `-') matches all options starting with that name, as well
+as the option with the range name sans the trailing `-'.
+That is, `x-foo-bar-' matches `x-foo-bar' and `x-foo-bar-baz'.
+
+RFC 4520 reserves options beginning with `x-' for private experiments.
+Other options should be registered with IANA, see RFC 4520 section 3.5.
+OpenLDAP also has the `binary' option built in, but this is a transfer
+option, not a tagging option.
+.TP
+.B olcAuthzPolicy: <policy>
+Used to specify which rules to use for Proxy Authorization.  Proxy
+authorization allows a client to authenticate to the server using one
+user's credentials, but specify a different identity to use for authorization
+and access control purposes. It essentially allows user A to login as user
+B, using user A's password.
+The
+.B none
+flag disables proxy authorization. This is the default setting.
+The
+.B from
+flag will use rules in the
+.I authzFrom
+attribute of the authorization DN.
+The
+.B to
+flag will use rules in the
+.I authzTo
+attribute of the authentication DN.
+The
+.B any
+flag, an alias for the deprecated value of
+.BR both ,
+will allow any of the above, whatever succeeds first (checked in
+.BR to ,
+.B from
+sequence.
+The
+.B all
+flag requires both authorizations to succeed.
+.LP
+.RS
+The rules are mechanisms to specify which identities are allowed 
+to perform proxy authorization.
+The
+.I authzFrom
+attribute in an entry specifies which other users
+are allowed to proxy login to this entry. The
+.I authzTo
+attribute in
+an entry specifies which other users this user can authorize as.  Use of
+.I authzTo
+rules can be easily
+abused if users are allowed to write arbitrary values to this attribute.
+In general the
+.I authzTo
+attribute must be protected with ACLs such that
+only privileged users can modify it.
+The value of
+.I authzFrom
+and
+.I authzTo
+describes an 
+.B identity 
+or a set of identities; it can take five forms:
+.RS
+.TP
+.B ldap:///<base>??[<scope>]?<filter>
+.RE
+.RS
+.B dn[.<dnstyle>]:<pattern>
+.RE
+.RS
+.B u[<mech>[<realm>]]:<pattern>
+.RE
+.RS
+.B group[/objectClass[/attributeType]]:<pattern>
+.RE
+.RS
+.B <pattern>
+.RE
+.RS
+
+.B <dnstyle>:={exact|onelevel|children|subtree|regex}
+
+.RE
+The first form is a valid LDAP
+.B URI
+where the 
+.IR <host>:<port> ,
+the
+.I <attrs>
+and the
+.I <extensions>
+portions must be absent, so that the search occurs locally on either
+.I authzFrom
+or 
+.IR authzTo .
+The second form is a 
+.BR DN ,
+with the optional style modifiers
+.IR exact ,
+.IR onelevel ,
+.IR children ,
+and
+.I subtree
+for exact, onelevel, children and subtree matches, which cause 
+.I <pattern>
+to be normalized according to the DN normalization rules, or the special
+.I regex
+style, which causes the
+.I <pattern>
+to be treated as a POSIX (''extended'') regular expression, as
+discussed in
+.BR regex (7)
+and/or
+.BR re_format (7).
+A pattern of
+.I *
+means any non-anonymous DN.
+The third form is a SASL
+.BR id ,
+with the optional fields
+.I <mech>
+and
+.I <realm>
+that allow to specify a SASL
+.BR mechanism ,
+and eventually a SASL
+.BR realm ,
+for those mechanisms that support one.
+The need to allow the specification of a mechanism is still debated, 
+and users are strongly discouraged to rely on this possibility.
+The fourth form is a group specification, consisting of the keyword
+.BR group ,
+optionally followed by the specification of the group
+.B objectClass
+and member
+.BR attributeType .
+The group with DN
+.B <pattern>
+is searched with base scope, and in case of match, the values of the
+member
+.B attributeType
+are searched for the asserted DN.
+For backwards compatibility, if no identity type is provided, i.e. only
+.B <pattern>
+is present, an
+.I exact DN
+is assumed; as a consequence, 
+.B <pattern>
+is subjected to DN normalization.
+Since the interpretation of
+.I authzFrom
+and
+.I authzTo
+can impact security, users are strongly encouraged 
+to explicitly set the type of identity specification that is being used.
+A subset of these rules can be used as third arg in the 
+.B olcAuthzRegexp
+statement (see below); significantly, the 
+.I URI
+and the
+.I dn.exact:<dn> 
+forms.
+.RE
+.TP
+.B olcAuthzRegexp: <match> <replace>
+Used by the authentication framework to convert simple user names,
+such as provided by SASL subsystem, to an LDAP DN used for
+authorization purposes.  Note that the resultant DN need not refer
+to an existing entry to be considered valid.  When an authorization
+request is received from the SASL subsystem, the SASL 
+.BR USERNAME ,
+.BR REALM , 
+and
+.B MECHANISM
+are taken, when available, and combined into a name of the form
+.RS
+.RS
+.TP
+.B UID=<username>[[,CN=<realm>],CN=<mechanism>],CN=auth
+
+.RE
+This name is then compared against the
+.B match
+POSIX (''extended'') regular expression, and if the match is successful,
+the name is replaced with the
+.B replace
+string.  If there are wildcard strings in the 
+.B match
+regular expression that are enclosed in parenthesis, e.g. 
+.RS
+.TP
+.B UID=([^,]*),CN=.*
+
+.RE
+then the portion of the name that matched the wildcard will be stored
+in the numbered placeholder variable $1. If there are other wildcard strings
+in parenthesis, the matching strings will be in $2, $3, etc. up to $9. The 
+placeholders can then be used in the 
+.B replace
+string, e.g. 
+.RS
+.TP
+.B UID=$1,OU=Accounts,DC=example,DC=com 
+
+.RE
+The replaced name can be either a DN, i.e. a string prefixed by "dn:",
+or an LDAP URI.
+If the latter, the server will use the URI to search its own database(s)
+and, if the search returns exactly one entry, the name is
+replaced by the DN of that entry.   The LDAP URI must have no
+hostport, attrs, or extensions components, but the filter is mandatory,
+e.g.
+.RS
+.TP
+.B ldap:///OU=Accounts,DC=example,DC=com??one?(UID=$1)
+
+.RE
+The protocol portion of the URI must be strictly
+.BR ldap .
+Note that this search is subject to access controls.  Specifically,
+the authentication identity must have "auth" access in the subject.
+
+Multiple 
+.B olcAuthzRegexp 
+values can be specified to allow for multiple matching 
+and replacement patterns. The matching patterns are checked in the order they 
+appear in the attribute, stopping at the first successful match.
+
+.\".B Caution:
+.\"Because the plus sign + is a character recognized by the regular expression engine,
+.\"and it will appear in names that include a REALM, be careful to escape the
+.\"plus sign with a backslash \\+ to remove the character's special meaning.
+.RE
+.TP
+.B olcConcurrency: <integer>
+Specify a desired level of concurrency.  Provided to the underlying
+thread system as a hint.  The default is not to provide any hint. This setting
+is only meaningful on some platforms where there is not a one to one
+correspondence between user threads and kernel threads.
+.TP
+.B olcConnMaxPending: <integer>
+Specify the maximum number of pending requests for an anonymous session.
+If requests are submitted faster than the server can process them, they
+will be queued up to this limit. If the limit is exceeded, the session
+is closed. The default is 100.
+.TP
+.B olcConnMaxPendingAuth: <integer>
+Specify the maximum number of pending requests for an authenticated session.
+The default is 1000.
+.TP
+.B olcDisallows: <features>
+Specify a set of features to disallow (default none).
+.B bind_anon
+disables acceptance of anonymous bind requests.  Note that this setting
+does not prohibit anonymous directory access (See "require authc").
+.B bind_simple
+disables simple (bind) authentication.
+.B tls_2_anon
+disables forcing session to anonymous status (see also
+.BR tls_authc )
+upon StartTLS operation receipt.
+.B tls_authc
+disallows the StartTLS operation if authenticated (see also
+.BR tls_2_anon ).
+.TP
+.B olcGentleHUP: { TRUE | FALSE }
+A SIGHUP signal will only cause a 'gentle' shutdown-attempt:
+.B Slapd
+will stop listening for new connections, but will not close the
+connections to the current clients.  Future write operations return
+unwilling-to-perform, though.  Slapd terminates when all clients
+have closed their connections (if they ever do), or \- as before \-
+if it receives a SIGTERM signal.  This can be useful if you wish to
+terminate the server and start a new
+.B slapd
+server
+.B with another database,
+without disrupting the currently active clients.
+The default is FALSE.  You may wish to use
+.B olcIdleTimeout
+along with this option.
+.TP
+.B olcIdleTimeout: <integer>
+Specify the number of seconds to wait before forcibly closing
+an idle client connection.  A setting of 0 disables this
+feature.  The default is 0.
+.TP
+.B olcIndexIntLen: <integer>
+Specify the key length for ordered integer indices. The most significant
+bytes of the binary integer will be used for index keys. The default
+value is 4, which provides exact indexing for 31 bit values.
+A floating point representation is used to index too large values.
+.TP
+.B olcIndexSubstrIfMaxlen: <integer>
+Specify the maximum length for subinitial and subfinal indices. Only
+this many characters of an attribute value will be processed by the
+indexing functions; any excess characters are ignored. The default is 4.
+.TP
+.B olcIndexSubstrIfMinlen: <integer>
+Specify the minimum length for subinitial and subfinal indices. An
+attribute value must have at least this many characters in order to be
+processed by the indexing functions. The default is 2.
+.TP
+.B olcIndexSubstrAnyLen: <integer>
+Specify the length used for subany indices. An attribute value must have
+at least this many characters in order to be processed. Attribute values
+longer than this length will be processed in segments of this length. The
+default is 4. The subany index will also be used in subinitial and
+subfinal index lookups when the filter string is longer than the
+.I olcIndexSubstrIfMaxlen
+value.
+.TP
+.B olcIndexSubstrAnyStep: <integer>
+Specify the steps used in subany index lookups. This value sets the offset
+for the segments of a filter string that are processed for a subany index
+lookup. The default is 2. For example, with the default values, a search
+using this filter "cn=*abcdefgh*" would generate index lookups for
+"abcd", "cdef", and "efgh".
+
+.LP
+Note: Indexing support depends on the particular backend in use. Also,
+changing these settings will generally require deleting any indices that
+depend on these parameters and recreating them with
+.BR slapindex (8).
+
+.TP
+.B olcLocalSSF: <SSF>
+Specifies the Security Strength Factor (SSF) to be given local LDAP sessions,
+such as those to the ldapi:// listener.  For a description of SSF values,
+see 
+.BR olcSaslSecProps 's
+.B minssf
+option description.  The default is 71.
+.TP
+.B olcLogFile: <filename>
+Specify a file for recording debug log messages. By default these messages
+only go to stderr and are not recorded anywhere else. Specifying a logfile
+copies messages to both stderr and the logfile.
+.TP
+.B olcLogLevel: <integer> [...]
+Specify the level at which debugging statements and operation 
+statistics should be syslogged (currently logged to the
+.BR syslogd (8) 
+LOG_LOCAL4 facility).
+They must be considered subsystems rather than increasingly verbose 
+log levels.
+Some messages with higher priority are logged regardless 
+of the configured loglevel as soon as any logging is configured.
+Log levels are additive, and available levels are:
+.RS
+.RS
+.PD 0
+.TP
+.B 1
+.B (0x1 trace)
+trace function calls
+.TP
+.B 2
+.B (0x2 packets)
+debug packet handling
+.TP
+.B 4
+.B (0x4 args)
+heavy trace debugging (function args)
+.TP
+.B 8
+.B (0x8 conns)
+connection management
+.TP
+.B 16
+.B (0x10 BER)
+print out packets sent and received
+.TP
+.B 32
+.B (0x20 filter)
+search filter processing
+.TP
+.B 64
+.B (0x40 config)
+configuration file processing
+.TP
+.B 128
+.B (0x80 ACL)
+access control list processing
+.TP
+.B 256
+.B (0x100 stats)
+stats log connections/operations/results
+.TP
+.B 512
+.B (0x200 stats2)
+stats log entries sent
+.TP
+.B 1024
+.B (0x400 shell)
+print communication with shell backends
+.TP
+.B 2048
+.B (0x800 parse)
+entry parsing
+\".TP
+\".B 4096
+\".B (0x1000 cache)
+\"caching (unused)
+\".TP
+\".B 8192
+\".B (0x2000 index)
+\"data indexing (unused)
+.TP
+.B 16384
+.B (0x4000 sync)
+LDAPSync replication
+.TP
+.B 32768
+.B (0x8000 none)
+only messages that get logged whatever log level is set
+.PD
+.RE
+The desired log level can be input as a single integer that combines 
+the (ORed) desired levels, both in decimal or in hexadecimal notation,
+as a list of integers (that are ORed internally),
+or as a list of the names that are shown between brackets, such that
+.LP
+.nf
+    olcLogLevel: 129
+    olcLogLevel: 0x81
+    olcLogLevel: 128 1
+    olcLogLevel: 0x80 0x1
+    olcLogLevel: acl trace
+.fi
+.LP
+are equivalent.
+The keyword 
+.B any
+can be used as a shortcut to enable logging at all levels (equivalent to -1).
+The keyword
+.BR none ,
+or the equivalent integer representation, causes those messages
+that are logged regardless of the configured olcLogLevel to be logged.
+In fact, if no olcLogLevel (or a 0 level) is defined, no logging occurs, 
+so at least the 
+.B none
+level is required to have high priority messages logged.
+.RE
+.TP
+.B olcPasswordCryptSaltFormat: <format>
+Specify the format of the salt passed to
+.BR crypt (3)
+when generating {CRYPT} passwords (see
+.BR olcPasswordHash )
+during processing of LDAP Password Modify Extended Operations (RFC 3062).
+
+This string needs to be in
+.BR sprintf (3)
+format and may include one (and only one) %s conversion.
+This conversion will be substituted with a string of random
+characters from [A\-Za\-z0\-9./].  For example, "%.2s"
+provides a two character salt and "$1$%.8s" tells some
+versions of crypt(3) to use an MD5 algorithm and provides
+8 random characters of salt.  The default is "%s", which
+provides 31 characters of salt.
+.TP
+.B olcPidFile: <filename>
+The ( absolute ) name of a file that will hold the 
+.B slapd
+server's process ID ( see
+.BR getpid (2)
+) if started without the debugging command line option.
+.TP
+.B olcPluginLogFile: <filename>
+The ( absolute ) name of a file that will contain log
+messages from
+.B SLAPI
+plugins. See
+.BR slapd.plugin (5)
+for details.
+.TP
+.B olcReferral: <url>
+Specify the referral to pass back when
+.BR slapd (8)
+cannot find a local database to handle a request.
+If multiple values are specified, each url is provided.
+.TP
+.B olcReverseLookup: TRUE | FALSE
+Enable/disable client name unverified reverse lookup (default is 
+.BR FALSE 
+if compiled with --enable-rlookups).
+.TP
+.B olcRootDSE: <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
+attributes normally produced by slapd.
+
+The root DSE is an entry with information about the server and its
+capabilities, in operational attributes.
+It has the empty DN, and can be read with e.g.:
+.ti +4
+ldapsearch -x -b "" -s base "+"
+.br
+See RFC 4512 section 5.1 for details.
+.TP
+.B olcSaslHost: <fqdn>
+Used to specify the fully qualified domain name used for SASL processing.
+.TP
+.B olcSaslRealm: <realm>
+Specify SASL realm.  Default is empty.
+.TP
+.B olcSaslSecProps: <properties>
+Used to specify Cyrus SASL security properties.
+The
+.B none
+flag (without any other properties) causes the flag properties
+default, "noanonymous,noplain", to be cleared.
+The
+.B noplain
+flag disables mechanisms susceptible to simple passive attacks.
+The
+.B noactive
+flag disables mechanisms susceptible to active attacks.
+The
+.B nodict
+flag disables mechanisms susceptible to passive dictionary attacks.
+The
+.B noanonymous
+flag disables mechanisms which support anonymous login.
+The
+.B forwardsec
+flag require forward secrecy between sessions.
+The
+.B passcred
+require mechanisms which pass client credentials (and allow
+mechanisms which can pass credentials to do so).
+The
+.B minssf=<factor> 
+property specifies the minimum acceptable
+.I security strength factor
+as an integer approximate to effective key length used for
+encryption.  0 (zero) implies no protection, 1 implies integrity
+protection only, 56 allows DES or other weak ciphers, 112
+allows triple DES and other strong ciphers, 128 allows RC4,
+Blowfish and other modern strong ciphers.  The default is 0.
+The
+.B maxssf=<factor> 
+property specifies the maximum acceptable
+.I security strength factor
+as an integer (see minssf description).  The default is INT_MAX.
+The
+.B maxbufsize=<size> 
+property specifies the maximum security layer receive buffer
+size allowed.  0 disables security layers.  The default is 65536.
+.TP
+.B olcServerID: <integer> [<URL>]
+Specify an integer ID from 0 to 4095 for this server. These IDs are
+required when using multimaster replication and each master must have a
+unique ID. If the URL is provided, this directive may be specified
+multiple times, providing a complete list of participating servers
+and their IDs. The fully qualified hostname of each server should be
+used in the supplied URLs. The IDs are used in the "replica id" field
+of all CSNs generated by the specified server. The default value is zero.
+Example:
+.LP
+.nf
+	olcServerID: 1 ldap://ldap1.example.com
+	olcServerID: 2 ldap://ldap2.example.com
+.fi
+.TP
+.B olcSockbufMaxIncoming: <integer>
+Specify the maximum incoming LDAP PDU size for anonymous sessions.
+The default is 262143.
+.TP
+.B olcSockbufMaxIncomingAuth: <integer>
+Specify the maximum incoming LDAP PDU size for authenticated sessions.
+The default is 4194303.
+.TP
+.B olcThreads: <integer>
+Specify the maximum size of the primary thread pool.
+The default is 16; the minimum value is 2.
+.TP
+.B olcToolThreads: <integer>
+Specify the maximum number of threads to use in tool mode.
+This should not be greater than the number of CPUs in the system.
+The default is 1.
+.\"ucdata-path is obsolete / ignored...
+.\".TP
+.\".B ucdata-path <path>
+.\"Specify the path to the directory containing the Unicode character
+.\"tables. The default path is DATADIR/ucdata.
+.SH TLS OPTIONS
+If
+.B slapd
+is built with support for Transport Layer Security, there are more options
+you can specify.
+.TP
+.B olcTLSCipherSuite: <cipher-suite-spec>
+Permits configuring what ciphers will be accepted and the preference order.
+<cipher-suite-spec> should be a cipher specification for OpenSSL.  Example:
+
+olcTLSCipherSuite: HIGH:MEDIUM:+SSLv2
+
+To check what ciphers a given spec selects in OpenSSL, use:
+
+.nf
+	openssl ciphers -v <cipher-suite-spec>
+.fi
+
+To obtain the list of ciphers in GNUtls use:
+
+.nf
+	gnutls-cli -l
+.fi
+.TP
+.B olcTLSCACertificateFile: <filename>
+Specifies the file that contains certificates for all of the Certificate
+Authorities that
+.B slapd
+will recognize.
+.TP
+.B olcTLSCACertificatePath: <path>
+Specifies the path of a directory that contains Certificate Authority
+certificates in separate individual files. Usually only one of this
+or the olcTLSCACertificateFile is defined. If both are specified, both
+locations will be used. This directive is not supported
+when using GNUtls.
+.TP
+.B olcTLSCertificateFile: <filename>
+Specifies the file that contains the
+.B slapd
+server certificate.
+.TP
+.B olcTLSCertificateKeyFile: <filename>
+Specifies the file that contains the
+.B slapd
+server private key that matches the certificate stored in the
+.B olcTLSCertificateFile
+file. If the private key is protected with a password, the password must
+be manually typed in when slapd starts.  Usually the private key is not
+protected with a password, to allow slapd to start without manual
+intervention, so
+it is of critical importance that the file is protected carefully. 
+.TP
+.B olcTLSDHParamFile: <filename>
+This directive specifies the file that contains parameters for Diffie-Hellman
+ephemeral key exchange.  This is required in order to use a DSA certificate on
+the server. If multiple sets of parameters are present in the file, all of
+them will be processed.  Note that setting this option may also enable
+Anonymous Diffie-Hellman key exchanges in certain non-default cipher suites.
+You should append "!ADH" to your cipher suites if you have changed them
+from the default, otherwise no certificate exchanges or verification will
+be done. When using GNUtls these parameters are always generated randomly
+so this directive is ignored.
+.TP
+.B olcTLSRandFile: <filename>
+Specifies the file to obtain random bits from when /dev/[u]random
+is not available.  Generally set to the name of the EGD/PRNGD socket.
+The environment variable RANDFILE can also be used to specify the filename.
+This directive is ignored with GNUtls.
+.TP
+.B olcTLSVerifyClient: <level>
+Specifies what checks to perform on client certificates in an
+incoming TLS session, if any.
+The
+.B <level>
+can be specified as one of the following keywords:
+.RS
+.TP
+.B never
+This is the default.
+.B slapd
+will not ask the client for a certificate.
+.TP
+.B allow
+The client certificate is requested.  If no certificate is provided,
+the session proceeds normally.  If a bad certificate is provided,
+it will be ignored and the session proceeds normally.
+.TP
+.B try
+The client certificate is requested.  If no certificate is provided,
+the session proceeds normally.  If a bad certificate is provided,
+the session is immediately terminated.
+.TP
+.B demand | hard | true
+These keywords are all equivalent, for compatibility reasons.
+The client certificate is requested.  If no certificate is provided,
+or a bad certificate is provided, the session is immediately terminated.
+
+Note that a valid client certificate is required in order to use the
+SASL EXTERNAL authentication mechanism with a TLS session.  As such,
+a non-default
+.B olcTLSVerifyClient
+setting must be chosen to enable SASL EXTERNAL authentication.
+.RE
+.TP
+.B olcTLSCRLCheck: <level>
+Specifies if the Certificate Revocation List (CRL) of the CA should be 
+used to verify if the client certificates have not been revoked. This
+requires
+.B olcTLSCACertificatePath
+parameter to be set. This parameter is ignored with GNUtls.
+.B <level>
+can be specified as one of the following keywords:
+.RS
+.TP
+.B none
+No CRL checks are performed
+.TP
+.B peer
+Check the CRL of the peer certificate
+.TP
+.B all
+Check the CRL for a whole certificate chain
+.RE
+.TP
+.B olcTLSCRLFile: <filename>
+Specifies a file containing a Certificate Revocation List to be used
+for verifying that certificates have not been revoked. This parameter
+is only valid when using GNUtls.
+.SH DYNAMIC MODULE OPTIONS
+If
+.B slapd
+is compiled with --enable-modules then the module-related entries will
+be available. These entries are named
+.B cn=module{x},cn=config
+and
+must have the olcModuleList objectClass. One entry should be created
+per
+.B olcModulePath.
+Normally the config engine generates the "{x}" index in the RDN
+automatically, so it can be omitted when initially loading these entries.
+.TP
+.B olcModuleLoad: <filename>
+Specify the name of a dynamically loadable module to load. The filename
+may be an absolute path name or a simple filename. Non-absolute names
+are searched for in the directories specified by the
+.B olcModulePath
+option.
+.TP
+.B olcModulePath: <pathspec>
+Specify a list of directories to search for loadable modules. Typically
+the path is colon-separated but this depends on the operating system.
+.SH SCHEMA OPTIONS
+Schema definitions are created as entries in the
+.B cn=schema,cn=config
+subtree. These entries must have the olcSchemaConfig objectClass.
+As noted above, the actual
+.B cn=schema,cn=config
+entry is predefined and any values specified for it are ignored.
+
+.HP
+.hy 0
+.B olcAttributetypes: "(\ <oid>\
+ [NAME\ <name>]\
+ [DESC\ <description>]\
+ [OBSOLETE]\
+ [SUP\ <oid>]\
+ [EQUALITY\ <oid>]\
+ [ORDERING\ <oid>]\
+ [SUBSTR\ <oid>]\
+ [SYNTAX\ <oidlen>]\
+ [SINGLE\-VALUE]\
+ [COLLECTIVE]\
+ [NO\-USER\-MODIFICATION]\
+ [USAGE\ <attributeUsage>]\ )"
+.RS
+Specify an attribute type using the LDAPv3 syntax defined in RFC 4512.
+The slapd parser extends the RFC 4512 definition by allowing string
+forms as well as numeric OIDs to be used for the attribute OID and
+attribute syntax OID.
+(See the
+.B olcObjectIdentifier
+description.) 
+.RE
+
+.HP
+.hy 0
+.B olcDitContentRules: "(\ <oid>\
+ [NAME\ <name>]\
+ [DESC\ <description>]\
+ [OBSOLETE]\
+ [AUX\ <oids>]\
+ [MUST\ <oids>]\
+ [MAY\ <oids>]\
+ [NOT\ <oids>]\ )"
+.RS
+Specify an DIT Content Rule using the LDAPv3 syntax defined in RFC 4512.
+The slapd parser extends the RFC 4512 definition by allowing string
+forms as well as numeric OIDs to be used for the attribute OID and
+attribute syntax OID.
+(See the
+.B olcObjectIdentifier
+description.) 
+.RE
+
+.HP
+.hy 0
+.B olcObjectClasses: "(\ <oid>\
+ [NAME\ <name>]\
+ [DESC\ <description>]\
+ [OBSOLETE]\
+ [SUP\ <oids>]\
+ [{ ABSTRACT | STRUCTURAL | AUXILIARY }]\
+ [MUST\ <oids>] [MAY\ <oids>] )"
+.RS
+Specify an objectclass using the LDAPv3 syntax defined in RFC 4512.
+The slapd parser extends the RFC 4512 definition by allowing string
+forms as well as numeric OIDs to be used for the object class OID.
+(See the
+.B
+olcObjectIdentifier
+description.)  Object classes are "STRUCTURAL" by default.
+.RE
+.TP
+.B olcObjectIdentifier: <name> "{ <oid> | <name>[:<suffix>] }"
+Define a string name that equates to the given OID. The string can be used
+in place of the numeric OID in objectclass and attribute definitions. The
+name can also be used with a suffix of the form ":xx" in which case the
+value "oid.xx" will be used.
+
+.SH GENERAL BACKEND OPTIONS
+Options in these entries only apply to the configuration of a single
+type of backend. All backends may support this class of options.
+The entry must be named
+.B olcBackend=<databasetype>,cn=config
+and must have the olcBackendConfig objectClass.
+<databasetype>
+should be one of
+.BR bdb ,
+.BR config ,
+.BR dnssrv ,
+.BR hdb ,
+.BR ldap ,
+.BR ldif ,
+.BR meta ,
+.BR monitor ,
+.BR null ,
+.BR passwd ,
+.BR perl ,
+.BR relay ,
+.BR shell ,
+or
+.BR sql .
+At present, no backend implements any options of this type.
+
+.SH DATABASE OPTIONS
+Database options are set in entries named
+.B olcDatabase={x}<databasetype>,cn=config
+and must have the olcDatabaseConfig objectClass. Normally the config
+engine generates the "{x}" index in the RDN automatically, so it
+can be omitted when initially loading these entries.
+
+The special frontend database is always numbered "{-1}" and the config
+database is always numbered "{0}".
+
+.SH GLOBAL DATABASE OPTIONS
+Options in this section may be set in the special "frontend" database
+and inherited in all the other databases. These options may be altered
+by further settings in each specific database. The frontend entry must
+be named
+.B olcDatabase=frontend,cn=config
+and must have the olcFrontendConfig objectClass.
+.TP
+.B olcAccess: to <what> "[ by <who> <access> <control> ]+"
+Grant access (specified by <access>) to a set of entries and/or
+attributes (specified by <what>) by one or more requestors (specified
+by <who>).
+If no access controls are present, the default policy
+allows anyone and everyone to read anything but restricts
+updates to rootdn.  (e.g., "olcAccess: to * by * read").
+See
+.BR slapd.access (5)
+and the "OpenLDAP Administrator's Guide" for details.
+
+Access controls set in the frontend are appended to any access
+controls set on the specific databases.
+The rootdn of a database can always read and write EVERYTHING
+in that database.
+
+Extra special care must be taken with the access controls on the
+config database. Unlike other databases, the default policy for the
+config database is to only allow access to the rootdn. Regular users
+should not have read access, and write access should be granted very
+carefully to privileged administrators.
+
+.TP
+.B olcDefaultSearchBase: <dn>
+Specify a default search base to use when client submits a
+non-base search request with an empty base DN.
+Base scoped search requests with an empty base DN are not affected.
+This setting is only allowed in the frontend entry.
+.TP
+.B olcPasswordHash: <hash> [<hash>...]
+This option configures one or more hashes to be used in generation of user
+passwords stored in the userPassword attribute during processing of
+LDAP Password Modify Extended Operations (RFC 3062).
+The <hash> must be one of
+.BR {SSHA} ,
+.BR {SHA} ,
+.BR {SMD5} ,
+.BR {MD5} ,
+.BR {CRYPT} ,
+and
+.BR {CLEARTEXT} .
+The default is
+.BR {SSHA} .
+
+.B {SHA}
+and
+.B {SSHA}
+use the SHA-1 algorithm (FIPS 160-1), the latter with a seed.
+
+.B {MD5}
+and
+.B {SMD5}
+use the MD5 algorithm (RFC 1321), the latter with a seed.
+
+.B {CRYPT}
+uses the
+.BR crypt (3).
+
+.B {CLEARTEXT}
+indicates that the new password should be
+added to userPassword as clear text.
+
+Note that this option does not alter the normal user applications
+handling of userPassword during LDAP Add, Modify, or other LDAP operations.
+This setting is only allowed in the frontend entry.
+.TP
+.B olcReadOnly: TRUE | FALSE
+This option puts the database into "read-only" mode.  Any attempts to 
+modify the database will return an "unwilling to perform" error.  By
+default, olcReadOnly is FALSE. Note that when this option is set
+TRUE on the frontend, it cannot be reset without restarting the
+server, since further writes to the config database will be rejected.
+.TP
+.B olcRequires: <conditions>
+Specify a set of conditions to require (default none).
+The directive may be specified globally and/or per-database;
+databases inherit global conditions, so per-database specifications
+are additive.
+.B bind
+requires bind operation prior to directory operations.
+.B LDAPv3
+requires session to be using LDAP version 3.
+.B authc
+requires authentication prior to directory operations.
+.B SASL
+requires SASL authentication prior to directory operations.
+.B strong
+requires strong authentication prior to directory operations.
+The strong keyword allows protected "simple" authentication
+as well as SASL authentication.
+.B none
+may be used to require no conditions (useful to clear out globally
+set conditions within a particular database); it must occur first
+in the list of conditions.
+.TP
+.B olcRestrict: <oplist>
+Specify a list of operations that are restricted.
+Restrictions on a specific database override any frontend setting.
+Operations can be any of 
+.BR add ,
+.BR bind ,
+.BR compare ,
+.BR delete ,
+.BR extended[=<OID>] ,
+.BR modify ,
+.BR rename ,
+.BR search ,
+or the special pseudo-operations
+.B read
+and
+.BR write ,
+which respectively summarize read and write operations.
+The use of 
+.I restrict write
+is equivalent to 
+.I olcReadOnly: TRUE
+(see above).
+The 
+.B extended
+keyword allows to indicate the OID of the specific operation
+to be restricted.
+.TP
+.B olcSchemaDN: <dn>
+Specify the distinguished name for the subschema subentry that
+controls the entries on this server.  The default is "cn=Subschema".
+.TP
+.B olcSecurity: <factors>
+Specify a set of security strength factors (separated by white space)
+to require (see
+.BR olcSaslSecprops 's
+.B minssf
+option for a description of security strength factors).
+The directive may be specified globally and/or per-database.
+.B ssf=<n>
+specifies the overall security strength factor.
+.B transport=<n>
+specifies the transport security strength factor.
+.B tls=<n>
+specifies the TLS security strength factor.
+.B sasl=<n>
+specifies the SASL security strength factor.
+.B update_ssf=<n>
+specifies the overall security strength factor to require for
+directory updates.
+.B update_transport=<n>
+specifies the transport security strength factor to require for
+directory updates.
+.B update_tls=<n>
+specifies the TLS security strength factor to require for
+directory updates.
+.B update_sasl=<n>
+specifies the SASL security strength factor to require for
+directory updates.
+.B simple_bind=<n>
+specifies the security strength factor required for
+.I simple
+username/password authentication.
+Note that the
+.B transport
+factor is measure of security provided by the underlying transport,
+e.g. ldapi:// (and eventually IPSEC).  It is not normally used.
+.TP
+.B olcSizeLimit: {<integer>|unlimited}
+.TP
+.B olcSizeLimit: size[.{soft|hard|unchecked}]=<integer> [...]
+Specify the maximum number of entries to return from a search operation.
+The default size limit is 500.
+Use
+.B unlimited
+to specify no limits.
+The second format allows a fine grain setting of the size limits.
+Extra args can be added in the same value or as additional values.
+See
+.BR olcLimits
+for an explanation of the different flags.
+.TP
+.B olcSortVals <attr> [...]
+Specify a list of multi-valued attributes whose values will always
+be maintained in sorted order. Using this option will allow Modify,
+Compare, and filter evaluations on these attributes to be performed
+more efficiently. The resulting sort order depends on the
+attributes' syntax and matching rules and may not correspond to
+lexical order or any other recognizable order.
+This setting is only allowed in the frontend entry.
+.TP
+.B olcTimeLimit: {<integer>|unlimited}
+.TP
+.B olcTimeLimit: time[.{soft|hard}]=<integer> [...]
+Specify the maximum number of seconds (in real time)
+.B slapd
+will spend answering a search request.  The default time limit is 3600.
+Use
+.B unlimited
+to specify no limits.
+The second format allows a fine grain setting of the time limits.
+Extra args can be added in the same value or as additional values.
+See
+.BR olcLimits
+for an explanation of the different flags.
+
+.SH GENERAL DATABASE OPTIONS
+Options in this section only apply to the specific database for
+which they are defined.  They are supported by every
+type of backend. All of the Global Database Options may also be
+used here.
+.TP
+.B olcHidden: TRUE | FALSE
+Controls whether the database will be used to answer
+queries. A database that is hidden will never be
+selected to answer any queries, and any suffix configured
+on the database will be ignored in checks for conflicts
+with other databases. By default, olcHidden is FALSE.
+.TP
+.B olcLastMod: TRUE | FALSE
+Controls whether
+.B slapd
+will automatically maintain the 
+modifiersName, modifyTimestamp, creatorsName, and 
+createTimestamp attributes for entries. It also controls
+the entryCSN and entryUUID attributes, which are needed
+by the syncrepl provider. By default, olcLastMod is TRUE.
+.TP
+.B olcLimits: <who> <limit> [<limit> [...]]
+Specify time and size limits based on who initiated an operation.
+The argument
+.B who
+can be any of
+.RS
+.RS
+.TP
+anonymous | users | [dn[.<style>]=]<pattern> | group[/oc[/at]]=<pattern>
+
+.RE
+with
+.RS
+.TP
+<style> ::= exact | base | onelevel | subtree | children | regex | anonymous
+
+.RE
+The term
+.B anonymous
+matches all unauthenticated clients.
+The term
+.B users
+matches all authenticated clients;
+otherwise an
+.B exact
+dn pattern is assumed unless otherwise specified by qualifying 
+the (optional) key string
+.B dn
+with 
+.B exact
+or
+.B base
+(which are synonyms), to require an exact match; with
+.BR onelevel , 
+to require exactly one level of depth match; with
+.BR subtree ,
+to allow any level of depth match, including the exact match; with
+.BR children ,
+to allow any level of depth match, not including the exact match;
+.BR regex
+explicitly requires the (default) match based on POSIX (''extended'')
+regular expression pattern.
+Finally,
+.B anonymous
+matches unbound operations; the 
+.B pattern
+field is ignored.
+The same behavior is obtained by using the 
+.B anonymous
+form of the
+.B who
+clause.
+The term
+.BR group ,
+with the optional objectClass
+.B oc
+and attributeType
+.B at
+fields, followed by
+.BR pattern ,
+sets the limits for any DN listed in the values of the
+.B at
+attribute (default
+.BR member )
+of the 
+.B oc
+group objectClass (default
+.BR groupOfNames )
+whose DN exactly matches
+.BR pattern .
+
+The currently supported limits are 
+.B size
+and 
+.BR time .
+
+The syntax for time limits is 
+.BR time[.{soft|hard}]=<integer> ,
+where 
+.I integer
+is the number of seconds slapd will spend answering a search request.
+If no time limit is explicitly requested by the client, the 
+.BR soft
+limit is used; if the requested time limit exceeds the
+.BR hard
+.\"limit, an
+.\".I "Administrative limit exceeded"
+.\"error is returned.
+limit, the value of the limit is used instead.
+If the
+.BR hard
+limit is set to the keyword 
+.IR soft ,
+the soft limit is used in either case; if it is set to the keyword 
+.IR unlimited , 
+no hard limit is enforced.
+Explicit requests for time limits smaller or equal to the
+.BR hard 
+limit are honored.
+If no limit specifier is set, the value is assigned to the 
+.BR soft 
+limit, and the
+.BR hard
+limit is set to
+.IR soft ,
+to preserve the original behavior.
+
+The syntax for size limits is
+.BR size[.{soft|hard|unchecked}]=<integer> ,
+where
+.I integer
+is the maximum number of entries slapd will return answering a search 
+request.
+If no size limit is explicitly requested by the client, the
+.BR soft
+limit is used; if the requested size limit exceeds the
+.BR hard
+.\"limit, an 
+.\".I "Administrative limit exceeded"
+.\"error is returned.
+limit, the value of the limit is used instead.
+If the 
+.BR hard
+limit is set to the keyword 
+.IR soft , 
+the soft limit is used in either case; if it is set to the keyword
+.IR unlimited , 
+no hard limit is enforced.
+Explicit requests for size limits smaller or equal to the
+.BR hard
+limit are honored.
+The
+.BR unchecked
+specifier sets a limit on the number of candidates a search request is allowed
+to examine.
+The rationale behind it is that searches for non-properly indexed
+attributes may result in large sets of candidates, which must be 
+examined by
+.BR slapd (8)
+to determine whether they match the search filter or not.
+The
+.B unchecked
+limit provides a means to drop such operations before they are even 
+started.
+If the selected candidates exceed the 
+.BR unchecked
+limit, the search will abort with 
+.IR "Unwilling to perform" .
+If it is set to the keyword 
+.IR unlimited , 
+no limit is applied (the default).
+If it is set to
+.IR disable ,
+the search is not even performed; this can be used to disallow searches
+for a specific set of users.
+If no limit specifier is set, the value is assigned to the
+.BR soft 
+limit, and the
+.BR hard
+limit is set to
+.IR soft ,
+to preserve the original behavior.
+
+In case of no match, the global limits are used.
+The default values are the same as
+.B olcSizeLimit
+and
+.BR olcTimeLimit ;
+no limit is set on 
+.BR unchecked .
+
+If 
+.B pagedResults
+control is requested, the 
+.B hard
+size limit is used by default, because the request of a specific page size
+is considered an explicit request for a limitation on the number
+of entries to be returned.
+However, the size limit applies to the total count of entries returned within
+the search, and not to a single page.
+Additional size limits may be enforced; the syntax is
+.BR size.pr={<integer>|noEstimate|unlimited} ,
+where
+.I integer
+is the max page size if no explicit limit is set; the keyword
+.I noEstimate
+inhibits the server from returning an estimate of the total number
+of entries that might be returned
+(note: the current implementation does not return any estimate).
+The keyword
+.I unlimited
+indicates that no limit is applied to the pagedResults control page size.
+The syntax
+.B size.prtotal={<integer>|unlimited|disabled}
+allows to set a limit on the total number of entries that a pagedResults
+control allows to return.
+By default it is set to the 
+.B hard
+limit.
+When set, 
+.I integer
+is the max number of entries that the whole search with pagedResults control
+can return.
+Use 
+.I unlimited
+to allow unlimited number of entries to be returned, e.g. to allow
+the use of the pagedResults control as a means to circumvent size 
+limitations on regular searches; the keyword
+.I disabled
+disables the control, i.e. no paged results can be returned.
+Note that the total number of entries returned when the pagedResults control 
+is requested cannot exceed the 
+.B hard 
+size limit of regular searches unless extended by the
+.B prtotal
+switch.
+.RE
+.TP
+.B olcMaxDerefDepth: <depth>
+Specifies the maximum number of aliases to dereference when trying to
+resolve an entry, used to avoid infinite alias loops. The default is 15.
+.TP
+.B olcMirrorMode: TRUE | FALSE
+This option puts a replica database into "mirror" mode.  Update
+operations will be accepted from any user, not just the updatedn.  The
+database must already be configured as syncrepl consumer
+before this keyword may be set.  This mode also requires a
+.B olcServerID
+(see above) to be configured.
+By default, this setting is FALSE.
+.TP
+.B olcPlugin: <plugin_type> <lib_path> <init_function> [<arguments>]
+Configure a SLAPI plugin. See the
+.BR slapd.plugin (5)
+manpage for more details.
+.TP
+.B olcRootDN: <dn>
+Specify the distinguished name that is not subject to access control 
+or administrative limit restrictions for operations on this database.
+This DN may or may not be associated with an entry.  An empty root
+DN (the default) specifies no root access is to be granted.  It is
+recommended that the rootdn only be specified when needed (such as
+when initially populating a database).  If the rootdn is within
+a namingContext (suffix) of the database, a simple bind password
+may also be provided using the
+.B olcRootPW
+directive. Note that the rootdn is always needed when using syncrepl.
+.TP
+.B olcRootPW: <password>
+Specify a password (or hash of the password) for the rootdn.  The
+password can only be set if the rootdn is within the namingContext
+(suffix) of the database.
+This option accepts all RFC 2307 userPassword formats known to
+the server (see 
+.B olcPasswordHash
+description) as well as cleartext.
+.BR slappasswd (8) 
+may be used to generate a hash of a password.  Cleartext
+and \fB{CRYPT}\fP passwords are not recommended.  If empty
+(the default), authentication of the root DN is by other means
+(e.g. SASL).  Use of SASL is encouraged.
+.TP
+.B olcSubordinate: [TRUE | FALSE | advertise]
+Specify that the current backend database is a subordinate of another
+backend database. A subordinate  database may have only one suffix. This
+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
+associated with a single namingContext should have identical rootdns.
+Behavior of other LDAP operations is unaffected by this setting. In
+particular, it is not possible to use moddn to move an entry from
+one subordinate to another subordinate within the namingContext.
+
+If the optional \fBadvertise\fP flag is supplied, the naming context of
+this database is advertised in the root DSE. The default is to hide this
+database context, so that only the superior context is visible.
+
+If the slap tools
+.BR slapcat (8),
+.BR slapadd (8),
+or
+.BR slapindex (8)
+are used on the superior database, any glued subordinates that support
+these tools are opened as well.
+
+Databases that are glued together should usually be configured with the
+same indices (assuming they support indexing), even for attributes that
+only exist in some of these databases. In general, all of the glued
+databases should be configured as similarly as possible, since the intent
+is to provide the appearance of a single directory.
+
+Note that the subordinate functionality is implemented internally
+by the \fIglue\fP overlay and as such its behavior will interact with other
+overlays in use. By default, the glue overlay is automatically configured as
+the last overlay on the superior database. Its position on the database
+can be explicitly configured by setting an \fBoverlay glue\fP directive
+at the desired position. This explicit configuration is necessary e.g.
+when using the \fIsyncprov\fP overlay, which needs to follow \fIglue\fP
+in order to work over all of the glued databases. E.g.
+.RS
+.nf
+	dn: olcDatabase={1}bdb,cn=config
+	olcSuffix: dc=example,dc=com
+	...
+
+	dn: olcOverlay={0}glue,olcDatabase={1}bdb,cn=config
+	...
+
+	dn: olcOverlay={1}syncprov,olcDatabase={1}bdb,cn=config
+	...
+.fi
+.RE
+See the Overlays section below for more details.
+.TP
+.B olcSuffix: <dn suffix>
+Specify the DN suffix of queries that will be passed to this 
+backend database.  Multiple suffix lines can be given and at least one is 
+required for each database definition.
+If the suffix of one database is "inside" that of another, the database
+with the inner suffix must come first in the configuration file.
+.HP
+.hy 0
+.B olcSyncrepl: rid=<replica ID>
+.B provider=ldap[s]://<hostname>[:port]
+.B searchbase=<base DN>
+.B [type=refreshOnly|refreshAndPersist]
+.B [interval=dd:hh:mm:ss]
+.B [retry=[<retry interval> <# of retries>]+]
+.B [filter=<filter str>]
+.B [scope=sub|one|base|subord]
+.B [attrs=<attr list>]
+.B [exattrs=<attr list>]
+.B [attrsonly]
+.B [sizelimit=<limit>]
+.B [timelimit=<limit>]
+.B [schemachecking=on|off]
+.B [bindmethod=simple|sasl]
+.B [binddn=<dn>]
+.B [saslmech=<mech>]
+.B [authcid=<identity>]
+.B [authzid=<identity>]
+.B [credentials=<passwd>]
+.B [realm=<realm>]
+.B [secprops=<properties>]
+.B [starttls=yes|critical]
+.B [tls_cert=<file>]
+.B [tls_key=<file>]
+.B [tls_cacert=<file>]
+.B [tls_cacertdir=<path>]
+.B [tls_reqcert=never|allow|try|demand]
+.B [tls_ciphersuite=<ciphers>]
+.B [tls_crlcheck=none|peer|all]
+.B [logbase=<base DN>]
+.B [logfilter=<filter str>]
+.B [syncdata=default|accesslog|changelog]
+.RS
+Specify the current database as a replica which is kept up-to-date with the 
+master content by establishing the current
+.BR slapd (8)
+as a replication consumer site running a
+.B syncrepl
+replication engine.
+The replica content is kept synchronized to the master content using
+the LDAP Content Synchronization protocol. Refer to the
+"OpenLDAP Administrator's Guide" for detailed information on
+setting up a replicated
+.B slapd
+directory service using the 
+.B syncrepl
+replication engine.
+
+.B rid
+identifies the current
+.B syncrepl
+directive within the replication consumer site.
+It is a non-negative integer having no more than three digits.
+
+.B provider
+specifies the replication provider site containing the master content
+as an LDAP URI. If <port> is not given, the standard LDAP port number
+(389 or 636) is used.
+
+The content of the
+.B syncrepl
+replica is defined using a search
+specification as its result set. The consumer
+.B slapd
+will send search requests to the provider
+.B slapd
+according to the search specification. The search specification includes
+.B searchbase, scope, filter, attrs, attrsonly, sizelimit,
+and
+.B timelimit
+parameters as in the normal search specification. The
+.B exattrs
+option may also be used to specify attributes that should be omitted
+from incoming entries.
+The \fBscope\fP defaults to \fBsub\fP, the \fBfilter\fP defaults to
+\fB(objectclass=*)\fP, and there is no default \fBsearchbase\fP. The
+\fBattrs\fP list defaults to \fB"*,+"\fP to return all user and operational
+attributes, and \fBattrsonly\fP and \fBexattrs\fP are unset by default.
+The \fBsizelimit\fP and \fBtimelimit\fP only
+accept "unlimited" and positive integers, and both default to "unlimited".
+Note, however, that any provider-side limits for the replication identity
+will be enforced by the provider regardless of the limits requested
+by the LDAP Content Synchronization operation, much like for any other
+search operation.
+
+The LDAP Content Synchronization protocol has two operation types.
+In the
+.B refreshOnly
+operation, the next synchronization search operation
+is periodically rescheduled at an interval time (specified by 
+.B interval
+parameter; 1 day by default)
+after each synchronization operation finishes.
+In the
+.B refreshAndPersist
+operation, a synchronization search remains persistent in the provider slapd.
+Further updates to the master replica will generate
+.B searchResultEntry
+to the consumer slapd as the search responses to the persistent
+synchronization search.
+
+If an error occurs during replication, the consumer will attempt to
+reconnect according to the
+.B retry
+parameter which is a list of the <retry interval> and <# of retries> pairs.
+For example, retry="60 10 300 3" lets the consumer retry every 60 seconds
+for the first 10 times and then retry every 300 seconds for the next 3
+times before stop retrying. The `+' in <# of retries> means indefinite
+number of retries until success.
+
+The schema checking can be enforced at the LDAP Sync
+consumer site by turning on the
+.B schemachecking
+parameter. The default is off.
+
+A
+.B bindmethod
+of 
+.B simple
+requires the options 
+.B binddn
+and 
+.B credentials
+and should only be used when adequate security services
+(e.g. TLS or IPSEC) are in place.
+A
+.B bindmethod
+of
+.B sasl
+requires the option
+.B saslmech.
+Depending on the mechanism, an authentication identity and/or
+credentials can be specified using
+.B authcid
+and
+.B credentials.
+The
+.B authzid
+parameter may be used to specify an authorization identity.
+Specific security properties (as with the
+.B sasl-secprops
+keyword above) for a SASL bind can be set with the
+.B secprops
+option. A non default SASL realm can be set with the
+.B realm 
+option.
+The provider, other than allow authentication of the syncrepl identity,
+should grant that identity appropriate access privileges to the data 
+that is being replicated (\fBaccess\fP directive), and appropriate time 
+and size limits (\fBlimits\fP directive).
+
+
+The
+.B starttls
+parameter specifies use of the StartTLS extended operation
+to establish a TLS session before Binding to the provider. If the
+.B critical
+argument is supplied, the session will be aborted if the StartTLS request
+fails. Otherwise the syncrepl session continues without TLS. The
+tls_reqcert setting defaults to "demand" and the other TLS settings
+default to the same as the main slapd TLS settings.
+
+Rather than replicating whole entries, the consumer can query logs of
+data modifications. This mode of operation is referred to as \fIdelta
+syncrepl\fP. In addition to the above parameters, the
+.B logbase
+and
+.B logfilter
+parameters must be set appropriately for the log that will be used. The
+.B syncdata
+parameter must be set to either "accesslog" if the log conforms to the
+.BR slapo-accesslog (5)
+log format, or "changelog" if the log conforms
+to the obsolete \fIchangelog\fP format. If the
+.B syncdata
+parameter is omitted or set to "default" then the log parameters are
+ignored.
+.RE
+.TP
+.B olcUpdateDN: <dn>
+This option is only applicable in a slave
+database.
+It specifies the DN permitted to update (subject to access controls)
+the replica.  It is only needed in certain push-mode
+replication scenarios.  Generally, this DN
+.I should not
+be the same as the
+.B rootdn 
+used at the master.
+.TP
+.B olcUpdateRef: <url>
+Specify the referral to pass back when
+.BR slapd (8)
+is asked to modify a replicated local database.
+If multiple values are specified, each url is provided.
+
+.SH DATABASE-SPECIFIC OPTIONS
+Each database may allow specific configuration options; they are
+documented separately in the backends' manual pages. See the
+.BR slapd.backends (5)
+manual page for an overview of available backends.
+.SH OVERLAYS
+An overlay is a piece of
+code that intercepts database operations in order to extend or change
+them. Overlays are pushed onto
+a stack over the database, and so they will execute in the reverse
+of the order in which they were configured and the database itself
+will receive control last of all.
+
+Overlays must be configured as child entries of a specific database. The
+entry's RDN must be of the form
+.B olcOverlay={x}<overlaytype>
+and the entry must have the olcOverlayConfig objectClass. Normally the
+config engine generates the "{x}" index in the RDN automatically, so
+it can be omitted when initially loading these entries.
+
+See the
+.BR slapd.overlays (5)
+manual page for an overview of available overlays.
+.SH EXAMPLES
+.LP
+Here is a short example of a configuration in LDIF suitable for use with
+.BR slapadd (8)
+:
+.LP
+.RS
+.nf
+dn: cn=config
+objectClass: olcGlobal
+cn: config
+olcPidFile: LOCALSTATEDIR/run/slapd.pid
+olcAttributeOptions: x-hidden lang-
+
+dn: cn=schema,cn=config
+objectClass: olcSchemaConfig
+cn: schema
+
+include: SYSCONFDIR/schema/core.ldif
+
+dn: olcDatabase=frontend,cn=config
+objectClass: olcDatabaseConfig
+objectClass: olcFrontendConfig
+olcDatabase: frontend
+# Subtypes of "name" (e.g. "cn" and "ou") with the
+# option ";x-hidden" can be searched for/compared,
+# but are not shown.  See \fBslapd.access\fP(5).
+olcAccess: to attrs=name;x-hidden by * =cs
+# Protect passwords.  See \fBslapd.access\fP(5).
+olcAccess: to attrs=userPassword  by * auth
+# Read access to other attributes and entries.
+olcAccess: to * by * read
+
+# set a rootpw for the config database so we can bind.
+# deny access to everyone else.
+dn: olcDatabase=config,cn=config
+objectClass: olcDatabaseConfig
+olcDatabase: config
+olcRootPW: {SSHA}XKYnrjvGT3wZFQrDD5040US592LxsdLy
+olcAccess: to * by * none
+
+dn: olcDatabase=bdb,cn=config
+objectClass: olcDatabaseConfig
+objectClass: olcBdbConfig
+olcDatabase: bdb
+olcSuffix: "dc=our-domain,dc=com"
+# The database directory MUST exist prior to
+# running slapd AND should only be accessible
+# by the slapd/tools. Mode 0700 recommended.
+olcDbDirectory: LOCALSTATEDIR/openldap-data
+# Indices to maintain
+olcDbIndex:     objectClass  eq
+olcDbIndex:     cn,sn,mail   pres,eq,approx,sub
+
+# We serve small clients that do not handle referrals,
+# so handle remote lookups on their behalf.
+dn: olcDatabase=ldap,cn=config
+objectClass: olcDatabaseConfig
+objectClass: olcLdapConfig
+olcDatabase: ldap
+olcSuffix: ""
+olcDbUri: ldap://ldap.some-server.com/
+.fi
+.RE
+.LP
+Assuming the above data was saved in a file named "config.ldif" and the
+ETCDIR/slapd.d directory has been created, this command will initialize
+the configuration:
+.RS
+.nf
+slapadd -F ETCDIR/slapd.d -n 0 -l config.ldif
+.fi
+.RE
+
+.LP
+"OpenLDAP Administrator's Guide" contains a longer annotated
+example of a slapd configuration.
+
+Alternatively, an existing slapd.conf file can be converted to the new
+format using slapd or any of the slap tools:
+.RS
+.nf
+slaptest -f ETCDIR/slapd.conf -F ETCDIR/slapd.d
+.fi
+.RE
+
+.SH FILES
+.TP
+ETCDIR/slapd.conf
+default slapd configuration file
+.TP
+ETCDIR/slapd.d
+default slapd configuration directory
+.SH SEE ALSO
+.BR ldap (3),
+.BR ldif (5),
+.BR slapd.access (5),
+.BR slapd.backends (5),
+.BR slapd.conf (5),
+.BR slapd.overlays (5),
+.BR slapd.plugin (5),
+.BR slapd.replog (5),
+.BR slapd (8),
+.BR slapacl (8),
+.BR slapadd (8),
+.BR slapauth (8),
+.BR slapcat (8),
+.BR slapdn (8),
+.BR slapindex (8),
+.BR slappasswd (8),
+.BR slaptest (8).
+.LP
+"OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Modified: openldap/trunk/doc/man/man5/slapd-dnssrv.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-dnssrv.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-dnssrv.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,7 @@
 .TH SLAPD-DNSSRV 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-dnssrv.5,v 1.7.2.5 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-dnssrv.5,v 1.11.2.3 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
 slapd-dnssrv \- DNS SRV referral backend to slapd
 .SH SYNOPSIS
@@ -26,7 +26,7 @@
 .B search
 operation when the
 .B manageDSAit
-control (RFC3296) is used, otherwise for every operation a referral,
+control (RFC 3296) is used, otherwise for every operation a referral,
 whenever appropriate, or an error is returned.
 Currently, there is no means to condition the returning of the referral
 by means of ACLs; no access control is implemented, except for 

Modified: openldap/trunk/doc/man/man5/slapd-ldap.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-ldap.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-ldap.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,7 @@
 .TH SLAPD-LDAP 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-ldap.5,v 1.24.2.17 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-ldap.5,v 1.41.2.6 2007/09/26 15:36:40 quanah Exp $
 .SH NAME
 slapd-ldap \- LDAP backend to slapd
 .SH SYNOPSIS
@@ -38,11 +38,14 @@
 for details.
 
 .LP
-Note: When looping back to the same instance of \fBslapd\fP(8), 
-each connection requires a new thread; as a consequence, \fBslapd\fP(8)
+Note: When looping back to the same instance of
+.BR slapd (8), 
+each connection requires a new thread; as a consequence,
+.BR slapd (8)
 must be compiled with thread support, and the \fBthreads\fP parameter 
 may need some tuning; in those cases, one may consider using 
-\fBslapd-relay\fP(5) instead, which performs the relayed operation 
+.BR slapd-relay (5)
+instead, which performs the relayed operation 
 internally and thus reuses the same connection.
 
 .SH CONFIGURATION
@@ -64,21 +67,20 @@
 .fi
 .RE
 .LP
-for every
+for 
 .B ldap
 and
 .B meta
-database.
-This is because operational attributes related to entry creation and
-modification should not be proxied, as they could be mistakenly written
+databases.
+This was required because operational attributes related to entry creation 
+and modification should not be proxied, as they could be mistakenly written
 to the target server(s), generating an error.
-The current implementation automatically sets lastmod to off, so its use
-is redundant and should be omitted, because the lastmod directive will
-be deprecated in the future.
+The current implementation automatically sets lastmod to \fBoff\fP, 
+so its use is redundant and should be omitted.
 
 .TP
 .B uri <ldapurl>
-LDAP server to use.  Multiple URIs can be set in in a single
+LDAP server to use.  Multiple URIs can be set in a single
 .B ldapurl
 argument, resulting in the underlying library automatically 
 call the first server of the list that responds, e.g. 
@@ -86,29 +88,45 @@
 \fBuri "ldap://host/ ldap://backup-host/"\fP
 
 The URI list is space- or comma-separated.
-.\"This statement is mandatory.
-.\".TP
-.\".B server <hostport>
-.\"Obsolete option; same as `uri ldap://<hostport>/'.
+Whenever the server that responds is not the first one in the list,
+the list is rearranged and the responsive server is moved to the head,
+so that it will be first contacted the next time a connection
+needs be created.
 .HP
 .hy 0
 .B acl-bind
 .B bindmethod=simple|sasl [binddn=<simple DN>] [credentials=<simple password>]
 .B [saslmech=<SASL mech>] [secprops=<properties>] [realm=<realm>]
 .B [authcId=<authentication ID>] [authzId=<authorization ID>]
+.B [tls_cert=<file>]
+.B [tls_key=<file>]
+.B [tls_cacert=<file>]
+.B [tls_cacertdir=<path>]
+.B [tls_reqcert=never|allow|try|demand]
+.B [tls_ciphersuite=<ciphers>]
+.B [tls_crlcheck=none|peer|all]
 .RS
 Allows to define the parameters of the authentication method that is 
-internally used by the proxy to collect info related to access control.
+internally used by the proxy to collect info related to access control,
+and whenever an operation occurs with the identity of the rootdn
+of the LDAP proxy database.
 The identity defined by this directive, according to the properties
 associated to the authentication method, is supposed to have read access 
 on the target server to attributes used on the proxy for ACL checking.
+
 There is no risk of giving away such values; they are only used to
 check permissions.
 The default is to use
 .BR simple 
 bind, with empty \fIbinddn\fP and \fIcredentials\fP,
 which means that the related operations will be performed anonymously.
+If not set, and if \fBidassert-bind\fP is defined, this latter identity
+is used instead.  See \fBidassert-bind\fP for details.
 
+The connection between the proxy database and the remote server
+associated to this identity is cached regardless of the lifespan
+of the client-proxy connection that first established it.
+
 .B This identity is by no means implicitly used by the proxy 
 .B when the client connects anonymously.
 The
@@ -119,9 +137,44 @@
 .BR acl-authcDN ,
 and
 .BR acl-passwd .
+
+The TLS settings default to the same as the main slapd TLS settings,
+except for
+.B tls_reqcert
+which defaults to "demand".
 .RE
 
 .TP
+.B cancel {ABANDON|ignore|exop[-discover]}
+Defines how to handle operation cancellation.
+By default,
+.B abandon
+is invoked, so the operation is abandoned immediately.
+If set to
+.BR ignore ,
+no action is taken and any further response is ignored; this may result
+in further response messages to be queued for that connection, so it is
+recommended that long lasting connections are timed out either by
+.I idle-timeout
+or
+.IR conn-ttl ,
+so that resources eventually get released.
+If set to
+.BR exop ,
+a
+.I cancel
+operation (RFC 3909) is issued, resulting in the cancellation 
+of the current operation; the
+.I cancel
+operation waits for remote server response, so its use 
+may not be recommended.
+If set to
+.BR exop-discover ,
+support of the
+.I cancel 
+extended operation is detected by reading the remote server's root DSE.
+
+.TP
 .B chase-referrals {YES|no}
 enable/disable automatic referral chasing, which is delegated to the
 underlying libldap, with rebinding eventually performed if the
@@ -155,6 +208,13 @@
 .B [saslmech=<SASL mech>] [secprops=<properties>] [realm=<realm>]
 .B [authcId=<authentication ID>] [authzId=<authorization ID>]
 .B [authz={native|proxyauthz}] [mode=<mode>] [flags=<flags>]
+.B [tls_cert=<file>]
+.B [tls_key=<file>]
+.B [tls_cacert=<file>]
+.B [tls_cacertdir=<path>]
+.B [tls_reqcert=never|allow|try|demand]
+.B [tls_ciphersuite=<ciphers>]
+.B [tls_crlcheck=none|peer|all]
 .RS
 Allows to define the parameters of the authentication method that is 
 internally used by the proxy to authorize connections that are 
@@ -196,7 +256,8 @@
 parameters).
 Otherwise, the default
 .B proxyauthz
-is used, i.e. the proxyAuthz control is added to all operations.
+is used, i.e. the proxyAuthz control (Proxied Authorization, RFC 4370)
+is added to all operations.
 
 The supported modes are:
 
@@ -267,7 +328,7 @@
 
 Flags can be
 
-\fBoverride,{prescriptive|non-prescriptive}\fP
+\fBoverride,[non-]prescriptive\fP
 
 When the 
 .B override
@@ -291,6 +352,15 @@
 .B idassert-authzFrom
 patterns.
 
+The TLS settings default to the same as the main slapd TLS settings,
+except for
+.B tls_reqcert
+which defaults to "demand".
+
+The identity associated to this directive is also used for privileged
+operations whenever \fBidassert-bind\fP is defined and \fBacl-bind\fP
+is not.  See \fBacl-bind\fP for details.
+
 This directive obsoletes
 .BR idassert-authcDN ,
 .BR idassert-passwd ,
@@ -333,6 +403,24 @@
 in conjunction with Proxy Authorization.
 
 .TP
+.B quarantine <interval>,<num>[;<interval>,<num>[...]]
+Turns on quarantine of URIs that returned
+.IR LDAP_UNAVAILABLE ,
+so that an attempt to reconnect only occurs at given intervals instead
+of any time a client requests an operation.
+The pattern is: retry only after at least
+.I interval
+seconds elapsed since last attempt, for exactly
+.I num
+times; then use the next pattern.
+If
+.I num
+for the last pattern is "\fB+\fP", it retries forever; otherwise, 
+no more retries occur.
+The process can be restarted by resetting the \fIolcDbQuarantine\fP
+attribute of the database entry in the configuration backend.
+
+.TP
 .B rebind-as-user {NO|yes}
 If this option is given, the client's bind credentials are remembered
 for rebinds, when trying to re-establish a broken connection,
@@ -342,6 +430,17 @@
 .IR yes .
 
 .TP
+.B session\-tracking\-request {NO|yes}
+Adds session tracking control for all requests.
+The client's IP and hostname, and the identity associated to each request,
+if known, are sent to the remote server for informational purposes.
+This directive is incompatible with setting \fIprotocol\-version\fP to 2.
+
+.TP
+.B single\-conn {NO|yes}
+Discards current cached connection when the client rebinds.
+
+.TP
 .B t-f-support {NO|yes|discover}
 enable if the remote server supports absolute filters
 (see \fIdraft-zeilenga-ldap-t-f\fP for details).
@@ -350,53 +449,96 @@
 support is detected by reading the remote server's root DSE.
 
 .TP
-.B timeout [{add|delete|modify|modrdn}=]<val> [...]
+.B timeout [<op>=]<val> [...]
 This directive allows to set per-operation timeouts.
-If no operation is specified, it affects all.
-Currently, only write operations are addressed, because searches
-can already be limited by means of the
-.B limits
-directive (see 
+Operations can be
+
+\fB<op> ::= bind, add, delete, modrdn, modify, compare, search\fP
+
+The overall duration of the \fBsearch\fP operation is controlled either
+by the \fBtimelimit\fP parameter or by server-side enforced
+time limits (see \fBtimelimit\fP and \fBlimits\fP in
 .BR slapd.conf (5)
-for details), and other operations are not supposed to incur into the
-need for timeouts.
-Note: if the timelimit is exceeded, the operation is abandoned;
-the protocol does not provide any means to rollback the operation,
-so the client will not know if the operation eventually succeeded or not.
+for details).
+This \fBtimeout\fP parameter controls how long the target can be 
+irresponsive before the operation is aborted.
+Timeout is meaningless for the remaining operations,
+\fBunbind\fP and \fBabandon\fP, which do not imply any response,
+while it is not yet implemented in currently supported \fBextended\fP 
+operations.
+If no operation is specified, the timeout \fBval\fP affects all
+supported operations.
 
-.TP
-.B tls {[try-]start|[try-]propagate}
-execute the StartTLS extended operation when the connection is initialized;
-only works if the URI directive protocol scheme is not \fBldaps://\fP.
+Note: if the timelimit is exceeded, the operation is cancelled
+(according to the \fBcancel\fP directive);
+the protocol does not provide any means to rollback operations,
+so the client will not be notified about the result of the operation,
+which may eventually succeeded or not.
+In case the timeout is exceeded during a bind operation, the connection
+is destroyed, according to RFC4511.
+
+Note: in some cases, this backend may issue binds prior
+to other operations (e.g. to bind anonymously or with some prescribed
+identity according to the \fBidassert-bind\fP directive).
+In this case, the timeout of the operation that resulted in the bind
+is used.
+
+.HP
+.hy 0
+.B tls {[try-]start|[try-]propagate|ldaps}
+.B [tls_cert=<file>]
+.B [tls_key=<file>]
+.B [tls_cacert=<file>]
+.B [tls_cacertdir=<path>]
+.B [tls_reqcert=never|allow|try|demand]
+.B [tls_ciphersuite=<ciphers>]
+.B [tls_crlcheck=none|peer|all]
+.RS
+Specify the use of TLS when a regular connection is initialized. The
+StartTLS extended operation will be used unless the URI directive protocol
+scheme is \fBldaps://\fP. In that case this keyword may only be
+set to "ldaps" and the StartTLS operation will not be used.
 \fBpropagate\fP issues the StartTLS operation only if the original
 connection did.
 The \fBtry-\fP prefix instructs the proxy to continue operations
-if the StartTLS operation failed; its use is highly deprecated.
+if the StartTLS operation failed; its use is \fBnot\fP recommended.
 
+The TLS settings default to the same as the main slapd TLS settings,
+except for
+.B tls_reqcert
+which defaults to "demand".
+.RE
+
+.TP
+.B use-temporary-conn {NO|yes}
+when set to 
+.BR yes ,
+create a temporary connection whenever competing with other threads
+for a shared one; otherwise, wait until the shared connection is available.
+
 .SH BACKWARD COMPATIBILITY
-The LDAP backend has been heavily reworked between releases 2.2 and 2.3;
-as a side-effect, some of the traditional directives have been
+The LDAP backend has been heavily reworked between releases 2.2 and 2.3,
+and subsequently between 2.3 and 2.4.
+As a side-effect, some of the traditional directives have been
 deprecated and should be no longer used, as they might disappear
 in future releases.
 
 .TP
-.B server <hostname[:port]>
-this directive is no longer supported.  Use the 
-.B uri
-directive as described above.
-
-.TP
 .B acl-authcDN "<administrative DN for access control purposes>"
-DN which is used to query the target server for acl checking; it
-is supposed to have read access on the target server to attributes used
+Formerly known as the
+.BR binddn ,
+it is the DN that is used to query the target server for acl checking;
+it is supposed to have read access on the target server to attributes used
 on the proxy for acl checking.
 There is no risk of giving away such values; they are only used to
 check permissions.
+
 .B The acl-authcDN identity is by no means implicitly used by the proxy 
 .B when the client connects anonymously.
-See the
+The
 .B idassert-*
-feature instead.
+feature can be used (at own risk) for that purpose instead.
+
 This directive is obsoleted by the
 .B binddn
 arg of
@@ -405,11 +547,13 @@
 
 .TP
 .B acl-passwd <password>
-Password used with the above
+Formerly known as the
+.BR bindpw ,
+it is the password used with the above
 .B acl-authcDN
 directive.
 This directive is obsoleted by the
-.B binddn
+.B credentials
 arg of
 .B acl-bind
 when \fIbindmethod\fP=\fBsimple\fP, and will be dismissed in the future.
@@ -432,7 +576,7 @@
 above.
 This directive is obsoleted by the
 .B crendentials
-of
+arg of
 .B idassert-bind
 when \fIbindmethod\fP=\fBsimple\fP, and will be dismissed in the future.
 
@@ -456,6 +600,18 @@
 and will be dismissed in the future.
 
 .TP
+.B port <port>
+this directive is no longer supported.  Use the 
+.B uri
+directive as described above.
+
+.TP
+.B server <hostname[:port]>
+this directive is no longer supported.  Use the 
+.B uri
+directive as described above.
+
+.TP
 .B suffixmassage, map, rewrite*
 These directives are no longer supported by back-ldap; their 
 functionality is now delegated to the

Modified: openldap/trunk/doc/man/man5/slapd-ldbm.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-ldbm.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-ldbm.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,141 +1,20 @@
 .TH SLAPD-LDBM 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-ldbm.5,v 1.8.2.6 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-ldbm.5,v 1.14.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapd-ldbm \- LDBM backend to slapd
+slapd-ldbm \- Discontinued LDBM backend to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
-The LDBM backend to
-.BR slapd (8)
-is an easy\-to\-configure but obsolete database backend.  It does not
-offer the data durability features of the BDB and HDB backends and
-hence is considered deprecated in favor of these robust backends.
-LDBM uses lightweight non\-transactional data interfaces, such as those
-provided by GDBM or Berkeley DB, to store data.  It makes extensive
-use of indexing and caching to speed data access.
-.SH CONFIGURATION
-These
-.B slapd.conf
-options apply to the LDBM backend database.
-That is, they must follow a "database ldbm" line and come before any
-subsequent "backend" or "database" lines.
-Other database options are described in the
-.BR slapd.conf (5)
-manual page.
-.TP
-.B cachesize <integer>
-Specify the size in entries of the in-memory cache maintained 
-by the LDBM backend database instance.
-The default is 1000 entries.
-.TP
-.B dbcachesize <integer>
-Specify the size in bytes of the in-memory cache associated with each
-open index file.
-If not supported by the underlying database method, this option is
-ignored without comment.
-The default is 100000 bytes.
-.TP
-.B dbnolocking
-Specify that no database locking should be performed.  
-Enabling this option may improve performance at the expense of data security.
-Do NOT run any slap tools while slapd is running.
-.TP
-.B dbnosync
-Specify that on-disk database contents should not be immediately
-synchronized with in memory changes.
-Enabling this option may improve performance at the expense of data
-security.
-.TP
-.B dbsync <frequency> <maxdelays> <delayinterval>
-Flush dirty database buffers to disk every
-.B <seconds>
-seconds.
-Implies
-.B dbnosync
-(ie. individual updates are no longer written to disk).
-It attempts to avoid syncs during periods of peak activity by waiting
-.B <delayinterval>
-seconds if the server is busy, repeating this delay up to
-.B <maxdelays>
-times before proceeding.  
-It is an attempt to provide higher write performance with some amount
-of data security.
-Note that it may still be possible to get an inconsistent database if
-the underlying engine fills its cache and writes out individual pages
-and slapd crashes or is killed before the next sync.
-.B <maxdelays>
-and
-.B <delayinterval>
-are optional and default to
-.B 12
-and
-.B 5
-respectively, giving a total elapsed delay of 60 seconds before a sync
-will occur.
-.B <maxdelays>
-may be zero, and
-.B <delayinterval>
-must be 1 or greater.
-.TP
-.B directory <directory>
-Specify the directory where the LDBM files containing this database and
-associated indexes live.
-A separate directory must be specified for each database.
-The default is
-.BR LOCALSTATEDIR/openldap-data .
-.TP
-.B
-index {<attrlist>|default} [pres,eq,approx,sub,<special>]
-Specify the indexes to maintain for the given attribute (or
-list of attributes).
-Some attributes only support a subset of indexes.
-If only an <attr> is given, the indices specified for \fBdefault\fR
-are maintained.
-Note that setting a default does not imply that all attributes will be
-indexed. Also, for best performance, an
-.B eq
-index should always be configured for the
-.B objectClass
-attribute.
+LDBM was the original database backend to
+.BR slapd (8),
+and was supported up to OpenLDAP 2.3.
+It has been superseded by the more robust BDB and HDB backends.
 
-A number of special index parameters may be specified.
-The index type
-.B sub
-can be decomposed into
-.BR subinitial ,
-.BR subany ,\ and
-.B subfinal
-indices.
-The special type
-.B notags
-(or
-.BR nolang )
-may be specified to disallow use of this index by subtypes with tagging
-options (such as language options).
-The special type
-.B nosubtypes
-may be specified to disallow use of this index by named subtypes.
-Note: changing index settings requires rebuilding indices, see
-.BR slapindex (8).
-.TP
-.B mode <integer>
-Specify the file protection mode that newly created database 
-index files should have.
-The default is 0600.
-.SH ACCESS CONTROL
-The 
-.B ldbm
-backend honors access control semantics as indicated in
-.BR slapd.access (5).
-.SH FILES
-.TP
-ETCDIR/slapd.conf
-default slapd configuration file
 .SH SEE ALSO
-.BR slapd.conf (5),
 .BR slapd (8),
-.BR slapadd (8),
-.BR slapcat (8),
-.BR slapindex (8).
+.BR slapd-bdb (5),
+.BR slapd.backends (5).
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Modified: openldap/trunk/doc/man/man5/slapd-ldif.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-ldif.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-ldif.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,7 @@
 .TH SLAPD-LDIF 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-ldif.5,v 1.1.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-ldif.5,v 1.3.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
 slapd-ldif \- LDIF backend to slapd
 .SH SYNOPSIS

Modified: openldap/trunk/doc/man/man5/slapd-meta.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-meta.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-meta.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -2,7 +2,7 @@
 .\" Copyright 1998-2007 The OpenLDAP Foundation, All Rights Reserved.
 .\" Copying restrictions apply.  See the COPYRIGHT file.
 .\" Copyright 2001, Pierangelo Masarati, All rights reserved. <ando at sys-net.it>
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-meta.5,v 1.29.2.17 2007/09/13 19:33:55 ando Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-meta.5,v 1.46.2.7 2007/09/13 19:17:15 ando Exp $
 .\"
 .\" Portions of this document should probably be moved to slapd-ldap(5)
 .\" and maybe manual pages for librewrite.
@@ -173,6 +173,15 @@
 .IR yes .
 
 .TP
+.B session\-tracking\-request {NO|yes}
+Adds session tracking control for all requests.
+The client's IP and hostname, and the identity associated to each request,
+if known, are sent to the remote server for informational purposes.
+This directive is incompatible with setting \fIprotocol\-version\fP to 2.
+If set before any target specification, it affects all targets, unless
+overridden by any per-target directive.
+
+.TP
 .B single\-conn {NO|yes}
 Discards current cached connection when the client rebinds.
 

Modified: openldap/trunk/doc/man/man5/slapd-monitor.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-monitor.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-monitor.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,10 +1,9 @@
 .TH SLAPD-MONITOR 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-monitor.5,v 1.4.2.6 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-monitor.5,v 1.9.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-.B slapd-monitor 
-\- Monitor backend to slapd
+slapd-monitor \- Monitor backend to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -122,4 +121,5 @@
 .BR slapd.access (5),
 .BR slapd (8),
 .BR ldap (3).
-
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Modified: openldap/trunk/doc/man/man5/slapd-null.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-null.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-null.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,7 @@
 .TH SLAPD-NULL 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 2002-2007 The OpenLDAP Foundation.  All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-null.5,v 1.5.4.5 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-null.5,v 1.10.2.3 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
 slapd-null \- Null backend to slapd
 .SH SYNOPSIS
@@ -18,7 +18,8 @@
 .br
 - Updates return success (unless readonly is on) but do nothing.
 .br
-- Binds fail unless the database option "bind on" is given.
+- Binds other than as the rootdn fail unless the database option "bind
+on" is given.
 .br
 - The
 .BR slapadd (8)
@@ -38,7 +39,7 @@
 manual page.
 .TP
 .B bind <on/off>
-Allow binds as DNs in this backend's suffix.
+Allow binds as any DN in this backend's suffix, with any password.
 The default is "off".
 .SH EXAMPLE
 Here is a possible slapd.conf extract using the Null backend:

Modified: openldap/trunk/doc/man/man5/slapd-passwd.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-passwd.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-passwd.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,7 @@
 .TH SLAPD-PASSWD 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-passwd.5,v 1.8.2.5 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-passwd.5,v 1.11.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
 slapd-passwd \- /etc/passwd backend to slapd
 .SH SYNOPSIS

Modified: openldap/trunk/doc/man/man5/slapd-perl.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-perl.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-perl.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH SLAPD-PERL 5 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-perl.5,v 1.5.4.2 2005/07/10 04:36:40 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-perl.5,v 1.7 2005/07/04 04:57:11 hallvard Exp $
 .SH NAME
 slapd-perl \- Perl backend to slapd
 .SH SYNOPSIS

Modified: openldap/trunk/doc/man/man5/slapd-relay.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-relay.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-relay.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -12,8 +12,8 @@
 instance into a virtual naming context, with attributeType
 and objectClass manipulation, if required.
 It requires the
-.B rwm
-.BR overlay .
+.BR slapo-rwm (5)
+overlay.
 .LP
 This backend and the above mentioned overlay are experimental.
 .SH CONFIGURATION
@@ -26,28 +26,31 @@
 .BR slapd.conf (5)
 manual page; only the
 .B suffix
-directive is required by the 
+directive is allowed by the 
 .I relay
 backend.
 .TP
-.B relay <real naming context> [massage]
+.B relay <real naming context>
 The naming context of the database that is presented 
 under a virtual naming context.
 The presence of this directive implies that one specific database,
 i.e. the one serving the
 .BR "real naming context" ,
 will be presented under a virtual naming context.
-This directive automatically instantiates the 
-.IR "rwm overlay" .
-If the optional
-.B massage
-keyword is present, the suffix massaging is automatically
-configured as well; otherwise, specific massaging instructions
-are required by means of the
-.I rewrite
-directives described in
-.BR slapo-rwm (5).
 
+.SH MASSAGING
+The
+.B relay
+database does not automatically rewrite the naming context
+of requests and responses.
+For this purpose, the
+.BR slapo-rwm (5)
+overlay must be explicitly instantiated, and configured
+as appropriate.
+Usually, the
+.B rwm-suffixmassage
+directive suffices if only naming context rewriting is required.
+
 .SH ACCESS RULES
 One important issue is that access rules are based on the identity
 that issued the operation.
@@ -57,7 +60,7 @@
 Moreover, since
 .B back-relay
 bypasses the real database frontend operations by short-circuiting
-operations thru the internal backend API, the original database
+operations through the internal backend API, the original database
 access rules do not apply but in selected cases, i.e. when the
 backend itself applies access control.
 As a consequence, the instances of the relay database must provide
@@ -88,29 +91,26 @@
 databases based on details of the virtual naming context,
 e.g. groups on one database and persons on another.
 .LP
-.SH Caveats
-The
-.B rwm overlay
-is experimental.
-.LP
 .SH EXAMPLES
 To implement a plain virtual naming context mapping
 that refers to a single database, use
 .LP
 .nf
-  database        relay
-  suffix          "dc=virtual,dc=naming,dc=context"
-  relay           "dc=real,dc=naming,dc=context" massage
+  database                relay
+  suffix                  "dc=virtual,dc=naming,dc=context"
+  relay                   "dc=real,dc=naming,dc=context"
+  overlay                 rwm
+  rwm-suffixmassage       "dc=real,dc=naming,dc=context"
 .fi
 .LP
 To implement a plain virtual naming context mapping
 that looks up the real naming context for each operation, use
 .LP
 .nf
-  database        relay
-  suffix          "dc=virtual,dc=naming,dc=context"
-  overlay         rwm
-  suffixmassage   "dc=real,dc=naming,dc=context"
+  database                relay
+  suffix                  "dc=virtual,dc=naming,dc=context"
+  overlay                 rwm
+  rwm-suffixmassage       "dc=real,dc=naming,dc=context"
 .fi
 .LP
 This is useful, for instance, to relay different databases that
@@ -122,39 +122,43 @@
 back from the real to the virtual naming context, use
 .LP
 .nf
-  database        relay
-  suffix          "dc=virtual,dc=naming,dc=context"
-  relay           "dc=real,dc=naming,dc=context"
-  rewriteEngine   on
-  rewriteContext  default
-  rewriteRule     "dc=virtual,dc=naming,dc=context"
-          "dc=real,dc=naming,dc=context" ":@"
-  rewriteContext  searchFilter
-  rewriteContext  searchEntryDN
-  rewriteContext  searchAttrDN
-  rewriteContext  matchedDN
+  database                relay
+  suffix                  "dc=virtual,dc=naming,dc=context"
+  relay                   "dc=real,dc=naming,dc=context"
+  overlay                 rwm
+  rwm-rewriteEngine       on
+  rwm-rewriteContext      default
+  rwm-rewriteRule         "dc=virtual,dc=naming,dc=context"
+                          "dc=real,dc=naming,dc=context" ":@"
+  rwm-rewriteContext      searchFilter
+  rwm-rewriteContext      searchEntryDN
+  rwm-rewriteContext      searchAttrDN
+  rwm-rewriteContext      matchedDN
 .fi
 .LP
-Note that the virtual database is bound to a single real database,
-so the 
-.B rwm overlay
-is automatically instantiated, but the rewrite rules 
-are written explicitly to map all the virtual to real 
-naming context data flow, but none of the real to virtual.
+Note that the 
+.BR slapo-rwm (5)
+overlay is instantiated, but the rewrite rules are written explicitly,
+rather than automatically as with the
+.B rwm-suffixmassage
+statement, to map all the virtual to real naming context data flow,
+but none of the real to virtual.
 .LP
 Access rules:
 .LP
 .nf
-  database        bdb
-  suffix          "dc=example,dc=com"
+  database                bdb
+  suffix                  "dc=example,dc=com"
   # skip...
   access to dn.subtree="dc=example,dc=com"
           by dn.exact="cn=Supervisor,dc=example,dc=com" write
           by * read
 
-  database        relay
-  suffix          "o=Example,c=US"
-  relay           "dc=example,dc=com" massage
+  database                relay
+  suffix                  "o=Example,c=US"
+  relay                   "dc=example,dc=com"
+  overlay                 rwm
+  rwm-suffixmassage       "dc=example,dc=com"
   # skip ...
   access to dn.subtree="o=Example,c=US"
           by dn.exact="cn=Supervisor,dc=example,dc=com" write

Modified: openldap/trunk/doc/man/man5/slapd-shell.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-shell.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-shell.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,7 @@
 .TH SLAPD-SHELL 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-shell.5,v 1.13.2.6 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-shell.5,v 1.16.2.3 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
 slapd-shell \- Shell backend to slapd
 .SH SYNOPSIS

Modified: openldap/trunk/doc/man/man5/slapd-sql.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-sql.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-sql.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH SLAPD-SQL 5 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-sql.5,v 1.16.2.8 2007/08/22 09:01:17 ando Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-sql.5,v 1.26.4.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
 slapd-sql \- SQL backend to slapd
 .SH SYNOPSIS
@@ -26,7 +26,7 @@
 (OpenLDAP FAQ-O-Matic/General LDAP FAQ/Directories vs. conventional
 databases) to find out more on this point.
 .LP
-The idea (detailed below) is to use some metainformation to translate
+The idea (detailed below) is to use some meta-information to translate
 LDAP queries to SQL queries, leaving relational schema untouched, so
 that old applications can continue using it without any
 modifications.
@@ -34,7 +34,7 @@
 replication, and exchange data as needed.
 .LP
 The SQL backend is designed to be tunable to virtually any relational
-schema without having to change source (through that metainformation
+schema without having to change source (through that meta-information
 mentioned).
 Also, it uses ODBC to connect to RDBMSes, and is highly configurable
 for SQL dialects RDBMSes may use, so it may be used for integration
@@ -107,7 +107,7 @@
 .RE
 .SH STATEMENT CONFIGURATION
 These options specify SQL query templates for loading schema mapping
-metainformation, adding and deleting entries to ldap_entries, etc.
+meta-information, adding and deleting entries to ldap_entries, etc.
 All these and subtree_cond should have the given default values.
 For the current value it is recommended to look at the sources,
 or in the log output when slapd starts with "-d 5" or greater.
@@ -520,7 +520,7 @@
 keys - he may want to write a patch, and submit it to OpenLDAP ITS,
 then I'll include it.
 .LP
-Also, several people complained that they don't really need very
+Also, several users complained that they don't really need very
 structured trees, and they don't want to update one more table every
 time they add or delete an instance in the relational schema.
 Those people can use a view instead of a real table for ldap_entries, something
@@ -551,8 +551,8 @@
 directive for a possible workaround.
 
 .LP
-.SH Typical SQL backend operation
-Having metainformation loaded, the SQL backend uses these tables to
+.SH TYPICAL SQL BACKEND OPERATION
+Having meta-information loaded, the SQL backend uses these tables to
 determine a set of primary keys of candidates (depending on search
 scope and filter).
 It tries to do it for each objectclass registered in ldap_objclasses.
@@ -592,7 +592,7 @@
 the user.
 .LP
 ADD, DELETE, MODIFY and MODRDN operations are also performed on per-attribute
-metainformation (add_proc etc.).
+meta-information (add_proc etc.).
 In those fields one can specify an SQL statement or stored procedure
 call which can add, or delete given values of a given attribute, using
 the given entry keyval (see examples -- mostly PostgreSQL, ORACLE and MSSQL 
@@ -605,17 +605,16 @@
 information on this matter - they are self-explanatory for those familiar
 with the concepts expressed above.
 .LP
-.SH Common techniques (referrals, multiclassing etc.)
-First of all, let's remember that among other major differences to the
-complete LDAP data model, the concept above does not directly support
-such things as multiple objectclasses per entry, and referrals.
+.SH COMMON TECHNIQUES
+First of all, let's recall that among other major differences to the
+complete LDAP data model, the above illustrated concept does not directly
+support such features as multiple objectclasses per entry, and referrals.
 Fortunately, they are easy to adopt in this scheme.
-The SQL backend suggests one more table being added to the schema:
+The SQL backend requires that one more table is added to the schema:
 ldap_entry_objectclasses(entry_id,oc_name).
 .LP
-The first contains any number of objectclass names that corresponding
-entries will be found by, in addition to that mentioned in
-mapping.
+That table contains any number of objectclass names that corresponding
+entries will possess, in addition to that mentioned in mapping.
 The SQL backend automatically adds attribute mapping for the "objectclass"
 attribute to each objectclass mapping that loads values from this table.
 So, you may, for instance, have a mapping for inetOrgPerson, and use it
@@ -635,7 +634,7 @@
 an "extensibleObject" value to ldap_entry_objclasses.
 
 .LP
-.SH Caveats
+.SH CAVEATS
 As previously stated, this backend should not be considered
 a replacement of other data storage backends, but rather a gateway
 to existing RDBMS storages that need to be published in LDAP form.
@@ -652,10 +651,10 @@
 instead.
 .LP
 A directoryString value of the form "__First___Last_"
-(where underscores should be replaced by spaces) corresponds
+(where underscores mean spaces, ASCII 0x20 char) corresponds
 to its prettified counterpart "First_Last"; this is not currently
 honored by back-sql if non-prettified data is written via RDBMS;
-when non-prettified data is written thru back-sql, the prettified 
+when non-prettified data is written through back-sql, the prettified 
 values are actually used instead.
 
 .LP

Deleted: openldap/trunk/doc/man/man5/slapd-tcl.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd-tcl.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd-tcl.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,271 +0,0 @@
-.TH SLAPD-TCL 5 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd-tcl.5,v 1.7 2003/01/09 11:07:14 kurt Exp $
-.SH NAME
-slapd-tcl \- Tcl backend to slapd
-.SH SYNOPSIS
-ETCDIR/slapd.conf
-.SH DESCRIPTION
-The Tcl backend to
-.BR slapd (8)
-works by embedding a
-.BR Tcl (3tcl)
-interpreter into
-.BR slapd (8).
-Any tcl database section of the configuration file
-.BR slapd.conf (5)
-must then specify what Tcl script to use.
-.LP
-This backend is experimental.
-.SH WARNING
-.B "This backend's calling conventions have changed since OpenLDAP 2.0."
-Previously, the 2nd argument to the procs was a message ID.
-Now they are an "operation ID" string.
-Also, proc abandon now gets a new
-.B abandonid
-argument.
-.SH CONFIGURATION
-These
-.B slapd.conf
-options apply to the TCL backend database.
-That is, they must follow a "database tcl" line and come before any
-subsequent "backend" or "database" lines.
-Other database options are described in the
-.BR slapd.conf (5)
-manual page.
-.TP
-.B scriptpath      <filename.tcl>
-The full path to the tcl script used for this database.
-.LP
-.B search   <proc>
-.br
-.B add      <proc>
-.br
-.B delete   <proc>
-.br
-.B modify   <proc>
-.br
-.B bind     <proc>
-.br
-.B unbind   <proc>
-.br
-.B modrdn   <proc>
-.br
-.B compare  <proc>
-.br
-.B abandon  <proc>
-.RS
-The procs for each ldap function.
-They refer to the tcl procs in the `scriptpath' script that handles them.
-.RE
-.TP
-.B tclrealm <interpreter name>
-This is one of the biggest pluses of using the tcl backend.
-The realm lets 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 between databases.
-If no tclrealm is specified, it is put into the "default" realm.
-.SH Variables passed to the procs
-.TP
-.B abandon { action opid suffix abandonid }
-.nf
-action    - Always equal to ABANDON.
-opid      - The opid of this ldap operation.
-suffix    - List of suffix(es) associated with the
-            call.  Each one is an entry in a tcl
-            formatted list (surrounded by {}'s).
-abandonid - The opid of the operation to abandon.
-.fi
-.TP
-.B add "{ action opid suffix entry }"
-.nf
-action - Always equal to ADD.
-opid   - The opid of this ldap operation.
-suffix - List of suffix(es), as above.
-entry  - Full entry to add. Each "type: val" is
-         an element in a tcl formatted list.
-.fi
-.TP
-.B bind "{ action opid suffix dn method cred_len cred }"
-.nf
-action   - Always equal to BIND.
-opid     - The opid of this ldap operation.
-suffix   - List of suffix(es), as above.
-dn       - DN being bound to.
-method   - One of the ldap authentication methods.
-cred_len - Length of cred.
-cred     - Credentials being used to authenticate,
-           according to RFC.  If this value is empty,
-           then it should be considered an anonymous
-           bind (??)
-.fi
-.TP
-.B compare "{ action opid suffix dn ava_type ava_value }"
-.nf
-action    - Always equal to COMPARE.
-opid      - The opid of this ldap operation.
-suffix    - List of suffix(es), as above.
-dn        - DN for compare.
-ava_type  - Type for comparison.
-ava_value - Value to compare.
-.fi
-.TP
-.B delete "{ action opid suffix dn }"
-.nf
-action    - Always equal to DELETE.
-opid      - The opid of this ldap operation.
-suffix    - List of suffix(es), as above.
-dn        - DN to delete.
-.fi
-.TP
-.B modify "{ action opid suffix dn mods }"
-.nf
-action - Always equal to MODIFY.
-opid   - The opid of this ldap operation.
-suffix - List of suffix(es), as above.
-dn     - DN to modify.
-mods   - Tcl list of modifications.
-         The list is formatted in this way:
-
-         {
-           { {op: type} {type: val} }
-           { {op: type} {type: val} {type: val} }
-           ...
-         }
-
-         Newlines are not present in the actual var,
-         they are present here for clarification.
-         "op" is the type of modification
-         (ADD, DELETE, REPLACE).
-.fi
-.TP
-.B modrdn "{ action opid suffix dn newrdn deleteoldrdn }"
-.nf
-action - Always equal to MODRDN.
-opid   - The opid of this ldap operation.
-suffix - List of suffix(es), as above.
-dn     - DN whose RDN is being renamed.
-newrdn - New RDN.
-deleteoldrdn - Boolean stating whether or not the
-         old RDN should be removed after being renamed.
-.fi
-.TP
-.B
-search { action opid suffix base scope deref \
-sizelimit timelimit filterstr attrsonly attrlist }
-.nf
-action    - Always equal to SEARCH.
-opid      - The opid of this ldap operation.
-suffix    - List of suffix(es), as above.
-base      - Base for this search.
-scope     - Scope of search, ( 0 | 1 | 2 ).
-deref     - Alias dereferencing ( 0 | 1 | 2 | 3 ).
-sizelimit - Maximum number of entries to return.
-timelimit - Time limit for search.
-filterstr - Filter string as sent by the requester.
-attrsonly - Boolean for whether to list only the
-            attributes, and not values as well.
-attrlist  - Tcl list if to retrieve.
-.fi
-.TP
-.B unbind "{ action opid suffix dn }"
-.nf
-action - Always equal to UNBIND.
-opid   - The opid of this ldap operation.
-suffix - List of suffix(es), as above.
-dn     - DN to unbind.
-.fi
-.LP
-An
-.I opid
-(operation ID) is a "connection ID/message ID" string identifying an
-operation.
-.LP
-.SH Return Method and Syntax
-There are only 2 return types.
-All procs must return a result to show status of the operation.
-The result is in this form:
-.LP
-.RS
-.nf
-{ RESULT {code: <integer>} {matched: <partialdn>}
-  {info: <string>} {} }
-.fi
-.RE
-.LP
-This is best accomplished with this type of tcl code
-.LP
-.RS
-.nf
-  lappend ret_val "RESULT"
-  lappend ret_val "code: 0"
-  lappend ret_val ""
-  return $ret_val
-.fi
-.RE
-.LP
-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.
-In the bind proc, LDAP uses the value of `code' to indicate whether or
-not the authentication is acceptable.
-.LP
-The other type of return is for searches.
-It is similar format to the shell backend return (as is most of the
-syntax here).
-Its format follows:
-.LP
-.RS
-.nf
-{dn: o=Company, c=US} {attr: val} {objectclass: val} {}
-{dn: o=CompanyB, c=US} {attr: val} {objectclass: val} {}
-.fi
-.RE
-.LP
-Again, newlines are for visual purposes here.
-Also note the {} marking the end of the entry (same effect as a
-newline in ldif format).
-Here is some example code again, showing a full search proc example.
-.LP
-.RS
-.nf
-# 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...
-
-  lappend ret_val "dn: $rdn,$base"
-  lappend ret_val "objectclass: $objcl"
-  lappend ret_val "sn: $rdn"
-  lappend ret_val "mail: $email"
-  lappend ret_val ""
-  # Now setup the result
-  lappend ret_val "RESULT"
-  lappend ret_val "code: 0"
-  lappend ret_val ""
-  return $ret_val
-}
-.fi
-.RE
-.LP
-NOTE: Newlines in the return value is acceptable in search entries
-(i.e. when returning base64 encoded binary entries).
-.LP
-.SH Builtin Commands and Variables
-.TP
-.B ldap:debug <msg>
-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.
-.SH FILES
-.TP
-ETCDIR/slapd.conf
-default slapd configuration file
-.SH SEE ALSO
-.BR slapd.conf (5),
-.BR slapd (8),
-.BR Tcl (3tcl).

Modified: openldap/trunk/doc/man/man5/slapd.access.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd.access.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd.access.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,6 @@
 .TH SLAPD.ACCESS 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd.access.5,v 1.55.2.10 2007/01/02 21:43:45 kurt Exp $
 .SH NAME
 slapd.access \- access configuration for slapd, the stand-alone LDAP daemon
 .SH SYNOPSIS
@@ -11,9 +10,7 @@
 .BR slapd.conf (5)
 file contains configuration information for the
 .BR slapd (8)
-daemon. This configuration file is also used by the
-.BR slurpd (8)
-replication daemon and by the SLAPD tools
+daemon. This configuration file is also used by the SLAPD tools
 .BR slapacl (8),
 .BR slapadd (8),
 .BR slapauth (8),
@@ -74,6 +71,50 @@
 .BR <what> ) 
 by one or more requestors (specified by 
 .BR <who> ).
+
+.LP
+Lists of access directives are evaluated in the order they appear
+in \fIslapd.conf\fP.
+When a
+.B <what>
+clause matches the datum whose access is being evaluated, its
+.B <who>
+clause list is checked.
+When a
+.B <who>
+clause matches the accessor's properties, its
+.B <access>
+and
+.B <control>
+clauses are evaluated.
+Access control checking stops at the first match of the
+.B <what>
+and
+.B <who>
+clause, unless otherwise dictated by the
+.B <control>
+clause.
+Each
+.B <who>
+clause list is implicitly terminated by a
+.LP
+.nf
+	by * none stop
+.fi
+.LP
+clause that results in stopping the access control with no access 
+privileges granted.
+Each
+.B <what>
+clause list is implicitly terminated by a
+.LP
+.nf
+	access to *
+		by * none
+.fi
+.LP
+clause that results in granting no access privileges to an otherwise
+unspecified datum.
 .SH THE <WHAT> FIELD
 The field
 .BR <what>
@@ -151,7 +192,7 @@
 .LP
 The statement
 .B filter=<ldapfilter>
-selects the entries based on a valid LDAP filter as described in RFC 2254.
+selects the entries based on a valid LDAP filter as described in RFC 4515.
 A filter of
 .B (objectClass=*)
 is implied if no
@@ -248,8 +289,7 @@
 	tls_ssf=<n>
 	sasl_ssf=<n>
 
-	aci[=<attrname>]
-	dynacl/name[/<options>][.<dynstyle>][=<pattern>]
+	dynacl/<name>[/<options>][.<dynstyle>][=<pattern>]
 .fi
 .LP
 with
@@ -260,10 +300,11 @@
 	<dnstyle>={{exact|base(object)}|regex
 		|one(level)|sub(tree)|children|level{<n>}}
 	<groupstyle>={exact|expand}
-	<peernamestyle>={<style>|ip|path}
+	<peernamestyle>={<style>|ip|ipv6|path}
 	<domainstyle>={exact|regex|sub(tree)}
 	<setstyle>={exact|regex}
 	<modifier>={expand}
+	<name>=aci		<pattern>=<attrname>]
 .fi
 .LP
 They may be specified in combination.
@@ -490,7 +531,10 @@
 and
 .BR sockurl=<sockurl>
 mean that the contacting host IP (in the form 
-.BR "IP=<ip>:<port>" )
+.BR "IP=<ip>:<port>"
+for IPv4, or
+.BR "IP=[<ipv6>]:<port>"
+for IPv6)
 or the contacting host named pipe file name (in the form
 .B "PATH=<path>"
 if connecting through a named pipe) for
@@ -539,6 +583,9 @@
 are dotted digit representations of the IP and the mask, while
 .BR <n> ,
 delimited by curly brackets, is an optional port.
+The same applies to IPv6 addresses when the special
+.B ipv6
+style is used.
 When checking access privileges, the IP portion of the
 .BR peername 
 is extracted, eliminating the
@@ -551,7 +598,9 @@
 .BR <mask> .
 As an example, 
 .B peername.ip=127.0.0.1
-allows connections only from localhost,
+and
+.B peername.ipv6=::1
+allow connections only from localhost,
 .B peername.ip=192.168.1.0%255.255.255.0 
 allows connections from any IP in the 192.168.1 class C domain, and
 .B peername.ip=192.168.1.16%255.255.255.240{9009}
@@ -614,19 +663,6 @@
 is undocumented yet.
 .LP
 The statement
-.B aci[=<attrname>]
-means that the access control is determined by the values in the
-.B attrname
-of the entry itself.
-The optional
-.B <attrname>
-indicates what attributeType holds the ACI information in the entry.
-By default, the 
-.B OpenLDAPaci
-operational attribute is used.
-ACIs are experimental; they must be enabled at compile time.
-.LP
-The statement
 .B dynacl/<name>[/<options>][.<dynstyle>][=<pattern>]
 means that access checking is delegated to the admin-defined method
 indicated by
@@ -641,13 +677,20 @@
 .B <pattern>
 are optional, and are directly passed to the registered parsing routine.
 Dynacl is experimental; it must be enabled at compile time.
-If dynacl and ACIs are both enabled, ACIs are cast into the dynacl scheme,
-where 
-.B <name>=aci
-and, optionally,
-.BR <patten>=<attrname> .
-However, the original ACI syntax is preserved for backward compatibility.
 .LP
+The statement
+.B dynacl/aci[=<attrname>]
+means that the access control is determined by the values in the
+.B attrname
+of the entry itself.
+The optional
+.B <attrname>
+indicates what attributeType holds the ACI information in the entry.
+By default, the 
+.B OpenLDAPaci
+operational attribute is used.
+ACIs are experimental; they must be enabled at compile time.
+.LP
 The statements
 .BR ssf=<n> ,
 .BR transport_ssf=<n> ,
@@ -657,7 +700,7 @@
 set the minimum required Security Strength Factor (ssf) needed
 to grant access.  The value should be positive integer.
 .SH THE <ACCESS> FIELD
-The field
+The optional field
 .B <access> ::= [[real]self]{<level>|<priv>}
 determines the access level or the specific access privileges the
 .B who 
@@ -665,8 +708,8 @@
 Its component are defined as
 .LP
 .nf
-	<level> ::= none|disclose|auth|compare|search|read|write
-	<priv> ::= {=|+|-}{w|r|s|c|x|d|0}+
+	<level> ::= none|disclose|auth|compare|search|read|write|manage
+	<priv> ::= {=|+|-}{m|w|r|s|c|x|d|0}+
 .fi
 .LP
 The modifier
@@ -699,8 +742,8 @@
 and
 .BR write .
 Each access level implies all the preceding ones, thus 
-.B write
-access will imply all accesses.
+.B manage
+grants all access including administrative access,
 .LP
 The
 .B none 
@@ -733,6 +776,8 @@
 .B -
 signs add/remove access privileges to the existing ones.
 The privileges are
+.B m
+for manage,
 .B w
 for write,
 .B r
@@ -748,6 +793,7 @@
 More than one of the above privileges can be added in one statement.
 .B 0
 indicates no privileges and is used only by itself (e.g., +0).
+.LP
 If no access is given, it defaults to 
 .BR +0 .
 .SH THE <CONTROL> FIELD
@@ -1052,7 +1098,4 @@
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.
+.so ../Project

Copied: openldap/trunk/doc/man/man5/slapd.backends.5 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man5/slapd.backends.5)
===================================================================
--- openldap/trunk/doc/man/man5/slapd.backends.5	                        (rev 0)
+++ openldap/trunk/doc/man/man5/slapd.backends.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,136 @@
+.TH SLAPD.BACKENDS 5 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" Copyright 2006-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd.backends.5,v 1.3.2.2 2007/08/31 23:13:53 quanah Exp $
+.SH NAME
+slapd.backends \- backends for slapd, the stand-alone LDAP daemon
+.SH DESCRIPTION
+The
+.BR slapd (8)
+daemon can use a variety of different backends for serving LDAP requests.
+Backends may be compiled statically into slapd, or when module support
+is enabled, they may be dynamically loaded. Multiple instances of a
+backend can be configured, to serve separate databases from the same
+slapd server.
+
+
+Configuration options for each backend are documented separately in the
+corresponding
+.BR slapd-<backend> (5)
+manual pages.
+.TP
+.B bdb
+This is the recommended primary backend for a normal slapd database.
+It takes care to configure it properly.
+It uses the transactional database interface of the Oracle Berkeley
+DB (BDB) package to store data.
+.TP
+.B config
+This backend is used to manage the configuration of slapd at run-time.
+Unlike other backends, only a single instance of the
+.B config
+backend may be defined. It also instantiates itself automatically,
+so it is always present even if not explicitly defined in the
+.BR slapd.conf (5)
+file.
+.TP
+.B dnssrv
+This backend is experimental.
+It serves up referrals based upon SRV resource records held in the
+Domain Name System.
+.TP
+.B hdb
+This is a variant of the
+.B bdb
+backend that uses a hierarchical database
+layout. This layout stores entry DNs more efficiently than the
+.B bdb
+backend,
+using less space and requiring less work to create, delete, and rename
+entries. It is also one of the few backends to support subtree renames.
+.TP
+.B ldap
+This backend acts as a proxy to forward incoming requests to another
+LDAP server.
+.TP
+.B ldif
+This database uses the filesystem to build the tree structure
+of the database, using plain ascii files to store data.
+Its usage should be limited to very simple databases, where performance
+is not a requirement. This backend also supports subtree renames.
+.TP
+.B meta
+This backend performs basic LDAP proxying with respect to a set of
+remote LDAP servers. It is an enhancement of the
+.B ldap
+backend.
+.TP
+.B monitor
+This backend provides information about the running status of the slapd
+daemon. Only a single instance of the
+.B monitor
+backend may be defined.
+.TP
+.B null
+Operations in this backend succeed but do nothing.
+.TP
+.B passwd
+This backend is provided for demonstration purposes only.
+It serves up user account information from the system
+.BR passwd (5)
+file.
+.TP
+.B perl
+This backend embeds a
+.BR perl (1)
+interpreter into slapd.
+It runs Perl subroutines to implement LDAP operations.
+.TP
+.B relay
+This backend is experimental.
+It redirects LDAP operations to another database
+in the same server, based on the naming context of the request.
+Its use requires the 
+.B rwm
+overlay (see
+.BR slapo-rwm (5)
+for details) to rewrite the naming context of the request.
+It is primarily intended to implement virtual views on databases
+that actually store data.
+.TP
+.B shell
+This backend executes external programs to implement LDAP operations.
+It is primarily intended to be used in prototypes.
+.TP
+.B sql
+This backend is experimental.
+It services LDAP requests from an SQL database.
+.SH FILES
+.TP
+ETCDIR/slapd.conf
+default slapd configuration file
+.TP
+ETCDIR/slapd.d
+default slapd configuration directory
+.SH SEE ALSO
+.BR ldap (3),
+.BR slapd\-bdb (5),
+.BR slapd\-config (5),
+.BR slapd\-dnssrv (5),
+.BR slapd\-hdb (5),
+.BR slapd\-ldap (5),
+.BR slapd\-ldif (5),
+.BR slapd\-meta (5),
+.BR slapd\-monitor (5),
+.BR slapd\-null (5),
+.BR slapd\-passwd (5),
+.BR slapd\-perl (5),
+.BR slapd\-relay (5),
+.BR slapd\-shell (5),
+.BR slapd\-sql (5),
+.BR slapd.conf (5),
+.BR slapd.overlays (5),
+.BR slapd (8).
+"OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Modified: openldap/trunk/doc/man/man5/slapd.conf.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd.conf.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd.conf.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,7 @@
 .TH SLAPD.CONF 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd.conf.5,v 1.191.2.32 2007/10/11 20:56:48 quanah Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd.conf.5,v 1.239.2.14 2007/12/03 17:47:41 quanah Exp $
 .SH NAME
 slapd.conf \- configuration file for slapd, the stand-alone LDAP daemon
 .SH SYNOPSIS
@@ -11,9 +11,7 @@
 .B ETCDIR/slapd.conf
 contains configuration information for the
 .BR slapd (8)
-daemon.  This configuration file is also used by the
-.BR slurpd (8)
-replication daemon and by the SLAPD tools
+daemon.  This configuration file is also used by the SLAPD tools
 .BR slapacl (8),
 .BR slapadd (8),
 .BR slapauth (8),
@@ -54,7 +52,10 @@
 file is used).
 .LP
 If a line begins with white space, it is considered a continuation
-of the previous line.  Blank lines and comment lines beginning with
+of the previous line.  No physical line should be over 2000 bytes
+long.
+.LP
+Blank lines and comment lines beginning with
 a `#' character are ignored.  Note: continuation lines are unwrapped
 before comment processing is applied.
 .LP
@@ -102,6 +103,9 @@
 .B update_anon
 allows unauthenticated (anonymous) update operations to be processed
 (subject to access controls and other administrative limits).
+.B proxy_authz_anon
+allows unauthenticated (anonymous) proxy authorization control to be processed
+(subject to access controls, authorization and other administrative limits).
 .TP
 .B argsfile <filename>
 The ( absolute ) name of a file that will hold the 
@@ -415,9 +419,10 @@
 disables simple (bind) authentication.
 .B tls_2_anon
 disables forcing session to anonymous status (see also
-.BR tls_authc ) upon StartTLS operation receipt.
+.BR tls_authc )
+upon StartTLS operation receipt.
 .B tls_authc
-disallow the StartTLS operation if authenticated (see also
+disallows the StartTLS operation if authenticated (see also
 .BR tls_2_anon ).
 .HP
 .hy 0
@@ -465,6 +470,12 @@
 Read additional configuration information from the given file before
 continuing with the next line of the current file.
 .TP
+.B index_intlen <integer>
+Specify the key length for ordered integer indices. The most significant
+bytes of the binary integer will be used for index keys. The default
+value is 4, which provides exact indexing for 31 bit values.
+A floating point representation is used to index too large values.
+.TP
 .B index_substr_if_minlen <integer>
 Specify the minimum length for subinitial and subfinal indices. An
 attribute value must have at least this many characters in order to be
@@ -491,12 +502,12 @@
 using this filter "cn=*abcdefgh*" would generate index lookups for
 "abcd", "cdef", and "efgh".
 
-.\"-- NEW_LOGGING option --
-.\".TP
-.\".B logfile <filename>
-.\"Specify a file for recording debug log messages. By default these messages
-.\"only go to stderr and are not recorded anywhere else. Specifying a logfile
-.\"copies messages to both stderr and the logfile.
+.LP
+Note: Indexing support depends on the particular backend in use. Also,
+changing these settings will generally require deleting any indices that
+depend on these parameters and recreating them with
+.BR slapindex (8).
+
 .TP
 .B localSSF <SSF>
 Specifies the Security Strength Factor (SSF) to be given local LDAP sessions,
@@ -506,6 +517,11 @@
 .B minssf
 option description.  The default is 71.
 .TP
+.B logfile <filename>
+Specify a file for recording debug log messages. By default these messages
+only go to stderr and are not recorded anywhere else. Specifying a logfile
+copies messages to both stderr and the logfile.
+.TP
 .B loglevel <integer> [...]
 Specify the level at which debugging statements and operation 
 statistics should be syslogged (currently logged to the
@@ -514,8 +530,7 @@
 They must be considered subsystems rather than increasingly verbose 
 log levels.
 Some messages with higher priority are logged regardless 
-of the configured loglevel as soon as some logging is configured,
-otherwise anything is logged at all.
+of the configured loglevel as soon as any logging is configured.
 Log levels are additive, and available levels are:
 .RS
 .RS
@@ -555,7 +570,7 @@
 .TP
 .B 256
 .B (0x100 stats)
-stats log connections/operations/results
+connections, LDAP operations, results (recommended)
 .TP
 .B 512
 .B (0x200 stats2)
@@ -568,15 +583,15 @@
 .B 2048
 .B (0x800 parse)
 entry parsing
+\".TP
+\".B 4096
+\".B (0x1000 cache)
+\"caching (unused)
+\".TP
+\".B 8192
+\".B (0x2000 index)
+\"data indexing (unused)
 .TP
-.B 4096
-.B (0x1000 cache)
-caching (unused)
-.TP
-.B 8192
-.B (0x2000 index)
-data indexing (unused)
-.TP
 .B 16384
 .B (0x4000 sync)
 LDAPSync replication
@@ -611,7 +626,10 @@
 so at least the 
 .B none
 level is required to have high priority messages logged.
+
 The loglevel defaults to \fBstats\fP.
+This level should usually also be included when using other loglevels, to
+help analyze the logs.
 .RE
 .TP
 .B moduleload <filename>
@@ -717,24 +735,6 @@
 cannot find a local database to handle a request.
 If specified multiple times, each url is provided.
 .TP
-.B replica-argsfile
-The ( absolute ) name of a file that will hold the 
-.B slurpd
-server's command line options
-if started without the debugging command line option.
-.TP
-.B replica-pidfile
-The ( absolute ) name of a file that will hold the 
-.B slurpd
-server's process ID ( see
-.BR getpid (2)
-) if started without the debugging command line option.
-.TP
-.B replicationinterval
-The number of seconds 
-.B slurpd 
-waits before checking the replogfile for changes.
-.TP
 .B require <conditions>
 Specify a set of conditions (separated by white space) to
 require (default none).
@@ -767,6 +767,14 @@
 Specify the name of an LDIF(5) file containing user defined attributes
 for the root DSE.  These attributes are returned in addition to the
 attributes normally produced by slapd.
+
+The root DSE is an entry with information about the server and its
+capabilities, in operational attributes.
+It has the empty DN, and can be read with e.g.:
+.ti +4
+ldapsearch -x -b "" -s base "+"
+.br
+See RFC 4512 section 5.1 for details.
 .TP
 .B sasl-host <fqdn>
 Used to specify the fully qualified domain name used for SASL processing.
@@ -858,6 +866,22 @@
 factor is measure of security provided by the underlying transport,
 e.g. ldapi:// (and eventually IPSEC).  It is not normally used.
 .TP
+.B serverID <integer> [<URL>]
+Specify an integer ID from 0 to 4095 for this server (limited
+to 3 hexadecimal digits).
+These IDs are
+required when using multimaster replication and each master must have a
+unique ID. If the URL is provided, this directive may be specified
+multiple times, providing a complete list of participating servers
+and their IDs. The fully qualified hostname of each server should be
+used in the supplied URLs. The IDs are used in the "replica id" field
+of all CSNs generated by the specified server. The default value is zero.
+Example:
+.LP
+.nf
+	serverID 1
+.fi
+.TP
 .B sizelimit {<integer>|unlimited}
 .TP
 .B sizelimit size[.{soft|hard|unchecked}]=<integer> [...]
@@ -880,6 +904,14 @@
 Specify the maximum incoming LDAP PDU size for authenticated sessions.
 The default is 4194303.
 .TP
+.B sortvals <attr> [...]
+Specify a list of multi-valued attributes whose values will always
+be maintained in sorted order. Using this option will allow Modify,
+Compare, and filter evaluations on these attributes to be performed
+more efficiently. The resulting sort order depends on the
+attributes' syntax and matching rules and may not correspond to
+lexical order or any other recognizable order.
+.TP
 .B threads <integer>
 Specify the maximum size of the primary thread pool.
 The default is 16; the minimum value is 2.
@@ -922,7 +954,16 @@
 
 To check what ciphers a given spec selects, use:
 
-openssl ciphers -v <cipher-suite-spec>
+.nf
+	openssl ciphers -v <cipher-suite-spec>
+.fi
+
+To obtain the list of ciphers in GNUtls use:
+
+.nf
+	gnutls-cli -l
+.fi
+
 .TP
 .B TLSCACertificateFile <filename>
 Specifies the file that contains certificates for all of the Certificate
@@ -933,7 +974,8 @@
 .B TLSCACertificatePath <path>
 Specifies the path of a directory that contains Certificate Authority
 certificates in separate individual files. Usually only one of this
-or the TLSCACertificateFile is used.
+or the TLSCACertificateFile is used. This directive is not supported
+when using GNUtls.
 .TP
 .B TLSCertificateFile <filename>
 Specifies the file that contains the
@@ -956,12 +998,14 @@
 Anonymous Diffie-Hellman key exchanges in certain non-default cipher suites.
 You should append "!ADH" to your cipher suites if you have changed them
 from the default, otherwise no certificate exchanges or verification will
-be done.
+be done. When using GNUtls these parameters are always generated randomly so
+this directive is ignored.
 .TP
 .B TLSRandFile <filename>
 Specifies the file to obtain random bits from when /dev/[u]random
 is not available.  Generally set to the name of the EGD/PRNGD socket.
 The environment variable RANDFILE can also be used to specify the filename.
+This directive is ignored with GNUtls.
 .TP
 .B TLSVerifyClient <level>
 Specifies what checks to perform on client certificates in an
@@ -1003,7 +1047,7 @@
 used to verify if the client certificates have not been revoked. This
 requires
 .B TLSCACertificatePath
-parameter to be set.
+parameter to be set. This directive is ignored with GNUtls.
 .B <level>
 can be specified as one of the following keywords:
 .RS
@@ -1017,6 +1061,11 @@
 .B all
 Check the CRL for a whole certificate chain
 .RE
+.TP
+.B TLSCRLFile <filename>
+Specifies a file containing a Certificate Revocation List to be used
+for verifying that certificates have not been revoked. This directive is
+only valid when using GNUtls.
 .SH GENERAL BACKEND OPTIONS
 Options in this section only apply to the configuration file section
 for the specified backend.  They are supported by every
@@ -1030,7 +1079,6 @@
 .BR dnssrv ,
 .BR hdb ,
 .BR ldap ,
-.BR ldbm ,
 .BR ldif ,
 .BR meta ,
 .BR monitor ,
@@ -1060,7 +1108,6 @@
 .BR dnssrv ,
 .BR hdb ,
 .BR ldap ,
-.BR ldbm ,
 .BR ldif ,
 .BR meta ,
 .BR monitor ,
@@ -1073,6 +1120,13 @@
 .BR sql ,
 depending on which backend will serve the database.
 .TP
+.B hidden on | off
+Controls whether the database will be used to answer
+queries. A database that is hidden will never be
+selected to answer any queries, and any suffix configured
+on the database will be ignored in checks for conflicts
+with other databases. By default, hidden is off.
+.TP
 .B lastmod on | off
 Controls whether
 .B slapd
@@ -1298,19 +1352,45 @@
 size limit of regular searches unless extended by the
 .B prtotal
 switch.
+
+The \fBlimits\fP statement is typically used to let an unlimited
+number of entries be returned by searches performed
+with the identity used by the consumer for synchronization purposes
+by means of the RFC 4533 LDAP Content Synchronization protocol
+(see \fBsyncrepl\fP for details).
 .RE
 .TP
 .B maxderefdepth <depth>
 Specifies the maximum number of aliases to dereference when trying to
-resolve an entry, used to avoid infinite alias loops. The default is 1.
+resolve an entry, used to avoid infinite alias loops. The default is 15.
 .TP
+.B mirrormode on | off
+This option puts a replica database into "mirror" mode.  Update
+operations will be accepted from any user, not just the updatedn.  The
+database must already be configured as a syncrepl consumer
+before this keyword may be set. This mode also requires a
+.B serverID
+(see above) to be configured.
+By default, mirrormode is off.
+.TP
+.B monitoring on | off
+This option enables database-specific monitoring in the entry related
+to the current database in the "cn=Databases,cn=Monitor" subtree 
+of the monitor database, if the monitor database is enabled.
+Currently, only the BDB and the HDB databases provide database-specific
+monitoring.
+The default depends on the backend type.
+.TP
 .B overlay <overlay-name>
 Add the specified overlay to this database. An overlay is a piece of
 code that intercepts database operations in order to extend or change
 them. Overlays are pushed onto
 a stack over the database, and so they will execute in the reverse
 of the order in which they were configured and the database itself
-will receive control last of all. Note that all of the database's
+will receive control last of all. See the
+.BR slapd.overlays (5)
+manual page for an overview of the available overlays.
+Note that all of the database's
 regular settings should be configured before any overlay settings.
 .TP
 .B readonly on | off
@@ -1325,7 +1405,7 @@
 .B bindmethod=simple|sasl [binddn=<simple DN>] [credentials=<simple password>]
 .B [saslmech=<SASL mech>] [secprops=<properties>] [realm=<realm>]
 .B [authcId=<authentication ID>] [authzId=<authorization ID>]
-.B [attr[!]=<attr list>]
+.B [attrs[!]=<attr list>]
 .RS
 Specify a replication site for this database.  Refer to the "OpenLDAP 
 Administrator's Guide" for detailed information on setting up a replicated
@@ -1369,7 +1449,7 @@
 An
 .B attr list
 can be given after the 
-.B attr
+.B attrs
 keyword to allow the selective replication of the listed attributes only;
 if the optional 
 .B !
@@ -1379,18 +1459,6 @@
 are (are not) replicated.
 .RE
 .TP
-.B replogfile <filename>
-Specify the name of the replication log file to log changes to.  
-The replication log is typically written by
-.BR slapd (8)
-and read by
-.BR slurpd (8).
-See
-.BR slapd.replog (5)
-for more information.  The specified file should be located
-in a directory with limited read/write/execute access as the replication
-logs may contain sensitive information.
-.TP
 .B restrict <oplist>
 Specify a whitespace separated list of operations that are restricted.
 If defined inside a database specification, restrictions apply only
@@ -1504,18 +1572,17 @@
 .hy 0
 .B syncrepl rid=<replica ID>
 .B provider=ldap[s]://<hostname>[:port]
+.B searchbase=<base DN>
 .B [type=refreshOnly|refreshAndPersist]
 .B [interval=dd:hh:mm:ss]
 .B [retry=[<retry interval> <# of retries>]+]
-.B searchbase=<base DN>
 .B [filter=<filter str>]
-.B [scope=sub|one|base]
+.B [scope=sub|one|base|subord]
 .B [attrs=<attr list>]
 .B [attrsonly]
 .B [sizelimit=<limit>]
 .B [timelimit=<limit>]
 .B [schemachecking=on|off]
-.B [starttls=yes|critical]
 .B [bindmethod=simple|sasl]
 .B [binddn=<dn>]
 .B [saslmech=<mech>]
@@ -1524,6 +1591,14 @@
 .B [credentials=<passwd>]
 .B [realm=<realm>]
 .B [secprops=<properties>]
+.B [starttls=yes|critical]
+.B [tls_cert=<file>]
+.B [tls_key=<file>]
+.B [tls_cacert=<file>]
+.B [tls_cacertdir=<path>]
+.B [tls_reqcert=never|allow|try|demand]
+.B [tls_ciphersuite=<ciphers>]
+.B [tls_crlcheck=none|peer|all]
 .B [logbase=<base DN>]
 .B [logfilter=<filter str>]
 .B [syncdata=default|accesslog|changelog]
@@ -1542,15 +1617,20 @@
 directory service using the 
 .B syncrepl
 replication engine.
+
 .B rid
 identifies the current
 .B syncrepl
 directive within the replication consumer site.
-It is a non-negative integer having no more than three digits.
+It is a non-negative integer not greater than 4095 (limited
+to three hexadecimal digits).
+
 .B provider
 specifies the replication provider site containing the master content
 as an LDAP URI. If <port> is not given, the standard LDAP port number
-(389 or 636) is used. The content of the
+(389 or 636) is used.
+
+The content of the
 .B syncrepl
 replica is defined using a search
 specification as its result set. The consumer
@@ -1558,16 +1638,26 @@
 will send search requests to the provider
 .B slapd
 according to the search specification. The search specification includes
-.B searchbase, scope, filter, attrs, attrsonly, sizelimit,
+.BR searchbase ", " scope ", " filter ", " attrs ", " attrsonly ", " sizelimit ", "
 and
 .B timelimit
 parameters as in the normal search specification. 
 The \fBscope\fP defaults to \fBsub\fP, the \fBfilter\fP defaults to
-\fB(objectclass=*)\fP, and there is no default \fBsearchbase\fP. The
+\fB(objectclass=*)\fP, while there is no default \fBsearchbase\fP. The
 \fBattrs\fP list defaults to \fB"*,+"\fP to return all user and operational
 attributes, and \fBattrsonly\fP is unset by default.
 The \fBsizelimit\fP and \fBtimelimit\fP only
 accept "unlimited" and positive integers, and both default to "unlimited".
+The \fBsizelimit\fP and \fBtimelimit\fP parameters define
+a consumer requested limitation on the number of entries that can be returned
+by the LDAP Content Synchronization operation; as such, it is intended
+to implement partial replication based on the size of the replicated database
+and on the time required by the synchronization.
+Note, however, that any provider-side limits for the replication identity
+will be enforced by the provider regardless of the limits requested
+by the LDAP Content Synchronization operation, much like for any other
+search operation.
+
 The LDAP Content Synchronization protocol has two operation types.
 In the
 .B refreshOnly
@@ -1583,6 +1673,7 @@
 .B searchResultEntry
 to the consumer slapd as the search responses to the persistent
 synchronization search.
+
 If an error occurs during replication, the consumer will attempt to
 reconnect according to the
 .B retry
@@ -1591,18 +1682,18 @@
 for the first 10 times and then retry every 300 seconds for the next 3
 times before stop retrying. The `+' in <# of retries> means indefinite
 number of retries until success.
+
 The schema checking can be enforced at the LDAP Sync
 consumer site by turning on the
 .B schemachecking
-parameter. The default is off.
-The
-.B starttls
-parameter specifies use of the StartTLS extended operation
-to establish a TLS session before Binding to the provider. If the
-StartTLS request fails and the
-.B critical
-argument was used, the session will be aborted. Otherwise the syncrepl
-session continues without TLS.
+parameter. The default is \fBoff\fP.
+Schema checking \fBon\fP means that replicated entries must have
+a structural objectClass, must obey to objectClass requirements
+in terms of required/allowed attributes, and that naming attributes
+and distinguished values must be present.
+As a consequence, schema checking should be \fBoff\fP when partial
+replication is used.
+
 A
 .B bindmethod
 of 
@@ -1635,7 +1726,27 @@
 option. A non default SASL realm can be set with the
 .B realm 
 option.
+The identity used for synchronization by the consumer should be allowed
+to receive an unlimited number of entries in response to a search request.
+The provider, other than allow authentication of the syncrepl identity,
+should grant that identity appropriate access privileges to the data 
+that is being replicated (\fBaccess\fP directive), and appropriate time 
+and size limits.
+This can be accomplished by either allowing unlimited \fBsizelimit\fP
+and \fBtimelimit\fP, or by setting an appropriate \fBlimits\fP statement
+in the consumer's configuration (see \fBsizelimit\fP and \fBlimits\fP
+for details).
 
+The
+.B starttls
+parameter specifies use of the StartTLS extended operation
+to establish a TLS session before Binding to the provider. If the
+.B critical
+argument is supplied, the session will be aborted if the StartTLS request
+fails. Otherwise the syncrepl session continues without TLS. The
+tls_reqcert setting defaults to "demand" and the other TLS settings
+default to the same as the main slapd TLS settings.
+
 Rather than replicating whole entries, the consumer can query logs of
 data modifications. This mode of operation is referred to as \fIdelta
 syncrepl\fP. In addition to the above parameters, the
@@ -1655,12 +1766,10 @@
 .TP
 .B updatedn <dn>
 This option is only applicable in a slave
-database updated using
-.BR slurpd(8). 
+database.
 It specifies the DN permitted to update (subject to access controls)
-the replica (typically, this is the DN
-.BR slurpd (8)
-binds to update the replica).  Generally, this DN
+the replica.  It is only needed in certain push-mode
+replication scenarios.  Generally, this DN
 .I should not
 be the same as the
 .B rootdn 
@@ -1674,182 +1783,9 @@
 
 .SH DATABASE-SPECIFIC OPTIONS
 Each database may allow specific configuration options; they are
-documented separately in the backends' manual pages.
-.SH BACKENDS
-The following backends can be compiled into slapd.
-They are documented in the
-.BR slapd-<backend> (5)
-manual pages.
-.TP
-.B bdb
-This is the recommended primary backend for a normal slapd database.
-It takes care to configure it properly.
-It uses the transactional database interface of the Oracle Berkeley
-DB (BDB) package to store data.
-.TP
-.B config
-This backend is used to manage the configuration of slapd run-time.
-.TP
-.B dnssrv
-This backend is experimental.
-It serves up referrals based upon SRV resource records held in the
-Domain Name System.
-.TP
-.B hdb
-This is a variant of the BDB backend that uses a hierarchical database
-layout which supports subtree renames.
-.TP
-.B ldap
-This backend acts as a proxy to forward incoming requests to another
-LDAP server.
-.TP
-.B ldbm
-This is an easy-to-configure but obsolete database backend. It
-does not offer the data durability features of the BDB and HDB
-backends and hence is deprecated in favor of these robust backends.
-LDBM uses lightweight non-transactional DB interfaces,
-such as those providing by GDBM or Berkeley DB, to store data.
-.TP
-.B ldif
-This database uses the filesystem to build the tree structure
-of the database, using plain ascii files to store data.
-Its usage should be limited to very simple databases, where performance
-is not a requirement.
-.TP
-.B meta
-This backend performs basic LDAP proxying with respect to a set of
-remote LDAP servers. It is an enhancement of the ldap backend.
-.TP
-.B monitor
-This backend provides information about the running status of the slapd
-daemon.
-.TP
-.B null
-Operations in this backend succeed but do nothing.
-.TP
-.B passwd
-This backend is provided for demonstration purposes only.
-It serves up user account information from the system
-.BR passwd (5)
-file.
-.TP
-.B perl
-This backend embeds a
-.BR perl (1)
-interpreter into slapd.
-It runs Perl subroutines to implement LDAP operations.
-.TP
-.B relay
-This backend is experimental.
-It redirects LDAP operations to another database
-in the same server, based on the naming context of the request.
-Its use requires the 
-.B rwm
-overlay (see
-.BR slapo-rwm (5)
-for details) to rewrite the naming context of the request.
-It is primarily intended to implement virtual views on databases
-that actually store data.
-.TP
-.B shell
-This backend executes external programs to implement LDAP operations.
-It is primarily intended to be used in prototypes.
-.TP
-.B sql
-This backend is experimental.
-It services LDAP requests from an SQL database.
-.SH OVERLAYS
-The following overlays can be compiled into slapd.
-They are documented in the
-.BR slapo-<overlay> (5)
-manual pages.
-.TP
-.B accesslog
-Access Logging.
-This overlay can record accesses to a given backend database on another
-database.
-.TP
-.B auditlog
-Audit Logging.
-This overlay records changes on a given backend database to an LDIF log
-file.
-By default it is not built.
-.TP
-.B chain
-Chaining.
-This overlay allows automatic referral chasing when a referral would
-have been returned, either when configured by the server or when 
-requested by the client.
-.TP
-.B denyop
-Deny Operation.
-This overlay allows selected operations to be denied, similar to the
-\fBrestrict\fP option.
-.TP
-.B dyngroup
-Dynamic Group.
-This is a demo overlay which extends the Compare operation to detect
-members of a dynamic group.
-It has no effect on any other operations.
-.TP
-.B dynlist
-Dynamic List.
-This overlay allows expansion of dynamic groups and more.
-.TP
-.B lastmod
-Last Modification.
-This overlay maintains a service entry in the database with the DN,
-modification type, modifiersName and modifyTimestamp of the last write
-operation performed on that database.
-.TP
-.B pcache
-Proxycache.
-This overlay allows caching of LDAP search requests in a local database.
-It is most often used with the ldap or meta backends.
-.TP
-.B ppolicy
-Password Policy.
-This overlay provides a variety of password control mechanisms,
-e.g. password aging, password reuse and duplication control, mandatory
-password resets, etc.
-.TP
-.B refint
-Referential Integrity.
-This overlay can be used with a backend database such as
-.BR slapd-bdb (5)
-to maintain the cohesiveness of a schema which utilizes reference
-attributes.
-.TP
-.B retcode
-Return Code.
-This overlay is useful to test the behavior of clients when
-server-generated erroneous and/or unusual responses occur.
-.TP
-.B rwm
-Rewrite/remap.
-This overlay is experimental.
-It performs basic DN/data rewrite and
-objectClass/attributeType mapping.
-.TP
-.B syncprov
-Syncrepl Provider.
-This overlay implements the provider-side support for
-.B syncrepl
-replication, including persistent search functionality.
-.TP
-.B translucent
-Translucent Proxy.
-This overlay can be used with a backend database such as
-.BR slapd-bdb (5)
-to create a "translucent proxy".
-Content of entries retrieved from a remote LDAP server can be partially
-overridden by the database.
-.TP
-.B unique
-Attribute Uniqueness.
-This overlay can be used with a backend database such as
-.BR slapd-bdb (5)
-to enforce the uniqueness of some or all attributes within a subtree.
+documented separately in the backends' manual pages. See the
+.BR slapd.backends (5)
+manual page for an overview of available backends.
 .SH EXAMPLES
 .LP
 Here is a short example of a configuration file:
@@ -1857,13 +1793,13 @@
 .RS
 .nf
 include   SYSCONFDIR/schema/core.schema
-pidfile   LOCALSTATEDIR/slapd.pid
+pidfile   LOCALSTATEDIR/run/slapd.pid
 
 # Subtypes of "name" (e.g. "cn" and "ou") with the
 # option ";x-hidden" can be searched for/compared,
 # but are not shown.  See \fBslapd.access\fP(5).
 attributeoptions x-hidden lang-
-access to attr=name;x-hidden by * =cs
+access to attrs=name;x-hidden by * =cs
 
 # Protect passwords.  See \fBslapd.access\fP(5).
 access    to attrs=userPassword  by * auth
@@ -1898,21 +1834,10 @@
 default slapd configuration file
 .SH SEE ALSO
 .BR ldap (3),
-.BR slapd\-bdb (5),
-.BR slapd\-dnssrv (5),
-.BR slapd\-hdb (5),
-.BR slapd\-ldap (5),
-.BR slapd\-ldbm (5),
-.BR slapd\-ldif (5),
-.BR slapd\-meta (5),
-.BR slapd\-monitor (5),
-.BR slapd\-null (5),
-.BR slapd\-passwd (5),
-.BR slapd\-perl (5),
-.BR slapd\-relay (5),
-.BR slapd\-shell (5),
-.BR slapd\-sql (5),
+.BR slapd\-config (5),
 .BR slapd.access (5),
+.BR slapd.backends (5),
+.BR slapd.overlays (5),
 .BR slapd.plugin (5),
 .BR slapd.replog (5),
 .BR slapd (8),
@@ -1923,27 +1848,8 @@
 .BR slapdn (8),
 .BR slapindex (8),
 .BR slappasswd (8),
-.BR slaptest (8),
-.BR slurpd (8).
-
-Known overlays are documented in
-.BR slapo\-accesslog (5),
-.BR slapo\-auditlog (5),
-.BR slapo\-chain (5),
-.BR slapo\-dynlist (5),
-.BR slapo\-lastmod (5),
-.BR slapo\-pcache (5),
-.BR slapo\-ppolicy (5),
-.BR slapo\-refint (5),
-.BR slapo\-retcode (5),
-.BR slapo\-rwm (5),
-.BR slapo\-syncprov (5),
-.BR slapo\-translucent (5),
-.BR slapo\-unique (5).
+.BR slaptest (8).
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Copied: openldap/trunk/doc/man/man5/slapd.overlays.5 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man5/slapd.overlays.5)
===================================================================
--- openldap/trunk/doc/man/man5/slapd.overlays.5	                        (rev 0)
+++ openldap/trunk/doc/man/man5/slapd.overlays.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,148 @@
+.TH SLAPD.OVERLAYS 5 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" Copyright 2006-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd.overlays.5,v 1.4.2.2 2007/08/31 23:13:53 quanah Exp $
+.SH NAME
+slapd.overlays \- overlays for slapd, the stand-alone LDAP daemon
+.SH DESCRIPTION
+The
+.BR slapd (8)
+daemon can use a variety of different overlays to alter or extend
+the normal behavior of a database backend.
+Overlays may be compiled statically into slapd, or when module support
+is enabled, they may be dynamically loaded. Most of the overlays
+are only allowed to be configured on individual databases, but some
+may also be configured globally.
+
+Configuration options for each overlay are documented separately in the
+corresponding
+.BR slapo-<overlay> (5)
+manual pages.
+.TP
+.B accesslog
+Access Logging.
+This overlay can record accesses to a given backend database on another
+database.
+.TP
+.B auditlog
+Audit Logging.
+This overlay records changes on a given backend database to an LDIF log
+file.
+By default it is not built.
+.TP
+.B chain
+Chaining.
+This overlay allows automatic referral chasing when a referral would
+have been returned, either when configured by the server or when 
+requested by the client.
+.TP
+.B constraint
+Constraint.
+This overlay enforces a regular expression constraint on all values
+of specified attributes. It is used to enforce a more rigorous
+syntax when the underlying attribute syntax is too general.
+.TP
+.B dds
+Dynamic Directory Services.
+This overlay supports dynamic objects, which have a limited life after
+which they expire and are automatically deleted.
+.TP
+.B dyngroup
+Dynamic Group.
+This is a demo overlay which extends the Compare operation to detect
+members of a dynamic group.
+It has no effect on any other operations.
+.TP
+.B dynlist
+Dynamic List.
+This overlay allows expansion of dynamic groups and more.
+.TP
+.B pcache
+Proxycache.
+This overlay allows caching of LDAP search requests in a local database.
+It is most often used with the
+.BR slapd-ldap (5)
+or
+.BR slapd-meta (5)
+backends.
+.TP
+.B ppolicy
+Password Policy.
+This overlay provides a variety of password control mechanisms,
+e.g. password aging, password reuse and duplication control, mandatory
+password resets, etc.
+.TP
+.B refint
+Referential Integrity.
+This overlay can be used with a backend database such as
+.BR slapd-bdb (5)
+to maintain the cohesiveness of a schema which utilizes reference
+attributes.
+.TP
+.B retcode
+Return Code.
+This overlay is useful to test the behavior of clients when
+server-generated erroneous and/or unusual responses occur.
+.TP
+.B rwm
+Rewrite/remap.
+This overlay is experimental.
+It performs basic DN/data rewrite and
+objectClass/attributeType mapping.
+.TP
+.B syncprov
+Syncrepl Provider.
+This overlay implements the provider-side support for
+.B syncrepl
+replication, including persistent search functionality.
+.TP
+.B translucent
+Translucent Proxy.
+This overlay can be used with a backend database such as
+.BR slapd-bdb (5)
+to create a "translucent proxy".
+Content of entries retrieved from a remote LDAP server can be partially
+overridden by the database.
+.TP
+.B unique
+Attribute Uniqueness.
+This overlay can be used with a backend database such as
+.BR slapd-bdb (5)
+to enforce the uniqueness of some or all attributes within a subtree.
+.TP
+.B valsort
+Value Sorting.
+This overlay can be used to enforce a specific order for the values
+of an attribute when it is returned in a search.
+.SH FILES
+.TP
+ETCDIR/slapd.conf
+default slapd configuration file
+.TP
+ETCDIR/slapd.d
+default slapd configuration directory
+.SH SEE ALSO
+.BR ldap (3),
+.BR slapo\-accesslog (5),
+.BR slapo\-auditlog (5),
+.BR slapo\-chain (5),
+.BR slapo\-constraint (5),
+.BR slapo\-dds (5),
+.BR slapo\-dyngroup (5),
+.BR slapo\-dynlist (5),
+.BR slapo\-pcache (5),
+.BR slapo\-ppolicy (5),
+.BR slapo\-refint (5),
+.BR slapo\-retcode (5),
+.BR slapo\-rwm (5),
+.BR slapo\-syncprov (5),
+.BR slapo\-translucent (5),
+.BR slapo\-unique (5).
+.BR slapo\-valsort (5).
+.BR slapd\-config (5),
+.BR slapd.conf (5),
+.BR slapd.backends (5),
+.BR slapd (8).
+"OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Modified: openldap/trunk/doc/man/man5/slapd.plugin.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd.plugin.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd.plugin.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -10,9 +10,7 @@
 .BR slapd.conf (5)
 file contains configuration information for the
 .BR slapd (8)
-daemon. This configuration file is also used by the
-.BR slurpd (8)
-replication daemon and by the SLAPD tools
+daemon. This configuration file is also used by the SLAPD tools
 .BR slapadd (8),
 .BR slapcat (8),
 and
@@ -94,7 +92,7 @@
 .TP
 .B pluginlog <file>
 Specify an alternative path for the plugin log file (default is
-LOCALSTATEDIR/error).
+LOCALSTATEDIR/errors).
 .TP
 .B modulepath <pathspec>
 This statement sets the module load path for dynamically loadable 
@@ -114,12 +112,12 @@
 .TP
 ETCDIR/slapd.conf
 default slapd configuration file
+.TP
+LOCALSTATEDIR/errors
+default plugin log file
 .SH SEE ALSO
 .BR slapd (8),
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.
+.so ../Project

Deleted: openldap/trunk/doc/man/man5/slapd.replog.5
===================================================================
--- openldap/trunk/doc/man/man5/slapd.replog.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapd.replog.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,170 +0,0 @@
-.TH SLAPD.REPLOG 5 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapd.replog.5,v 1.12.2.4 2007/01/02 21:43:45 kurt Exp $
-.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
-.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.SH NAME
-slapd.replog \- slapd replication log format
-.SH SYNOPSIS
-slapd.replog
-slapd.replog.lock
-.SH DESCRIPTION
-.LP
-The file slapd.replog is produced by the stand-alone LDAP daemon,
-.BR slapd (8),
-when changes are made to its local database that are to be
-propagated to one or more replica
-.IR slapd s.
-The file consists of
-zero or more records, each one corresponding to a change, addition,
-or deletion from the
-.I slapd
-database.  The file is meant to be read
-and processed by
-.BR slurpd (8),
-the stand-alone LDAP update replication daemon.  The records are
-separated by a blank line.  Each record has the following format.
-.LP
-The record begins with one or more lines indicating the replicas
-to which the change is to be propagated:
-.LP
-.nf
-	replica: <hostname[:portnumber]>
-.fi
-.LP
-Next, the time the change took place given, as the number of seconds since
-00:00:00 GMT, Jan. 1, 1970, with an optional decimal extension, in order
-to make times unique.  Note that slapd does not make times unique, but
-slurpd makes all times unique in its copies of the replog files.
-.LP
-.nf
-	time: <integer[.integer]>
-.fi
-.LP
-Next, the distinguished name of the entry being changed is given:
-.LP
-.nf
-	dn: <distinguishedname>
-.fi
-.LP
-Next, the type of change being made is given:
-.LP
-.nf
-	changetype: <[modify|add|delete|modrdn]>
-.fi
-.LP
-Finally, the change information itself is given, the format of which
-depends on what kind of change was specified above.  For a \fIchangetype\fP
-of \fImodify\fP, the format is one or more of the following:
-.LP
-.nf
-	add: <attributetype>
-	<attributetype>: <value1>
-	<attributetype>: <value2>
-	...
-	-
-.fi
-.LP
-Or, for a replace modification:
-.LP
-.nf
-	replace: <attributetype>
-	<attributetype>: <value1>
-	<attributetype>: <value2>
-	...
-	-
-.fi
-.LP
-Or, for a delete modification:
-.LP
-.nf
-	delete: <attributetype>
-	<attributetype>: <value1>
-	<attributetype>: <value2>
-	...
-	-
-.fi
-.LP
-If no \fIattributetype\fP lines are given, the entire attribute is to be
-deleted.
-.LP
-For a \fIchangetype\fP of \fIadd\fP, the format is:
-.LP
-.nf
-	<attributetype1>: <value1>
-	<attributetype1>: <value2>
-	...
-	<attributetypeN>: <value1>
-	<attributetypeN>: <value2>
-.fi
-.LP
-For a \fIchangetype\fP of \fImodrdn\fP, the format is:
-.LP
-.nf
-	newrdn: <newrdn>
-	deleteoldrdn: 0 | 1
-.fi
-.LP
-where a value of 1 for deleteoldrdn means to delete the values
-forming the old rdn from the entry, and a value of 0 means to
-leave the values as non-distinguished attributes in the entry.
-.LP
-For a \fIchangetype\fP of \fIdelete\fP, no additional information
-is needed in the record.
-.LP
-The format of the values is the LDAP Directory Interchange Format
-described in
-.BR ldif (5).
-.LP
-Access to the \fIslapd.replog\fP file is synchronized through the
-use of
-.BR flock (3)
-on the file \fIslapd.replog.lock\fP.  Any process
-reading or writing this file should obey this locking convention.
-.SH EXAMPLE
-The following sample \fIslapd.replog\fP file contains information
-on one of each type of change.
-.LP
-.nf
-	replica: truelies.rs.itd.umich.edu
-	replica: judgmentday.rs.itd.umich.edu
-	time: 797612941
-	dn: cn=Babs Jensen,dc=example,dc=com
-	changetype: add
-	objectclass: person
-	cn: babs
-	cn: babs jensen
-	sn: jensen
-	 
-	replica: truelies.rs.itd.umich.edu
-	replica: judgmentday.rs.itd.umich.edu
-	time: 797612973
-	dn: cn=Babs Jensen,dc=example,dc=com
-	changetype: modify
-	add: description
-	description: the fabulous babs
-	 
-	replica: truelies.rs.itd.umich.edu
-	replica: judgmentday.rs.itd.umich.edu
-	time: 797613020
-	dn: cn=Babs Jensen,dc=example,dc=com
-	changetype: modrdn
-	newrdn: cn=Barbara J Jensen
-	deleteoldrdn: 0
-.fi
-.SH FILES
-.TP
-slapd.replog
-slapd replication log file
-.TP
-slapd.replog.lock
-lockfile for slapd.replog
-.SH SEE ALSO
-.BR ldap (3),
-.BR ldif (5),
-.BR slapd (8),
-.BR slurpd (8)
-.SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  

Modified: openldap/trunk/doc/man/man5/slapo-accesslog.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-accesslog.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-accesslog.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH SLAPO-ACCESSLOG 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 2005-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-accesslog.5,v 1.1.2.9 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-accesslog.5,v 1.9.2.4 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-accesslog \- Access Logging overlay
+slapo-accesslog \- Access Logging overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -25,9 +25,9 @@
 .TP
 .B logdb <suffix>
 Specify the suffix of a database to be used for storing the log records.
-The specified database must have already been configured in a prior section
-of the config file, and it must have a rootDN configured. The access controls
-on the log database should prevent general write access. The suffix entry
+The specified database must be defined elsewhere in the configuration.
+The access controls
+on the log database should prevent general access. The suffix entry
 of the log database will be created automatically by this overlay. The log
 entries will be generated as the immediate children of the suffix entry.
 .TP
@@ -55,6 +55,12 @@
 the entry matches the filter, the old contents of the entry will be
 logged along with the current request.
 .TP
+.B logoldattr <attr> ...
+Specify a list of attributes whose old contents are always logged in
+Modify and ModRDN requests. Usually only the contents of attributes that were
+actually modified will be logged; by default no old attributes are logged
+for ModRDN requests.
+.TP
 .B logpurge <age> <interval>
 Specify the maximum age for log entries to be retained in the database,
 and how often to scan the database for old entries. Both the
@@ -90,17 +96,19 @@
 .LP
 .nf
 	database bdb
-	suffix cn=log
-	\...
-	index reqStart eq
-
-	database bdb
 	suffix dc=example,dc=com
 	\...
 	overlay accesslog
 	logdb cn=log
 	logops writes reads
 	logold (objectclass=person)
+
+	database bdb
+	suffix cn=log
+	\...
+	index reqStart eq
+	access to *
+	  by dn.base="cn=admin,dc=example,dc=com" read
 .fi
 
 .SH SCHEMA
@@ -110,7 +118,7 @@
 This schema is specifically designed for
 .B accesslog
 auditing and is not intended to be used otherwise.  It is also
-noted that the schema describe here is
+noted that the schema described here is
 .I a work in
 .IR progress ,
 and hence subject to change without notice.
@@ -355,7 +363,7 @@
     DESC 'ModRDN operation'
     SUP auditWriteObject STRUCTURAL
     MUST ( reqNewRDN $ reqDeleteOldRDN )
-    MAY reqNewSuperior )
+    MAY ( reqNewSuperior $ reqOld ) )
 .RE
 .P
 The
@@ -374,6 +382,14 @@
 .B reqNewSuperior
 attribute carries the DN of the new parent entry if the request specified
 the new parent.
+The
+.B reqOld
+attribute is only populated if the entry being modified matches the
+configured
+.B logold
+filter and contains attributes in the
+.B logoldattr
+list.
 
 .LP
 .RS 4

Modified: openldap/trunk/doc/man/man5/slapo-auditlog.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-auditlog.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-auditlog.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH SLAPO-AUDITLOG 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 2005-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-auditlog.5,v 1.1.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-auditlog.5,v 1.3.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-auditlog \- Audit Logging overlay
+slapo-auditlog \- Audit Logging overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION

Modified: openldap/trunk/doc/man/man5/slapo-chain.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-chain.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-chain.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH SLAPO-CHAIN 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation, All Rights Reserved.
 .\" Copying restrictions apply.  See the COPYRIGHT file.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-chain.5,v 1.1.2.8 2007/09/06 18:21:41 ando Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-chain.5,v 1.10.2.3 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-chain \- chain overlay
+slapo-chain \- chain overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -13,15 +13,15 @@
 .BR slapd (8)
 allows automatic referral chasing.
 Any time a referral is returned (except for bind operations),
-it chased by using an instance of the ldap backend.
+it is chased by using an instance of the ldap backend.
 If operations are performed with an identity (i.e. after a bind),
 that identity can be asserted while chasing the referrals 
 by means of the \fIidentity assertion\fP feature of back-ldap
 (see
 .BR slapd-ldap (5)
 for details), which is essentially based on the
-.B proxyAuthz
-control (see \fIdraft-weltman-ldapv3-proxy\fP for details.)
+.B proxied authorization
+control [RFC 4370].
 Referral chasing can be controlled by the client by issuing the 
 \fBchaining\fP control
 (see \fIdraft-sermersheim-ldap-chaining\fP for details.)
@@ -40,7 +40,7 @@
 instantiated by the overlay may assume a special meaning when used 
 in conjunction with this overlay.  They are described in
 .BR slapd-ldap (5),
-and they also need be prefixed by
+and they also need to be prefixed by
 .BR chain\- .
 .TP
 .B overlay chain

Copied: openldap/trunk/doc/man/man5/slapo-constraint.5 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man5/slapo-constraint.5)
===================================================================
--- openldap/trunk/doc/man/man5/slapo-constraint.5	                        (rev 0)
+++ openldap/trunk/doc/man/man5/slapo-constraint.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,57 @@
+.TH SLAPO-CONSTRAINT 5 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" Copyright 2005-2006 Hewlett-Packard Company
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+slapo-constraint \- Attribute Constraint Overlay to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The constraint overlay is used to enforce a regular expression
+constraint on all values of specified attributes. Attributes can
+have multiple constraints placed upon them, and all must be satisfied
+when modifying an attribute value under constraint.
+.LP
+This overlay is intended to be used to force syntactic regularity upon
+certain string represented data which have well known canonical forms,
+like telephone numbers, post codes, FQDNs, etc.
+.SH CONFIGURATION
+This
+.B slapd.conf
+option applies to the constraint overlay.
+It should appear after the
+.B overlay
+directive.
+.TP
+.B constraint_attribute <attribute_name> <type> <value>
+Specifies the constraint which should apply to the attribute named as
+the first parameter.
+At the moment only one type of constraint is supported -
+.B
+regex.
+The parameter following the
+.B
+regex
+type is a Unix style regular expression (See
+.B
+regex(7))
+
+Any attempt to add or modify an attribute named as part of the
+constraint overlay specification which does not fit the regular
+expression constraint listed will fail with a
+LDAP_CONSTRAINT_VIOLATION error.
+.SH EXAMPLES
+.B
+constraint_attribute mail regex ^[:alnum:]+ at mydomain.com$
+
+A specification like the above would reject any
+.B
+mail
+attribute which did not look like
+.B
+<alpha-numeric string>@mydomain.com
+.SH FILES
+.TP
+ETCDIR/slapd.conf
+default slapd configuration file
+.SH SEE ALSO
+.BR slapd.conf (5).

Copied: openldap/trunk/doc/man/man5/slapo-dds.5 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man5/slapo-dds.5)
===================================================================
--- openldap/trunk/doc/man/man5/slapo-dds.5	                        (rev 0)
+++ openldap/trunk/doc/man/man5/slapo-dds.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,266 @@
+.TH SLAPO-DDS 5 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" Copyright 2005-2007 The OpenLDAP Foundation, All Rights Reserved.
+.\" Copying restrictions apply.  See the COPYRIGHT file.
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-dds.5,v 1.1.2.3 2007/08/31 23:13:53 quanah Exp $
+.SH NAME
+slapo-dds \- Dynamic Directory Services overlay to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The
+.B dds
+overlay to
+.BR slapd (8)
+implements dynamic objects as per RFC 2589.
+The name 
+.B dds
+stands for
+Dynamic Directory Services.
+It allows to define dynamic objects, characterized by the
+.B dynamicObject
+objectClass.
+
+Dynamic objects have a limited lifetime, determined by a time-to-live
+(TTL) that can be refreshed by means of a specific
+.B refresh
+extended operation.
+This operation allows to set the Client Refresh Period (CRP),
+namely the period between refreshes that is required to preserve the
+dynamic object from expiration.
+The expiration time is computed by adding the requested TTL to the 
+current time.
+When dynamic objects reach the end of their lifetime without being
+further refreshed, they are automatically deleted.
+There is no guarantee of immediate deletion, so clients should not count
+on it.
+
+Dynamic objects can have subordinates, provided these also are dynamic
+objects.
+RFC 2589 does not specify what the behavior of a dynamic directory
+service should be when a dynamic object with (dynamic) subordinates
+expires.
+In this implementation, the lifetime of dynamic objects with subordinates
+is prolonged until all the dynamic subordinates expire.
+
+
+This 
+.BR slapd.conf (5)
+directive adds the 
+.B dds
+overlay to the current database:
+
+.TP
+.B overlay dds
+
+.LP
+The 
+.B dds
+overlay may be used with any backend that implements the 
+.BR add ,
+.BR modify ,
+.BR search ,
+and
+.BR delete
+operations.
+Since its use may result in many internal entry lookups, adds
+and deletes, it should be best used in conjunction with backends
+that have reasonably good write performances.
+
+.LP 
+The config directives that are specific to the
+.B dds
+overlay are prefixed by
+.BR dds\- ,
+to avoid potential conflicts with directives specific to the underlying 
+database or to other stacked overlays.
+
+.TP
+.B dds\-max\-ttl <ttl>
+Specifies the max TTL value.
+This is also the default TTL newly created
+dynamic objects receive, unless
+.B dds\-default\-ttl
+is set.
+When the client with a refresh extended operation requests a TTL higher
+than it, sizeLimitExceeded is returned.
+This value must be between 86400 (1 day, the default) and 31557600
+(1 year plus 6 hours, as per RFC 2589).
+
+.TP
+.B dds\-min\-ttl <ttl>
+Specifies the min TTL value; clients requesting a lower TTL by means
+of the refresh extended operation actually obtain this value as CRP.
+If set to 0 (the default), no lower limit is set.
+
+.TP
+.B dds\-default\-ttl <ttl>
+Specifies the default TTL value that newly created dynamic objects get.
+If set to 0 (the default), the
+.B dds\-max\-ttl
+is used.
+
+.TP
+.B dds\-interval <ttl>
+Specifies the interval between expiration checks; defaults to 1 hour.
+
+.TP
+.B dds\-tolerance <ttl>
+Specifies an extra time that is added to the timer that actually wakes up
+the thread that will delete an expired dynamic object.
+So the nominal lifetime of the entry is that specified in the
+.B entryTtl
+attribute, but its lifetime will actually be
+.BR "entryTtl + tolerance" .
+Note that there is no guarantee that the lifetime of a dynamic object
+will be
+.I exactly
+the requested TTL; due to implementation details, it may be longer, which 
+is allowed by RFC 2589.
+By default, tolerance is 0.
+
+.TP
+.B dds\-max\-dynamicObjects <num>
+Specifies the maximum number of dynamic objects that can simultaneously exist
+within a naming context.
+This allows to limit the amount of resources (mostly in terms of
+run-queue size) that are used by dynamic objects.
+By default, no limit is set.
+
+.TP
+.B dds-state {TRUE|false}
+Specifies if the Dynamic Directory Services feature is enabled or not.
+By default it is; however, a proxy does not need to keep track of dynamic
+objects itself, it only needs to inform the frontend that support for
+dynamic objects is available.
+
+.SH ACCESS CONTROL
+The
+.B dds
+overlay restricts the refresh operation by requiring 
+.B manage
+access to the 
+.B entryTtl
+attribute (see
+.BR slapd.access (5)
+for details about the 
+.B manage
+access privilege).
+Since the
+.B entryTtl
+is an operational, NO-USER-MODIFICATION attribute, no direct write access
+to it is possible.
+So the 
+.B dds
+overlay turns refresh extended operation into an internal modification to
+the value of the
+.B entryTtl
+attribute with the
+.B manageDIT
+control set.
+
+RFC 2589 recommends that anonymous clients should not be allowed to refresh
+a dynamic object.
+This can be implemented by appropriately crafting access control to obtain 
+the desired effect.
+
+Example: restrict refresh to authenticated clients
+
+.RS
+.nf
+access to attrs=entryTtl
+	by users manage
+	by * read
+
+.fi
+.RE
+Example: restrict refresh to the creator of the dynamic object
+
+.RS
+.nf
+access to attrs=entryTtl
+	by dnattr=creatorsName manage
+	by * read
+
+.fi
+.RE
+Another suggested usage of dynamic objects is to implement dynamic meetings;
+in this case, all the participants to the meeting are allowed to refresh 
+the meeting object, but only the creator can delete it (otherwise it will
+be deleted when the TTL expires)
+
+Example: assuming \fIparticipant\fP is a valid DN-valued attribute, 
+allow users to start a meeting and to join it; restrict refresh 
+to the participants; restrict delete to the creator
+
+.RS
+.nf
+access to dn.base="cn=Meetings"
+		attrs=children
+	by users write
+
+access to dn.onelevel="cn=Meetings"
+		attrs=entry
+	by dnattr=creatorsName write
+	by * read
+
+access to dn.onelevel="cn=Meetings"
+		attrs=participant
+	by dnattr=creatorsName write
+	by users selfwrite
+	by * read
+
+access to dn.onelevel="cn=Meetings"
+		attrs=entryTtl
+	by dnattr=participant manage
+	by * read
+
+.fi
+.RE
+
+.SH REPLICATION
+This implementation of RFC 2589 provides a restricted interpretation of how
+dynamic objects replicate.  Only the master takes care of handling dynamic
+object expiration, while replicas simply see the dynamic object as a plain
+object.
+
+When replicating these objects, one needs to explicitly exclude the 
+.B dynamicObject
+class and the
+.B entryTtl
+attribute.
+This implementation of RFC 2589 introduces a new operational attribute,
+.BR entryExpireTimestamp ,
+that contains the expiration timestamp.  This must be excluded from 
+replication as well.
+
+The quick and dirty solution is to set 
+.B schemacheck=off
+in the syncrepl configuration
+and, optionally, exclude the operational attributes from replication, using
+
+.RS
+.nf
+syncrepl ...
+	exattrs=entryTtl,entryExpireTimestamp
+.fi
+.RE
+
+In any case the overlay must be either statically built in or run-time loaded 
+by the consumer, so that it is aware of the 
+.B entryExpireTimestamp
+operational attribute; however, it must not be configured in the shadow 
+database.
+Currently, there is no means to remove the 
+.B dynamicObject
+class from the entry; this may be seen as a feature, since it allows to see
+the dynamic properties of the object.
+
+.SH FILES
+.TP
+ETCDIR/slapd.conf
+default slapd configuration file
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8).
+.SH AUTHOR
+Implemented by Pierangelo Masarati.

Copied: openldap/trunk/doc/man/man5/slapo-dyngroup.5 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man5/slapo-dyngroup.5)
===================================================================
--- openldap/trunk/doc/man/man5/slapo-dyngroup.5	                        (rev 0)
+++ openldap/trunk/doc/man/man5/slapo-dyngroup.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,48 @@
+.TH SLAPO-DYNGROUP 5 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" Copyright 2005-2007 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-dyngroup.5,v 1.2.2.1 2007/08/31 23:13:53 quanah Exp $
+.SH NAME
+slapo-dyngroup \- Dynamic Group overlay to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The Dynamic Group overlay allows clients to use LDAP Compare operations
+to test the membership of a dynamic group the same way they would check
+against a static group. Compare operations targeting a group's static
+member attribute will be intercepted and tested against the configured
+dynamic group's URL attribute.
+.LP
+Note that this intercept only happens if the actual
+Compare operation does not return a LDAP_COMPARE_TRUE result. So if a
+group has both static and dynamic members, the static member list will
+be checked first.
+.SH CONFIGURATION
+This
+.B slapd.conf
+option applies to the Dynamic Group overlay.
+It should appear after the
+.B overlay
+directive.
+.TP
+.B attrpair <memberAttr> <URLattr>
+Specify the attributes to be compared. A compare operation on the
+.I memberAttr
+will cause the
+.I URLattr
+to be evaluated for the result.
+.SH EXAMPLES
+.nf
+  database bdb
+  ...
+  overlay dyngroup
+  attrpair member memberURL
+.fi
+.SH FILES
+.TP
+ETCDIR/slapd.conf
+default slapd configuration file
+.SH SEE ALSO
+.BR slapd.conf (5).
+.SH AUTHOR
+Howard Chu

Modified: openldap/trunk/doc/man/man5/slapo-dynlist.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-dynlist.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-dynlist.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH SLAPO-DYNLIST 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 1998-2007 The OpenLDAP Foundation, All Rights Reserved.
 .\" Copying restrictions apply.  See the COPYRIGHT file.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-dynlist.5,v 1.1.2.9 2007/08/06 15:49:54 ghenry Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-dynlist.5,v 1.7.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-dynlist \- Dynamic List overlay
+slapo-dynlist \- Dynamic List overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -45,7 +45,7 @@
 .LP
 This
 .B slapd.conf
-configuration option is define for the dynlist overlay. It may have multiple 
+configuration option is defined for the dynlist overlay. It may have multiple 
 occurrences, and it must appear after the
 .B overlay
 directive.
@@ -89,6 +89,18 @@
 with well-defined patterns, one should consider adding a proxycache
 later on in the overlay stack.
 
+.SH AUTHORIZATION
+By default the expansions are performed using the identity of the current
+LDAP user. This identity may be overridden by setting the
+.B dgIdentity
+attribute to the DN of another LDAP user. In that case the dgIdentity
+will be used when expanding the URIs in the object. Setting the dgIdentity
+to a zero-length string will cause the expansions to be performed
+anonymously. Note that the dgIdentity attribute is defined in the
+.B dyngroup
+schema, and this schema must be loaded before the dgIdentity
+authorization feature may be used.
+
 .SH EXAMPLE
 This example collects all the email addresses of a database into a single
 entry; first of all, make sure that slapd.conf contains the directives:
@@ -135,6 +147,18 @@
 .fi
 .LP
 
+A dynamic group with dgIdentity authorization could be created with an
+entry like
+.LP
+.nf
+    dn: cn=Dynamic Group,ou=Groups,dc=example,dc=com
+    objectClass: groupOfURLs
+    objectClass: dgIdentityAux
+    cn: Dynamic Group
+    memberURL: ldap:///ou=People,dc=example,dc=com??sub?(objectClass=person)
+    dgIdentity: cn=Group Proxy,ou=Services,dc=example,dc=com
+.fi
+
 .SH FILES
 .TP
 ETCDIR/slapd.conf

Deleted: openldap/trunk/doc/man/man5/slapo-lastmod.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-lastmod.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-lastmod.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,185 +0,0 @@
-.\" Copyright 2004-2007 The OpenLDAP Foundation All Rights Reserved.
-.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.TH SLAPO_LASTMOD 5 "RELEASEDATE" "OpenLDAP LDVERSION"
-.SH NAME
-slapo-lastmod \- Last Modification overlay
-.SH SYNOPSIS
-ETCDIR/slapd.conf
-.SH DESCRIPTION
-.LP
-The 
-.B lastmod
-overlay creates a service entry rooted at the suffix of the database
-it's stacked onto, which holds the DN, the modification type,
-the modifiersName and the modifyTimestamp of the last write operation
-performed on that database.
-The lastmod overlay cannot be used when the "lastmod" feature
-is disabled, i.e. "lastmod off" is used.
-.P
-All operations targeted at the DN of the lastmod entry are rejected,
-except reads, i.e. searches with 
-.B base
-scope.
-Regular operations are ignored, unless they result in writing; then,
-in case of success, the lastmod entry is updated accordingly,
-if possible.
-
-.SH CONFIGURATION
-These 
-.B slapd.conf
-configuration options apply to the lastmod overlay. They must appear
-after the
-.B overlay
-directive.
-.TP
-.B lastmod-rdnvalue <RDN value>
-Specify the value of the RDN used for the service entry.  By default
-.I Lastmod
-is used.
-.TP
-.B lastmod-enabled {yes|no}
-Specify whether the overlay must be enabled or not at startup.
-By default, the overlay is enabled; however, by changing the boolean
-value of the attribute
-.IR lastmodEnabled ,
-one can affect the status of the overlay.
-This is useful, for instance, to inhibit the overlay from keeping track
-of large bulk loads or deletions.
-
-.SH OBJECT CLASS
-The 
-.B lastmod
-overlay depends on the
-.B lastmod
-objectClass.  The definition of that class is as follows:
-.LP
-.RS 4
-( 1.3.6.1.4.1.4203.666.3.13 "
-    NAME 'lastmod'
-    DESC 'OpenLDAP per-database last modification monitoring'
-    STRUCTURAL
-    SUP top
-    MUST ( cn $ lastmodDN $ lastmodType )
-    MAY ( description $ seeAlso ) )
-.RE
-
-.SH ATTRIBUTES
-.P
-Each one of the sections below details the meaning and use of a particular
-attribute of this
-.B lastmod
-objectClass.
-Most of the attributes that are specific to the lastmod objectClass are
-operational, since they can logically be altered only by the DSA.
-The most notable exception is the
-.I lastmodEnabled
-attributeType, which can be altered via protocol to change the status
-of the overlay.
-.P
-
-.B lastmodEnabled
-.P
-This attribute contains a boolean flag that determines the status
-of the overlay.  It can be altered via protocol by issuing a modify
-operation that replaces the value of the attribute.
-.LP
-.RS 4
-(  1.3.6.1.4.1.4203.666.1.30
-   NAME 'lastmodEnabled'
-   DESC 'Lastmod overlay state'
-   SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
-   EQUALITY booleanMatch
-   SINGLE-VALUE )
-.RE
-
-.SH OPERATIONAL ATTRIBUTES
-.P
-Each one of the sections below details the meaning and use of a particular
-attribute of this
-.B lastmod
-objectClass.
-Most of the attributes that are specific to the lastmod objectClass are
-operational, since they can logically be altered only by the DSA.
-.P
-
-.B lastmodDN
-.P
-This attribute contains the distinguished name of the entry
-that was last modified within the naming context of a database.
-.LP
-.RS 4
-(  1.3.6.1.4.1.4203.666.1.28
-   NAME 'lastmodDN'
-   DESC 'DN of last modification'
-   EQUALITY distinguishedNameMatch
-   SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
-   NO-USER-MODIFICATION
-   USAGE directoryOperation )
-.RE
-
-.B lastmodType
-.P
-This attribute contains the type of the modification that occurred
-to the last modified entry.  Legal values are
-.BR add ,
-.BR delete ,
-.BR exop ,
-.BR modify ,
-.B modrdn
-and
-.BR unknown .
-The latter should only be used as a fall-thru in case of unhandled
-request types that are considered equivalent to a write operation.
-.LP
-.RS 4
-(  1.3.6.1.4.1.4203.666.1.29
-   NAME 'lastmodType'
-   DESC 'Type of last modification'
-   SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
-   EQUALITY caseIgnoreMatch
-   SINGLE-VALUE
-   NO-USER-MODIFICATION
-   USAGE directoryOperation )
-.RE
-
-
-.SH EXAMPLES
-.LP
-.RS
-.nf
-database    bdb
-suffix      dc=example,dc=com
-\...
-overlay     lastmod
-lastmod-rdnvalue "Last Modification"
-.fi
-.RE
-
-.SH SEE ALSO
-.BR ldap (3),
-.BR slapd.conf (5),
-.LP
-"OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
-.LP
-
-.SH BUGS
-It is unclear whether this overlay can safely interoperate 
-with other overlays.
-If the underlying backend does not implement entry_get/entry_release
-handlers, modrdn update can become tricky.
-The code needs some cleanup and more consistent error handling.
-So far, the OIDs for the schema haven't been assigned yet.
-
-.SH ACKNOWLEDGEMENTS
-.P
-This module was written in 2004 by Pierangelo Masarati in fulfillment
-of requirements from SysNet s.n.c.; this man page has been copied
-from 
-.BR slapo-ppolicy (5),
-and most of the overlays ever written are copied from Howard Chu's
-first overlays.
-.P
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  

Copied: openldap/trunk/doc/man/man5/slapo-memberof.5 (from rev 891, openldap/vendor/openldap-2.4.7/doc/man/man5/slapo-memberof.5)
===================================================================
--- openldap/trunk/doc/man/man5/slapo-memberof.5	                        (rev 0)
+++ openldap/trunk/doc/man/man5/slapo-memberof.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,114 @@
+.TH SLAPO-MEMBEROF 5 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" Copyright 1998-2007 The OpenLDAP Foundation, All Rights Reserved.
+.\" Copying restrictions apply.  See the COPYRIGHT file.
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-memberof.5,v 1.1.2.1 2007/08/31 23:13:53 quanah Exp $
+.SH NAME
+slapo-memberof \- Reverse Group Membership overlay to slapd
+.SH SYNOPSIS
+ETCDIR/slapd.conf
+.SH DESCRIPTION
+The
+.B memberof
+overlay to
+.BR slapd (8)
+allows automatic reverse group membership maintenance.
+Any time a group entry is modified, its members are modified as appropriate
+in order to keep a DN-valued "is member of" attribute updated with the DN
+of the group.
+
+.SH CONFIGURATION
+The config directives that are specific to the
+.B memberof
+overlay must be prefixed by
+.BR memberof\- ,
+to avoid potential conflicts with directives specific to the underlying 
+database or to other stacked overlays.
+
+.TP
+.B overlay memberof
+This directive adds the memberof overlay to the current database; see
+.BR slapd.conf (5)
+for details.
+
+.LP
+The following
+.B slapd.conf
+configuration options are defined for the memberofoverlay.
+
+.TP
+.B memberof-group-oc <group-oc>
+The value 
+.B <group-oc> 
+is the name of the objectClass that triggers the reverse group membership
+update.
+It defaults to \fIgroupOfNames\fP.
+
+.TP
+.B memberof-member-ad <member-ad>
+The value 
+.B <member-ad> 
+is the name of the attribute that contains the names of the members
+in the group objects; it must be DN-valued.
+It defaults to \fImember\fP.
+
+.TP
+.B memberof-memberof-ad <memberof-ad>
+The value 
+.B <memberof-ad> 
+is the name of the attribute that contains the names of the groups
+an entry is member of; it must be DN-valued.  Its contents are 
+automatically updated by the overlay.
+It defaults to \fImemberOf\fP.
+
+.TP
+.B memberof-dn <dn>
+The value 
+.B <dn> 
+contains the DN that is used as \fImodifiersName\fP for internal 
+modifications performed to update the reverse group membership.
+It defaults to the \fIrootdn\fP of the underlying database.
+
+.TP
+.B memberof-dangling {ignore, drop, error}
+This option determines the behavior of the overlay when, during 
+a modification, it encounters dangling references.
+The default is
+.BR ignore ,
+which may leave dangling references.
+Other options are
+.BR drop ,
+which discards those modifications that would result in dangling
+references, and
+.BR error ,
+which causes modifications that would result in dangling references
+to fail.
+
+.TP
+.B memberof-refint {true|FALSE}
+This option determines whether the overlay will try to preserve
+referential integrity or not.
+If set to
+.BR TRUE ,
+when an entry containing values of the "is member of" attribute is modified,
+the corresponding groups are modified as well.
+
+.LP
+The memberof overlay may be used with any backend that provides full 
+read-write functionality, but it is mainly intended for use 
+with local storage backends.
+
+.SH FILES
+.TP
+ETCDIR/slapd.conf
+default slapd configuration file
+.SH SEE ALSO
+.BR slapd.conf (5),
+.BR slapd (8).
+The
+.BR slapo-memberof (5)
+overlay supports dynamic configuration via
+.BR back-config .
+.SH ACKNOWLEDGEMENTS
+.P
+This module was written in 2005 by Pierangelo Masarati for SysNet s.n.c.
+

Modified: openldap/trunk/doc/man/man5/slapo-pcache.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-pcache.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-pcache.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -2,9 +2,9 @@
 .\" Copyright 1998-2007 The OpenLDAP Foundation, All Rights Reserved.
 .\" Copying restrictions apply.  See the COPYRIGHT file.
 .\" Copyright 2001, Pierangelo Masarati, All rights reserved. <ando at sys-net.it>
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-pcache.5,v 1.3.2.10 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-pcache.5,v 1.14.2.3 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-pcache \- proxycache overlay
+slapo-pcache \- proxycache overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -24,7 +24,7 @@
 
 A template is defined by a filter string and an index identifying a set of
 attributes. The \fBtemplate string\fP for a query can be obtained by
-removing assertion values from the RFC 2254 representation of its search
+removing assertion values from the RFC 4515 representation of its search
 filter. A query belongs to a template if its template string and set of
 projected attributes correspond to a cacheable template.
 Examples of template strings are \fB(mail=)\fP, \fB(|(sn=)(cn=))\fP,
@@ -67,15 +67,39 @@
 .RS
 proxycache \fBbdb 10000 1 50 100\fP
 .RE
+
 .TP
 .B proxycachequeries <queries>
 Specify the maximum number of queries to cache. The default is 10000.
 
 .TP
+.B proxysavequeries { TRUE | FALSE }
+Specify whether the cached queries should be saved across restarts
+of the caching proxy, to provide hot startup of the cache.  Only non-expired
+queries are reloaded.  The default is FALSE.
+
+.BR CAVEAT :
+of course, the configuration of the proxycache must not change
+across restarts; the pcache overlay does not perform any consistency
+checks in this sense.
+In detail, this option should be disabled unless the existing
+.B proxyattrset
+and
+.B proxytemplate
+directives are not changed neither in order nor in contents.
+If new sets and templates are added, or if other details of the pcache
+overlay configuration changed, this feature should not be affected.
+
+.TP
 .B proxyattrset <index> <attrs...>
 Used to associate a set of attributes <attrs..> with an <index>. Each attribute
 set is associated with an integer from 0 to <numattrsets>-1. These indices are
 used by the \fBproxytemplate\fP directive to define cacheable templates. 
+A set of attributes cannot be empty.  A set of attributes can contain the
+special attributes "*" (all user attributes), "+" (all operational attributes)
+or both; in the latter case, any other attribute is redundant and should
+be avoided for clarity.  A set of attributes can contain "1.1" as the only
+attribute; in this case, only the presence of the entries is cached.
 
 .TP
 .B proxytemplate <template_string> <attrset_index> <ttl> [<negttl>]

Modified: openldap/trunk/doc/man/man5/slapo-ppolicy.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-ppolicy.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-ppolicy.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-ppolicy.5,v 1.4.2.8 2007/05/23 21:29:17 ghenry Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-ppolicy.5,v 1.12.2.5 2007/11/14 09:04:34 ghenry Exp $
 .\" Copyright 2004-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .TH SLAPO_PPOLICY 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .SH NAME
-slapo-ppolicy \- Password Policy overlay
+slapo-ppolicy \- Password Policy overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -29,6 +29,12 @@
 .B rootdn
 identity; all the operations, when performed with any other identity,
 may be subjected to constraints, like access control.
+.P
+Note that the IETF Password Policy proposal for LDAP makes sense
+when considering a single-valued password attribute, while 
+the userPassword attribute allows multiple values.  This implementation
+enforces a single value for the userPassword attribute, despite
+its specification.
 
 .SH CONFIGURATION
 These 
@@ -497,7 +503,7 @@
 .B userPassword
 .P
 The
-.b userPassword
+.B userPassword
 attribute is not strictly part of the
 .B ppolicy
 module.  It is, however, the attribute that is tracked and controlled
@@ -623,7 +629,7 @@
 
 time=
 .RS 4
-generalizedTimeString as specified in section 6.14 of [RFC2252]
+GeneralizedTime as specified in section 3.3.13 of [RFC4517]
 .RE
 
 .P
@@ -631,13 +637,13 @@
 .RS 4
 This is the string representation of the dotted-decimal OID that
 defines the syntax used to store the password.  numericoid is
-described in section 4.1 of [RFC2252].
+described in section 1.4 of [RFC4512].
 .RE
 
-length = numericstring
+length = NumericString
 .RS 4
-The number of octets in the data.  numericstring is described in
-section 4.1 of [RFC2252].
+The number of octets in the data.  NumericString is described in
+section 3.3.23 of [RFC4517].
 .RE
 
 data =
@@ -750,7 +756,4 @@
 IETF document named draft-behera-ldap-password-policy-09.txt,
 written in July of 2005.
 .P
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man5/slapo-refint.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-refint.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-refint.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH SLAPO-REFINT 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 2004-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-refint.5,v 1.2.2.5 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-refint.5,v 1.5.2.3 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-refint \- Referential Integrity overlay
+slapo-refint \- Referential Integrity overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -18,12 +18,19 @@
 .B delete
 operation. For example, if the integrity attribute were configured as
 .BR manager ,
-deletion of the record "uid=robert,ou=people,o=openldap.org" would trigger a
+deletion of the record "uid=robert,ou=people,dc=example,dc=com" would trigger a
 search for all other records which have a
 .B manager
 attribute containing that DN. Entries matching that search would have their
 .B manager
 attribute removed.
+Or, renaming the same record into "uid=george,ou=people,dc=example,dc=com" 
+would trigger a search for all other records which have a
+.B manager
+attribute containing that DN.
+Entries matching that search would have their
+.B manager
+attribute deleted and replaced by the new DN.
 .SH CONFIGURATION
 These
 .B slapd.conf
@@ -49,3 +56,5 @@
 default slapd configuration file
 .SH SEE ALSO
 .BR slapd.conf (5).
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Modified: openldap/trunk/doc/man/man5/slapo-retcode.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-retcode.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-retcode.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -2,9 +2,9 @@
 .\" Copyright 1998-2007 The OpenLDAP Foundation, All Rights Reserved.
 .\" Copying restrictions apply.  See the COPYRIGHT file.
 .\" Copyright 2001, Pierangelo Masarati, All rights reserved. <ando at sys-net.it>
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-retcode.5,v 1.2.2.8 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-retcode.5,v 1.9.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-retcode \- return code overlay
+slapo-retcode \- return code overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -58,16 +58,31 @@
 .hy 0
 .B retcode\-item <RDN> <errCode> [op=<oplist>] [text=<message>]
 .B [ref=<referral>] [sleeptime=<sec>] [matched=<DN>]
+.B [unsolicited=<OID>[:<data>]] [flags=[{pre|post}-]disconnect[,...]]
 .RS
 A dynamically generated entry, located below \fBretcode\-parent\fP.
-The \fB<errCode>\fP is the number of the response code;
-it can be in any format supported by strtol.
-The optional \fB<oplist>\fP is a list of operations that cause
+The \fBerrCode\fP is the number of the response code;
+it can be in any format supported by
+.BR strtol (3).
+The optional \fBoplist\fP is a list of operations that cause
 response code generation; if absent, all operations are affected.
 The \fBmatched\fP field is the matched DN that is returned
-along with the error.
+along with the error, while the \fBtext\fP field is an optional
+diagnostics message.
 The \fBref\fP field is only allowed for the \fBreferral\fP 
 response code.
+The \fBsleeptime\fP field causes
+.BR slapd (8)
+to sleep the specified number of seconds before proceeding 
+with the operation.
+The \fBunsolicited\fP field can be used to cause the return
+of an RFC 4511 unsolicited response message; if \fBOID\fP
+is not "0", an extended response is generated, with the optional
+\fBdata\fP appended.
+If \fBflags\fP contains \fBdisconnect\fP, or \fBpre-disconnect\fP,
+.BR slapd (8)
+disconnects abruptly, without notice; \fBpost-disconnect\fP
+causes disconnection right after sending response as appropriate.
 .RE
 .TP
 .B retcode\-indir
@@ -148,6 +163,40 @@
     SINGLE-VALUE )
 .RE
 .LP
+The OID to be returned as extended response OID
+in RFC 4511 unsolicited responses
+("0" generates a regular response with msgid set to 0):
+.RS 4
+( 1.3.6.1.4.1.4203.666.11.4.1.6
+    NAME ( 'errUnsolicitedOID' )
+    DESC 'OID to be returned within unsolicited response'
+    EQUALITY objectIdentifierMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
+    SINGLE-VALUE )
+.RE
+.LP
+The octet string to be returned as extended response data
+in RFC 4511 unsolicited response:
+.RS 4
+( 1.3.6.1.4.1.4203.666.11.4.1.7
+    NAME ( 'errUnsolicitedData' )
+    DESC 'Data to be returned within unsolicited response'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+    SINGLE-VALUE )
+.RE
+.LP
+If TRUE,
+.BR slapd (8)
+disconnects abruptly without notice; if FALSE, it disconnects
+after sending response as appropriate:
+.RS 4
+( 1.3.6.1.4.1.4203.666.11.4.1.8
+    NAME ( 'errDisconnect' )
+    DESC 'Disconnect without notice'
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+    SINGLE-VALUE )
+.RE
+.LP
 The abstract class that triggers the overlay:
 .RS 4
 ( 1.3.6.1.4.1.4203.666.11.4.3.0

Modified: openldap/trunk/doc/man/man5/slapo-rwm.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-rwm.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-rwm.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -2,13 +2,13 @@
 .\" Copyright 1998-2007 The OpenLDAP Foundation, All Rights Reserved.
 .\" Copying restrictions apply.  See the COPYRIGHT file.
 .\" Copyright 2004, Pierangelo Masarati, All rights reserved. <ando at sys-net.it>
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-rwm.5,v 1.8.2.7 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-rwm.5,v 1.14.2.3 2007/08/31 23:13:53 quanah Exp $
 .\"
 .\" Portions of this document should probably be moved to slapd-ldap(5)
 .\" and maybe manual pages for librewrite.
 .\"
 .SH NAME
-slapo-rwm \- rewrite/remap overlay
+slapo-rwm \- rewrite/remap overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -71,6 +71,24 @@
 Also, note that there are DN-related syntaxes (i.e. compound types with
 a portion that is DN-valued), like nameAndOptionalUID,
 whose values are currently not rewritten.
+.LP
+If the foreign type of an attribute mapping is not defined on the local 
+server, it might be desirable to have the attribute values normalized after
+the mapping process. Not normalizing the values can lead to wrong results, 
+when the
+.B rwm
+overlay is used together with e.g. the
+.B pcache
+overlay. This normalization can be enabled by means of the 
+.B rwm-normalize-mapped-attrs
+directive.
+.TP
+.B rwm-normalize-mapped-attrs {yes|no}
+Set this to "yes", if the
+.B rwm
+overlay should try to normalize the values of attributes that are mapped from
+an attribute type that is unknown to the local server. The default value of
+this setting is "no".
 .SH SUFFIX MASSAGING
 A basic feature of the
 .B rwm
@@ -78,6 +96,20 @@
 and a real naming context by means of the 
 .B rwm-suffixmassage
 directive.
+This, in conjunction with proxy backends,
+.BR slapd-ldap (5)
+and
+.BR slapd-meta (5),
+or with the relay backend, 
+.BR slapd-relay (5),
+allows to create virtual views of databases.
+A distinguishing feature of this overlay is that, when instantiated
+before any database, it can modify the DN of requests
+.I before
+database selection.
+For this reason, rules that rewrite the empty DN ("") 
+or the subschemaSubentry DN (usually "cn=subschema"),
+would prevent clients from reading the root DSE or the DSA's schema.
 .TP
 .B rwm-suffixmassage "[<virtual naming context>]" "<real naming context>"
 Shortcut to implement naming context rewriting; the trailing part
@@ -393,6 +425,51 @@
 to any single rule; an optional per-rule limit can be set.
 This limit is overridden by setting specific per-rule limits
 with the `M{n}' flag.
+
+.SH "MAPS"
+Currently, few maps are builtin and there are no provisions for developers
+to register new map types at runtime.
+
+Supported maps are:
+.TP
+.B LDAP <URI> [bindwhen=<when>] [version=<version>] [binddn=<DN>] [credentials=<cred>]
+The
+.B LDAP
+map expands a value by performing a simple LDAP search.
+Its configuration is based on a mandatory URI, whose
+.B attrs
+portion must contain exactly one attribute
+(use
+.B entryDN
+to fetch the DN of an entry).
+If a multi-valued attribute is used, only the first value is considered.
+
+The parameter
+.B bindwhen
+determines when the connection is established.
+It can take the values
+.BR now ,
+.BR later ,
+and
+.BR everytime ,
+respectively indicating that the connection should be created at startup,
+when required, or any time it is used.
+In the former two cases, the connection is cached, while in the latter
+a fresh new one is used all times.  This is the default.
+
+The parameters
+.B binddn
+and
+.B credentials
+represent the DN and the password that is used to perform an authenticated
+simple bind before performing the search operation; if not given,
+an anonymous connection is used.
+
+The parameter
+.B version
+can be 2 or 3 to indicate the protocol version that must be used.
+The default is 3.
+
 .SH "REWRITE CONFIGURATION EXAMPLES"
 .nf
 # set to `off' to disable rewriting

Modified: openldap/trunk/doc/man/man5/slapo-syncprov.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-syncprov.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-syncprov.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH SLAPO-SYNCPROV 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 2004-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-syncprov.5,v 1.2.2.8 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-syncprov.5,v 1.9.2.3 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-syncprov \- Sync Provider overlay
+slapo-syncprov \- Sync Provider overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -21,9 +21,6 @@
 configured to write the contextCSN into the underlying database to minimize
 recovery time after an unclean shutdown.
 
-Note that due to deadlock constraints in the LDBM database, this overlay
-will only work in RefreshOnly mode, and cannot perform checkpoints, on LDBM.
-
 On databases that support inequality indexing, it is helpful to set an
 eq index on the entryCSN attribute when using this overlay.
 .SH CONFIGURATION
@@ -64,7 +61,7 @@
 not properly set this flag, so the overlay must ignore it. This option
 should be set TRUE when working with newer releases that properly support
 this flag. It must be set TRUE when using the accesslog overlay for
-delta-based syncrepl support.  The default is FALSE.
+delta-based syncrepl replication support.  The default is FALSE.
 .SH FILES
 .TP
 ETCDIR/slapd.conf
@@ -73,3 +70,5 @@
 .BR slapd.conf (5),
 .BR slapo-accesslog (5).
 OpenLDAP Administrator's Guide.
+.SH ACKNOWLEDGEMENTS
+.so ../Project

Modified: openldap/trunk/doc/man/man5/slapo-translucent.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-translucent.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-translucent.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH SLAPO-TRANSLUCENT 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 2004-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-translucent.5,v 1.2.2.4 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-translucent.5,v 1.4.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-translucent \- Translucent Proxy overlay
+slapo-translucent \- Translucent Proxy overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
@@ -36,11 +36,9 @@
 .BR slapd-ldap (5).
 These
 .B slapd.conf
-options are specific to the Translucent Proxy overlay; they may appear anywhere
+options are specific to the Translucent Proxy overlay; they should appear 
 after the
 .B overlay
-directive and before any subsequent
-.B database
 directive.
 .TP
 .B translucent_strict

Modified: openldap/trunk/doc/man/man5/slapo-unique.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-unique.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-unique.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,17 +1,17 @@
 .TH SLAPO-UNIQUE 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 2004-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-unique.5,v 1.2.2.6 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-unique.5,v 1.6.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-unique \- Attribute Uniqueness overlay
+slapo-unique \- Attribute Uniqueness overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION
 The Attribute Uniqueness overlay can be used with a backend database such as
 .BR slapd-bdb (5)
-to enforce the uniqueness of some or all attributes within a subtree. This
-subtree defaults to the base DN of the database for which the Uniqueness
-overlay is configured.
+to enforce the uniqueness of some or all attributes within a
+scope. This subtree defaults to all objects within the subtree of the
+database for which the Uniqueness overlay is configured.
 .LP
 Uniqueness is enforced by searching the subtree to ensure that the values of
 all attributes presented with an
@@ -19,7 +19,7 @@
 .B modify
 or
 .B modrdn
-operation are unique within the subtree.
+operation are unique within the scope.
 For example, if uniqueness were enforced for the
 .B uid
 attribute, the subtree would be searched for any other records which also
@@ -35,18 +35,59 @@
 .B overlay
 directive.
 .TP
-.B unique_base <basedn>
-Configure the subtree against which uniqueness searches will be invoked.
+.B unique_uri <[strict ][ignore ]URI[URI...]...>
+Configure the base, attributes, scope, and filter for uniqueness
+checking.  Multiple URIs may be specified within a domain, allowing complex selections of objects.  Multiple
+.B unique_uri
+statements or
+.B olcUniqueURI
+attributes will create independent domains, each with their own independent lists of URIs and ignore/strict settings.
+
+The LDAP URI syntax is a subset of
+.B RFC-4516,
+and takes the form:
+
+ldap:///[base dn]?[attributes...]?scope[?filter]
+
 The
-.B basedn
-defaults to the base DN of the database for which uniqueness is configured.
-.TP
-.B unique_ignore <attribute...>
-Configure one or more attributes for which uniqueness will not be enforced.
-If not configured, all non-operational (eg, system) attributes must be
+.B base dn
+defaults to that of the back-end database.  Specified base dns must be within the subtree of the back-end database.
+
+If no
+.B attributes
+are specified, the URI applies to all non-operational attributes.
+
+The
+.B scope
+component is effectively mandatory, because LDAP URIs default to
+.B base
+scope, which is not valid for uniqueness, because groups of one object
+are always unique.  Scopes of
+.B sub
+(for subtree) and
+.B one
+for one-level are valid.
+
+The
+.B filter
+component causes the domain to apply uniqueness constraints only to
+matching objects.  e.g.
+.B ldap:///?cn?sub?(sn=e*)
+would require unique
+.B cn
+attributes for all objects in the subtree of the back-end database whose
+.B sn
+starts with an e.
+
+It is possible to assert uniqueness upon all non-operational
+attributes except those listed by prepending the keyword
+.B ignore
+If not configured, all non-operational (e.g., system) attributes must be
 unique. Note that the
-.B unique_ignore
-list should generally contain the
+.B attributes
+list of an
+.B ignore
+URI should generally contain the
 .BR objectClass ,
 .BR dc ,
 .B ou
@@ -54,42 +95,55 @@
 .B o
 attributes, as these will generally not be unique, nor are they operational
 attributes.
+
+It is possible to set strict checking for the uniqueness domain by
+prepending the keyword
+.B strict.
+By default, uniqueness is not enforced
+for null values. Enabling
+.B strict
+mode extends the concept of uniqueness to include null values, such
+that only one attribute within a subtree will be allowed to have a
+null value.  Strictness applies to all URIs within a uniqueness
+domain, but some domains may be strict while others are not.
+.LP
+It is not possible to set both URIs and legacy slapo-unique configuration parameters simultaneously.  In general, the legacy configuration options control pieces of a single unfiltered subtree domain.
 .TP
+.B unique_base <basedn>
+This legacy configuration parameter should be converted to the
+.B base dn
+component of the above
+.B unique_uri
+style of parameter.
+.TP
+.B unique_ignore <attribute...>
+This legacy configuration parameter should be converted to a
+.B unique_uri
+parameter with
+.B ignore
+keyword as described above.
+.TP
 .B unique_attributes <attribute...>
-Specify one or more attributes for which uniqueness will be enforced.
-If not specified, all attributes which are not operational (eg, system
-attributes such as
-.B entryUUID )
-or specified via the
-.B unique_ignore
-directive above must be unique within the subtree.
+This legacy configuration parameter should be converted to a
+.B unique_uri
+parameter, as described above.
 .TP
 .B unique_strict
-By default, uniqueness is not enforced for null values. Enabling
-.B unique_strict
-mode extends the concept of uniqueness to include null values, such that
-only one attribute within a subtree will be allowed to have a null value.
+This legacy configuration parameter should be converted to a
+.B strict
+keyword prepended to a
+.B unique_uri
+parameter, as described above.
 .SH CAVEATS
 .LP
-The search key is generated with attributes that are non-operational, not
-on the
-.B unique_ignore
-list, and included in the
-.B unique_attributes
-list, in that order. This makes it possible to create interesting and
-unusable configurations. Usually only one of
-.B unique_ignore
-or
-.B unique_attributes
-should be configured; use
-.B unique_ignore
-if the majority of attributes should be unique, and use
-.B unique_attributes
-if only a small set of attributes should be unique.
+.B unique_uri
+cannot be used with the old-style of configuration, and vice versa.
+.B unique_uri
+can implement everything the older system can do, however.
 .LP
 Typical attributes for the
-.B unique_ignore
-directive are intentionally not hardcoded into the overlay to allow for
+.B ignore ldap:///...
+URIs are intentionally not hardcoded into the overlay to allow for
 maximum flexibility in meeting site-specific requirements.
 .SH FILES
 .TP

Modified: openldap/trunk/doc/man/man5/slapo-valsort.5
===================================================================
--- openldap/trunk/doc/man/man5/slapo-valsort.5	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man5/slapo-valsort.5	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,9 +1,9 @@
 .TH SLAPO-VALSORT 5 "RELEASEDATE" "OpenLDAP LDVERSION"
 .\" Copyright 2005-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-valsort.5,v 1.2.2.5 2007/01/02 21:43:45 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man5/slapo-valsort.5,v 1.4.2.2 2007/08/31 23:13:53 quanah Exp $
 .SH NAME
-slapo-valsort \- Value Sorting overlay
+slapo-valsort \- Value Sorting overlay to slapd
 .SH SYNOPSIS
 ETCDIR/slapd.conf
 .SH DESCRIPTION

Modified: openldap/trunk/doc/man/man8/Makefile.in
===================================================================
--- openldap/trunk/doc/man/man8/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # man8 Makefile.in for OpenLDAP
-# $OpenLDAP: pkg/ldap/doc/man/man8/Makefile.in,v 1.8.2.4 2007/01/02 21:43:46 kurt Exp $
+# $OpenLDAP: pkg/ldap/doc/man/man8/Makefile.in,v 1.11.2.2 2007/08/31 23:13:53 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/doc/man/man8/slapacl.8
===================================================================
--- openldap/trunk/doc/man/man8/slapacl.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slapacl.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -5,13 +5,14 @@
 slapacl \- Check access to a list of attributes.
 .SH SYNOPSIS
 .B SBINDIR/slapacl
-.B [\-v]
+.B \-b DN
 .B [\-d level]
+.B [\-D authcDN | \-U authcID]
 .B [\-f slapd.conf]
 .B [\-F confdir]
-.B [\-D authcDN | \-U authcID]
-.B \-b DN
+.B [\-o name[=value]]
 .B [\-u]
+.B [\-v]
 .B [\-X authzID | \-o authzDN=DN]
 .B [attr[/access][:value]] [...]
 .LP
@@ -33,13 +34,28 @@
 .LP
 .SH OPTIONS
 .TP
-.B \-v
-enable verbose mode.
+.BI \-b " DN"
+specify the 
+.B DN 
+which access is requested to; the corresponding entry is fetched 
+from the database, and thus it must exist.
+The DN is also used to determine what rules apply; thus, it must be
+in the naming context of a configured database.  See also
+.BR \-u .
 .TP
 .BI \-d " level"
 enable debugging messages as defined by the specified
-.IR level .
+.IR level ;
+see
+.BR slapd (8)
+for details.
 .TP
+.BI \-D " authcDN"
+specify a DN to be used as identity through the test session
+when selecting appropriate
+.B <by> 
+clauses in access lists.
+.TP
 .BI \-f " slapd.conf"
 specify an alternative
 .BR slapd.conf (5)
@@ -58,63 +74,43 @@
 config file. If a valid config directory exists then the
 default config file is ignored.
 .TP
-.BI \-D " authcDN"
-specify a DN to be used as identity through the test session
-when selecting appropriate
-.B <by> 
-clauses in access lists.
-.TP
-.BI \-U " authcID"
-specify an ID to be mapped to a 
-.B DN 
-as by means of 
-.B authz-regexp
-or
-.B authz-rewrite
-rules (see 
-.BR slapd.conf (5)
-for details); mutually exclusive with
-.BR \-D .
-.TP
-.BI \-X " authzID"
-specify an authorization ID to be mapped to a
-.B DN
-as by means of
-.B authz-regexp
-or
-.B authz-rewrite
-rules (see
-.BR slapd.conf (5)
-for details); mutually exclusive with \fB\-o\fP \fIauthzDN=DN\fP.
-.TP
 .BI \-o " option[=value]"
 Specify an
 .BR option
 with a(n optional)
 .BR value .
-Possible options/values are:
+Possible generic options/values are:
 .LP
 .nf
-              sockurl
+              syslog=<subsystems>  (see `\-s' in slapd(8))
+              syslog-level=<level> (see `\-S' in slapd(8))
+              syslog-user=<user>   (see `\-l' in slapd(8))
+
+.fi
+.RS
+Possible options/values specific to
+.B slapacl
+are:
+.RE
+.nf
+
+              authzDN
               domain
               peername
+              sasl_ssf
               sockname
+              sockurl
               ssf
+              tls_ssf
               transport_ssf
-              tls_ssf
-              sasl_ssf
-              authzDN
+
 .fi
+.RS
+See the related fields in
+.BR slapd.access (5)
+for details.
+.RE
 .TP
-.BI \-b " DN"
-specify the 
-.B DN 
-which access is requested to; the corresponding entry is fetched 
-from the database, and thus it must exist.
-The DN is also used to determine what rules apply; thus, it must be
-in the naming context of a configured database.  See also
-.BR \-u .
-.TP
 .BI \-u
 do not fetch the entry from the database.
 In this case, if the entry does not exist, a fake entry with the DN
@@ -129,6 +125,32 @@
 in the naming context of a configured database.
 See also
 .BR \-b .
+.TP
+.BI \-U " authcID"
+specify an ID to be mapped to a 
+.B DN 
+as by means of 
+.B authz-regexp
+or
+.B authz-rewrite
+rules (see 
+.BR slapd.conf (5)
+for details); mutually exclusive with
+.BR \-D .
+.TP
+.B \-v
+enable verbose mode.
+.TP
+.BI \-X " authzID"
+specify an authorization ID to be mapped to a
+.B DN
+as by means of
+.B authz-regexp
+or
+.B authz-rewrite
+rules (see
+.BR slapd.conf (5)
+for details); mutually exclusive with \fB\-o\fP \fIauthzDN=DN\fP.
 .SH EXAMPLES
 The command
 .LP
@@ -157,7 +179,4 @@
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man8/slapadd.8
===================================================================
--- openldap/trunk/doc/man/man8/slapadd.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slapadd.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,24 +1,27 @@
 .TH SLAPADD 8C "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man8/slapadd.8,v 1.23.2.11 2007/10/04 09:02:15 ando Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man8/slapadd.8,v 1.34.2.7 2007/11/14 09:04:34 ghenry Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 slapadd \- Add entries to a SLAPD database
 .SH SYNOPSIS
 .B SBINDIR/slapadd
-.B [\-v]
+.B [\-b suffix]
 .B [\-c]
-.B [\-g]
-.B [\-u]
-.B [\-q]
-.B [\-w]
-.B [\-s]
 .B [\-d level]
-.B [\-b suffix]
-.B [\-n dbnum]
 .B [\-f slapd.conf]
 .B [\-F confdir]
+.B [\-g]
+.B [\-j lineno]
 .B [\-l ldif-file]
+.B [\-n dbnum]
+.B [\-o name[=value]]
+.B [\-q]
+.B [\-s]
+.B [\-S SID]
+.B [\-u]
+.B [\-v]
+.B [\-w]
 .SH DESCRIPTION
 .LP
 .B Slapadd
@@ -33,15 +36,6 @@
 .B subordinate
 of this one are also updated, unless \fB-g\fP is specified.
 The LDIF input is read from standard input or the specified file.
-.LP
-As
-.B slapadd
-is designed to accept LDIF in database order, as produced by
-.BR slapcat (8),
-it does not verify that superior entries exist before
-adding an entry, does not perform all user and system
-schema checks, and does not maintain operational
-attributes (such as createTimeStamp and modifiersName). 
 
 All files eventually created by
 .BR slapadd
@@ -59,40 +53,6 @@
 .BR slapd (8).
 .SH OPTIONS
 .TP
-.B \-v
-enable verbose mode.
-.TP
-.B \-c
-enable continue (ignore errors) mode.
-.TP
-.B \-g
-disable subordinate gluing.  Only the specified database will be
-processed, and not its glued subordinates (if any).
-.TP
-.B \-u
-enable dry-run (don't write to backend) mode.
-.TP
-.B \-q
-enable quick (fewer integrity checks) mode.  Does fewer consistency checks
-on the input data, and no consistency checks when writing the database.
-Improves the load time but if any errors or interruptions occur the resulting
-database will be unusable.
-.TP
-.BI \-w
-write syncrepl context information.
-After all entries are added, the contextCSN
-will be updated with the greatest CSN in the database.
-.TP
-.BI \-s
-disable schema checking.  This option is intended to be used when loading
-databases containing special objects, such as fractional objects on a
-partial replica.  Loading normal objects which do not conform to
-schema may result in unexpected and ill behavior.
-.TP
-.BI \-d " level"
-enable debugging messages as defined by the specified
-.IR level .
-.TP
 .BI \-b " suffix" 
 Use the specified \fIsuffix\fR to determine which database to
 add entries to.  The \-b cannot be used in conjunction
@@ -100,14 +60,16 @@
 .B \-n
 option.
 .TP
-.BI \-n " dbnum"
-Add entries to the \fIdbnum\fR\-th database listed in the
-configuration file.  The
-.B \-n
-cannot be used in conjunction with the
-.B \-b
-option.
+.B \-c
+enable continue (ignore errors) mode.
 .TP
+.BI \-d " level"
+enable debugging messages as defined by the specified
+.IR level ;
+see
+.BR slapd (8)
+for details.
+.TP
 .BI \-f " slapd.conf"
 specify an alternative
 .BR slapd.conf (5)
@@ -127,8 +89,66 @@
 default config file is ignored. If dryrun mode is also specified,
 no conversion will occur.
 .TP
+.B \-g
+disable subordinate gluing.  Only the specified database will be
+processed, and not its glued subordinates (if any).
+.TP
+.BI \-j " lineno"
+Jump to the specified line number in the LDIF file before processing
+any entries. This allows a load that was aborted due to errors in the
+input LDIF to be resumed after the errors are corrected.
+.TP
 .BI \-l " ldif-file"
 Read LDIF from the specified file instead of standard input.
+.TP
+.BI \-n " dbnum"
+Add entries to the \fIdbnum\fR\-th database listed in the
+configuration file.  The
+.B \-n
+cannot be used in conjunction with the
+.B \-b
+option.
+.TP
+.BI \-o " option[=value]"
+Specify an
+.BR option
+with a(n optional)
+.BR value .
+Possible generic options/values are:
+.LP
+.nf
+              syslog=<subsystems>  (see `\-s' in slapd(8))
+              syslog-level=<level> (see `\-S' in slapd(8))
+              syslog-user=<user>   (see `\-l' in slapd(8))
+
+.fi
+.TP
+.B \-q
+enable quick (fewer integrity checks) mode.  Does fewer consistency checks
+on the input data, and no consistency checks when writing the database.
+Improves the load time but if any errors or interruptions occur the resulting
+database will be unusable.
+.TP
+.B -s
+disable schema checking.  This option is intended to be used when loading
+databases containing special objects, such as fractional objects on a
+partial replica.  Loading normal objects which do not conform to
+schema may result in unexpected and ill behavior.
+.TP
+.B \-S " SID"
+Server ID to use in generated entryCSN.  Also used for contextCSN
+if `\-w' is set as well.  Defaults to 0.
+.TP
+.B \-u
+enable dry-run (don't write to backend) mode.
+.TP
+.B \-v
+enable verbose mode.
+.TP
+.BI \-w
+write syncrepl context information.
+After all entries are added, the contextCSN
+will be updated with the greatest CSN in the database.
 .SH LIMITATIONS
 Your
 .BR slapd (8)
@@ -161,7 +181,4 @@
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man8/slapauth.8
===================================================================
--- openldap/trunk/doc/man/man8/slapauth.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slapauth.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -2,16 +2,17 @@
 .\" Copyright 2004-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-slapauth \- Check a list of string-represented IDs for authc/authz.
+slapauth \- Check a list of string-represented IDs for LDAP authc/authz
 .SH SYNOPSIS
 .B SBINDIR/slapauth
-.B [\-v]
 .B [\-d level]
 .B [\-f slapd.conf]
 .B [\-F confdir]
 .B [\-M mech]
+.B [\-o name[=value]]
 .B [\-R realm]
 .B [\-U authcID]
+.B [\-v]
 .B [\-X authzID]
 .B ID [...]
 .LP
@@ -33,12 +34,12 @@
 .LP
 .SH OPTIONS
 .TP
-.B \-v
-enable verbose mode.
-.TP
 .BI \-d " level"
 enable debugging messages as defined by the specified
-.IR level .
+.IR level ;
+see
+.BR slapd (8)
+for details.
 .TP
 .BI \-f " slapd.conf"
 specify an alternative
@@ -61,6 +62,20 @@
 .BI \-M " mech"
 specify a mechanism.
 .TP
+.BI \-o " option[=value]"
+Specify an
+.BR option
+with a(n optional)
+.BR value .
+Possible generic options/values are:
+.LP
+.nf
+              syslog=<subsystems>  (see `\-s' in slapd(8))
+              syslog-level=<level> (see `\-S' in slapd(8))
+              syslog-user=<user>   (see `\-l' in slapd(8))
+
+.fi
+.TP
 .BI \-R " realm"
 specify a realm.
 .TP
@@ -86,6 +101,9 @@
 and
 .I authzID
 are given via command line switch, the ID list cannot be present.
+.TP
+.B \-v
+enable verbose mode.
 .SH EXAMPLES
 The command
 .LP
@@ -119,7 +137,4 @@
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man8/slapcat.8
===================================================================
--- openldap/trunk/doc/man/man8/slapcat.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slapcat.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,22 +1,23 @@
 .TH SLAPCAT 8C "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man8/slapcat.8,v 1.19.2.9 2007/09/12 15:00:36 ghenry Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man8/slapcat.8,v 1.28.2.6 2007/11/14 09:04:34 ghenry Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 slapcat \- SLAPD database to LDIF utility
 .SH SYNOPSIS
 .B SBINDIR/slapcat
-.B [\-v]
+.B [\-a filter]
+.B [\-b suffix]
 .B [\-c]
-.B [\-g]
 .B [\-d level]
-.B [\-b suffix]
-.B [\-n dbnum]
-.B [\-a filter]
-.B [\-s subtree-dn]
 .B [\-f slapd.conf]
 .B [\-F confdir]
+.B [\-g]
 .B [\-l ldif-file]
+.B [\-n dbnum]
+.B [\-o name[=value]]
+.B [\-s subtree-dn]
+.B [\-v]
 .B 
 .LP
 .SH DESCRIPTION
@@ -33,43 +34,21 @@
 .B subordinate
 of this one are also output, unless \fB-g\fP is specified.
 .LP
-The LDIF generated by this tool is suitable for use with
+The entry records are presented in database order, not superior first
+order.  The entry records will include all (user and operational)
+attributes stored in the database.  The entry records will not include
+dynamically generated attributes (such as subschemaSubentry).
+.LP
+The output of slapcat is intended to be used as input to
 .BR slapadd (8).
-As the entries are in database order, not superior first order,
-they cannot be loaded with
+The output of slapcat cannot generally be used as input to
 .BR ldapadd (1)
-without first being reordered.
+or other LDAP clients without first editing the output.
+This editing would normally include reordering the records
+into superior first order and removing no-user-modification
+operational attributes.
 .SH OPTIONS
 .TP
-.B \-v
-Enable verbose mode.
-.TP
-.B \-c
-Enable continue (ignore errors) mode.
-.TP
-.B \-g
-disable subordinate gluing.  Only the specified database will be
-processed, and not its glued subordinates (if any).
-.TP
-.BI \-d " level"
-Enable debugging messages as defined by the specified
-.IR level .
-.TP
-.BI \-b " suffix" 
-Use the specified \fIsuffix\fR to determine which database to
-generate output for.  The \-b cannot be used in conjunction
-with the
-.B \-n
-option.
-.TP
-.BI \-n " dbnum"
-Generate output for the \fIdbnum\fR\-th database listed in the
-configuration file.  The
-.B \-n
-cannot be used in conjunction with the
-.B \-b
-option.
-.TP
 .BI \-a " filter"
 Only dump entries matching the asserted filter.
 For example
@@ -80,14 +59,23 @@
 will dump all but the "ou=People,dc=example,dc=com" subtree
 of the "dc=example,dc=com" database.
 .TP
-.BI \-s " subtree-dn"
-Only dump entries in the subtree specified by this DN.
-Implies `-b subtree-dn' if no
-.B \-b
-or
+.BI \-b " suffix" 
+Use the specified \fIsuffix\fR to determine which database to
+generate output for.  The \-b cannot be used in conjunction
+with the
 .B \-n
-option is given.
+option.
 .TP
+.B \-c
+Enable continue (ignore errors) mode.
+.TP
+.BI \-d " level"
+Enable debugging messages as defined by the specified
+.IR level ;
+see
+.BR slapd (8)
+for details.
+.TP
 .BI \-f " slapd.conf"
 Specify an alternative
 .BR slapd.conf (5)
@@ -106,8 +94,45 @@
 config file. If a valid config directory exists then the
 default config file is ignored.
 .TP
+.B \-g
+disable subordinate gluing.  Only the specified database will be
+processed, and not its glued subordinates (if any).
+.TP
 .BI \-l " ldif-file"
 Write LDIF to specified file instead of standard output.
+.TP
+.BI \-n " dbnum"
+Generate output for the \fIdbnum\fR\-th database listed in the
+configuration file.  The
+.B \-n
+cannot be used in conjunction with the
+.B \-b
+option.
+.TP
+.BI \-o " option[=value]"
+Specify an
+.BR option
+with a(n optional)
+.BR value .
+Possible generic options/values are:
+.LP
+.nf
+              syslog=<subsystems>  (see `\-s' in slapd(8))
+              syslog-level=<level> (see `\-S' in slapd(8))
+              syslog-user=<user>   (see `\-l' in slapd(8))
+
+.fi
+.TP
+.BI \-s " subtree-dn"
+Only dump entries in the subtree specified by this DN.
+Implies `-b subtree-dn' if no
+.B \-b
+or
+.B \-n
+option is given.
+.TP
+.B \-v
+Enable verbose mode.
 .SH LIMITATIONS
 For some backend types, your
 .BR slapd (8)
@@ -140,7 +165,4 @@
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man8/slapd.8
===================================================================
--- openldap/trunk/doc/man/man8/slapd.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slapd.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-.\" $OpenLDAP: pkg/ldap/doc/man/man8/slapd.8,v 1.53.2.9 2007/01/02 21:43:46 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man8/slapd.8,v 1.64.2.5 2007/08/31 23:13:53 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .TH SLAPD 8C "RELEASEDATE" "OpenLDAP LDVERSION"
@@ -13,6 +13,7 @@
 .B [\-F slapd\-config\-directory]
 .B [\-h URLs]
 .B [\-n service\-name] [\-s syslog\-level] [\-l syslog\-local\-user]
+.B [\-o option[=value]]
 .B [\-r directory]
 .B [\-u user] [\-g group]
 .B [\-c cookie]
@@ -45,15 +46,6 @@
 .B slapd
 will not fork and disassociate from the invoking tty.
 .LP
-.B Slapd
-can be configured to provide replicated service for a database with
-the help of
-.BR slurpd ,
-the standalone LDAP update replication daemon.
-See
-.BR slurpd (8)
-for details.
-.LP
 See the "OpenLDAP Administrator's Guide" for more details on
 .BR slapd .
 .SH OPTIONS
@@ -79,13 +71,20 @@
 .TP
 .BI \-d " debug\-level"
 Turn on debugging as defined by
-.I debug\-level.
+.IR debug\-level .
 If this option is specified, even with a zero argument,
 .B slapd
 will not fork or disassociate from the invoking terminal.  Some general
 operation and status messages are printed for any value of \fIdebug\-level\fP.
 \fIdebug\-level\fP is taken as a bit string, with each bit corresponding to a
 different kind of debugging information.  See <ldap_log.h> for details.
+Comma-separated arrays of friendly names can be specified to select
+debugging output of the corresponding debugging information.
+All the names recognized by the \fIloglevel\fP directive 
+described in \fBslapd.conf\fP(5) are supported.
+If \fIdebug\-level\fP is \fB?\fP, a list of installed levels is printed,
+and slapd exits.
+
 Remember that if you turn on packet logging, packets containing bind passwords
 will be output, so if you redirect the log to a logfile, that file should
 be read-protected.
@@ -96,6 +95,11 @@
 at what level debugging statements should be logged to the
 .BR syslog (8)
 facility.
+The value "syslog\-level" can be set to any value or combination
+allowed by the "-d" switch.
+Slapd logs all messages selected by "syslog\-level" 
+at the syslog(3) severity level "DEBUG",
+on the unit specified with "-l".
 .TP
 .BI \-n " service\-name"
 Specifies the service name for logging and other purposes.  Defaults
@@ -118,6 +122,7 @@
 local users with the 
 .BR syslog (8)
 facility.
+Logging to syslog(8) occurs at the "DEBUG" severity level.
 .TP
 .BI \-f " slapd\-config\-file"
 Specifies the slapd configuration file. The default is
@@ -226,6 +231,30 @@
 is the commit sequence number received by a previous synchronization
 and represents the state of the consumer replica content which the
 syncrepl engine will synchronize to the current provider content.
+.TP
+.BI \-o " option[=value]"
+This option provides a generic means to specify options without the need to reserve
+a separate letter for them.
+
+It supports the following options:
+.RS
+.TP
+slp={\fBon\fP|\fBoff\fP|\fIslp\-attrs\fP}
+When SLP support is compiled into slapd, disable it (
+.B off
+), enable it by registering at SLP DAs without specific SLP attributes (
+.B on
+), or with specific SLP attributes
+.I slp\-attrs
+that must be an SLP attribute list definition according to the SLP standard.
+
+For example, "-o slp=(tree=production),(server-type=OpenLDAP),(server-version=2.3.20)"
+registers at SLP DAs with the three SLP attributes tree, server-type and server-version
+that have the values given above.
+This allows to specifically query the SLP DAs for LDAP servers holding the
+.I production
+tree in case multiple trees are available.
+.RE
 .SH EXAMPLES
 To start 
 .I slapd
@@ -268,14 +297,10 @@
 .BR slapdn (8),
 .BR slapindex (8),
 .BR slappasswd (8),
-.BR slaptest (8),
-.BR slurpd (8)
+.BR slaptest (8).
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH BUGS
 See http://www.openldap.org/its/
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man8/slapdn.8
===================================================================
--- openldap/trunk/doc/man/man8/slapdn.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slapdn.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -2,14 +2,15 @@
 .\" Copyright 2004-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-slapdn \- Check a list of string-represented DNs based on schema syntax.
+slapdn \- Check a list of string-represented LDAP DNs based on schema syntax
 .SH SYNOPSIS
 .B SBINDIR/slapdn
-.B [\-v]
 .B [\-d level]
 .B [\-f slapd.conf]
 .B [\-F confdir]
 .B [\-N | \-P]
+.B [\-o name[=value]]
+.B [\-v]
 .B DN [...]
 .LP
 .SH DESCRIPTION
@@ -29,12 +30,12 @@
 .LP
 .SH OPTIONS
 .TP
-.B \-v
-enable verbose mode.
-.TP
 .BI \-d " level"
 enable debugging messages as defined by the specified
-.IR level .
+.IR level ;
+see
+.BR slapd (8)
+for details.
 .TP
 .BI \-f " slapd.conf"
 specify an alternative
@@ -59,10 +60,27 @@
 in a normalization tool; incompatible with
 .BR \-P .
 .TP
+.BI \-o " option[=value]"
+Specify an
+.BR option
+with a(n optional)
+.BR value .
+Possible generic options/values are:
+.LP
+.nf
+              syslog=<subsystems>  (see `\-s' in slapd(8))
+              syslog-level=<level> (see `\-S' in slapd(8))
+              syslog-user=<user>   (see `\-l' in slapd(8))
+
+.fi
+.TP
 .BI \-P
 only output a prettified form of the DN, suitable to be used
 in a check and beautification tool; incompatible with
 .BR \-N .
+.TP
+.B \-v
+enable verbose mode.
 .SH EXAMPLES
 To check a
 .B DN
@@ -80,7 +98,4 @@
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man8/slapindex.8
===================================================================
--- openldap/trunk/doc/man/man8/slapindex.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slapindex.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,20 +1,23 @@
 .TH SLAPINDEX 8C "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man8/slapindex.8,v 1.10.2.11 2007/10/04 09:02:15 ando Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man8/slapindex.8,v 1.19.2.8 2007/11/27 19:29:13 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
 slapindex \- SLAPD index to LDIF utility
 .SH SYNOPSIS
 .B SBINDIR/slapindex
-.B [\-v]
+.B [\-b suffix]
 .B [\-c]
-.B [\-g]
-.B [\-q]
 .B [\-d level]
-.B [\-b suffix]
-.B [\-n dbnum]
 .B [\-f slapd.conf]
 .B [\-F confdir]
+.B [\-g]
+.B [\-n dbnum]
+.B [\-o name[=value]]
+.B [\-q]
+.B [\-t]
+.B [\-v]
+.B [attr] [...]
 .B 
 .LP
 .SH DESCRIPTION
@@ -46,27 +49,6 @@
 .BR slapd (8).
 .SH OPTIONS
 .TP
-.B \-v
-enable verbose mode.
-.TP
-.B \-c
-enable continue (ignore errors) mode.
-.TP
-.B \-g
-disable subordinate gluing.  Only the specified database will be
-processed, and not its glued subordinates (if any).
-.TP
-.B \-q
-enable quick (fewer integrity checks) mode. Performs no consistency checks
-when writing the database. Improves indexing time,
-.B however
-the database will most likely be unusable if any errors or
-interruptions occur.
-.TP
-.BI \-d " level"
-enable debugging messages as defined by the specified
-.IR level .
-.TP
 .BI \-b " suffix" 
 Use the specified \fIsuffix\fR to determine which database to
 generate output for.  The \-b cannot be used in conjunction
@@ -74,14 +56,16 @@
 .B \-n
 option.
 .TP
-.BI \-n " dbnum"
-Generate output for the \fIdbnum\fR\-th database listed in the
-configuration file.  The
-.B \-n
-cannot be used in conjunction with the
-.B \-b
-option.
+.B \-c
+enable continue (ignore errors) mode.
 .TP
+.BI \-d " level"
+enable debugging messages as defined by the specified
+.IR level ;
+see
+.BR slapd (8)
+for details.
+.TP
 .BI \-f " slapd.conf"
 specify an alternative
 .BR slapd.conf (5)
@@ -99,6 +83,46 @@
 default config directory will be made before trying to use the default
 config file. If a valid config directory exists then the
 default config file is ignored.
+.TP
+.B \-g
+disable subordinate gluing.  Only the specified database will be
+processed, and not its glued subordinates (if any).
+.TP
+.BI \-n " dbnum"
+Generate output for the \fIdbnum\fR\-th database listed in the
+configuration file.  The
+.B \-n
+cannot be used in conjunction with the
+.B \-b
+option.
+.TP
+.BI \-o " option[=value]"
+Specify an
+.BR option
+with a(n optional)
+.BR value .
+Possible generic options/values are:
+.LP
+.nf
+              syslog=<subsystems>  (see `\-s' in slapd(8))
+              syslog-level=<level> (see `\-S' in slapd(8))
+              syslog-user=<user>   (see `\-l' in slapd(8))
+
+.fi
+.TP
+.B \-q
+enable quick (fewer integrity checks) mode. Performs no consistency checks
+when writing the database. Improves indexing time,
+.B however
+the database will most likely be unusable if any errors or
+interruptions occur.
+.TP
+.B \-t
+enable truncate mode. Truncates (empties) an index database before indexing
+any entries. May only be used with Quick mode.
+.TP
+.B \-v
+enable verbose mode.
 .SH LIMITATIONS
 Your
 .BR slapd (8)
@@ -115,6 +139,14 @@
 	SBINDIR/slapindex
 .ft
 .fi
+To regenerate the index for only a specific attribute, e.g. "uid",
+give the command:
+.LP
+.nf
+.ft tt
+	SBINDIR/slapindex uid
+.ft
+.fi
 .SH "SEE ALSO"
 .BR ldap (3),
 .BR ldif (5),
@@ -124,7 +156,4 @@
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man8/slappasswd.8
===================================================================
--- openldap/trunk/doc/man/man8/slappasswd.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slappasswd.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 .TH SLAPPASSWD 8C "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man8/slappasswd.8,v 1.18.2.3 2007/01/02 21:43:46 kurt Exp $
+.\" $OpenLDAP: pkg/ldap/doc/man/man8/slappasswd.8,v 1.21.2.4 2007/08/31 23:13:53 quanah Exp $
 .\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
@@ -8,9 +8,10 @@
 .B SBINDIR/slappasswd
 .B [\-v]
 .B [\-u]
-.B [\-s secret|\-T file]
+.B [\-g|\-s secret|\-T file]
 .B [\-h hash]
 .B [\-c salt-format]
+.B [\-n]
 .B 
 .LP
 .SH DESCRIPTION
@@ -35,20 +36,46 @@
 .TP
 .BI \-s " secret"
 The secret to hash.
-If this and
+If this,
+.B \-g
+and
 .B \-T
 are absent, the user will be prompted for the secret to hash.
+.BR \-s ,
+.B \-g
+and
+.B \-T
+and mutually exclusive flags.
+.TP
+.BI \-g
+Generate the secret.
+If this,
 .B \-s
 and
 .B \-T
+are absent, the user will be prompted for the secret to hash.
+.BR \-s ,
+.B \-g
+and
+.B \-T
 and mutually exclusive flags.
+If this is present,
+.I {CLEARTEXT}
+is used as scheme.
+.B \-g
+and
+.B \-h
+are mutually exclusive flags.
 .TP
 .BI \-T " file"
 Hash the contents of the file.
-If this and
+If this,
+.B \-g
+and
 .B \-s
 are absent, the user will be prompted for the secret to hash.
-.B \-s
+.BR \-s ,
+.B \-g
 and
 .B \-T
 and mutually exclusive flags.
@@ -87,6 +114,10 @@
 .B {CLEARTEXT}
 indicates that the new password should be added to userPassword as
 clear text.
+Unless
+.I {CLEARTEXT}
+is used, this flag is incompatible with
+.BR \-g .
 .TP
 .BI \-c " crypt-salt-format"
 Specify the format of the salt passed to
@@ -101,14 +132,18 @@
 versions of crypt(3) to use an MD5 algorithm and provides
 8 random characters of salt.  The default is '%s', which
 provides 31 characters of salt.
+.TP
+.BI \-n
+Omit the trailing newline; useful to pipe the credentials
+into a command.
 .SH LIMITATIONS
-The practice storing hashed passwords in userPassword violates
-Standard Track (RFC 2256) schema specifications and may hinder
+The practice of storing hashed passwords in userPassword violates
+Standard Track (RFC 4519) schema specifications and may hinder
 interoperability.  A new attribute type, authPassword, to hold
 hashed passwords has been defined (RFC 3112), but is not yet
 implemented in
 .BR slapd (8).
-.TP
+.LP
 It should also be noted that the behavior of
 .BR crypt (3)
 is platform specific.
@@ -116,7 +151,7 @@
 Use of hashed passwords does not protect passwords during
 protocol transfer.  TLS or other eavesdropping protections
 should be in\-place before using LDAP simple bind.
-.TP
+.LP
 The hashed password values should be protected as if they
 were clear text passwords.
 .SH "SEE ALSO"
@@ -125,11 +160,9 @@
 .BR slapd (8)
 .BR slapd.conf (5)
 .B RFC 2307
-.B RFC 2256
+.B RFC 4519
 .B RFC 3112
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-OpenLDAP is developed and maintained by
-The OpenLDAP Project (http://www.openldap.org/).
-OpenLDAP is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Modified: openldap/trunk/doc/man/man8/slaptest.8
===================================================================
--- openldap/trunk/doc/man/man8/slaptest.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slaptest.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -2,12 +2,14 @@
 .\" Copyright 2004-2007 The OpenLDAP Foundation All Rights Reserved.
 .\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
 .SH NAME
-slaptest \- Check the suitability of the slapd.conf file.
+slaptest \- Check the suitability of the OpenLDAP slapd.conf file
 .SH SYNOPSIS
 .B SBINDIR/slaptest
 .B [\-d level]
 .B [\-f slapd.conf]
 .B [\-F confdir]
+.B [\-o name[=value]]
+.B [\-Q]
 .B [\-u]
 .B [\-v]
 .LP
@@ -26,7 +28,10 @@
 .TP
 .BI \-d " level"
 enable debugging messages as defined by the specified
-.IR level .
+.IR level ;
+see
+.BR slapd (8)
+for details.
 .TP
 .BI \-f " slapd.conf"
 specify an alternative
@@ -47,11 +52,29 @@
 default config file is ignored. If dryrun mode is also specified,
 no conversion will occur.
 .TP
-.B \-u
+.BI \-o " option[=value]"
+Specify an
+.BR option
+with a(n optional)
+.BR value .
+Possible generic options/values are:
+.LP
+.nf
+              syslog=<subsystems>  (see `\-s' in slapd(8))
+              syslog-level=<level> (see `\-S' in slapd(8))
+              syslog-user=<user>   (see `\-l' in slapd(8))
+
+.fi
+.TP
+.BI \-Q
+Be extremely quiet: only the exit code indicates success (0) or not 
+(any other value).
+.TP
+.BI \-u
 enable dryrun mode (i.e. don't fail if databases cannot be opened,
 but config is fine).
 .TP
-.B \-v
+.BI \-v
 enable verbose mode.
 .SH EXAMPLES
 To check a 
@@ -70,7 +93,4 @@
 .LP
 "OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
 .SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  
+.so ../Project

Deleted: openldap/trunk/doc/man/man8/slurpd.8
===================================================================
--- openldap/trunk/doc/man/man8/slurpd.8	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/doc/man/man8/slurpd.8	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,163 +0,0 @@
-.TH SLURPD 8C "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" $OpenLDAP: pkg/ldap/doc/man/man8/slurpd.8,v 1.17.2.5 2007/01/02 21:43:46 kurt Exp $
-.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
-.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.SH NAME
-slurpd \- Standalone LDAP Update Replication Daemon
-.SH SYNOPSIS
-.B LIBEXECDIR/slurpd [\-d debug\-level]
-.B [\-f slapd\-config\-file] [\-r slapd\-replog\-file]
-.B [\-t temp\-dir] [\-o]
-.B 
-.SH DESCRIPTION
-.LP
-.B Slurpd
-is used to propagate changes from one slapd database to another.  If
-slapd is configured to produce a replication log, 
-.B slurpd
-reads that
-replication log and sends the changes to the slave 
-.B slapd
-instances
-via the LDAP protocol.
-.B slurpd
-is typically invoked at boot time, usually out of
-.BR  /etc/rc.local .
-.LP
-Upon startup,
-.B slurpd
-normally forks and disassociates itself from the invoking tty,
-then reads the replication log (given either by the
-.I replogfile
-directive in the 
-.B slapd
-config file, or by the
-.RB \- r
-command-line option).
-If the replication log file does not exist or is empty,
-.B slurpd
-goes to sleep.  It periodically wakes up and checks to see if there
-are any changes to be propagated.
-.LP
-When
-.B slurpd
-notices that there are changes to propagate to slave 
-.B slapd
-instances, it locks the replication log, makes its own private copy,
-releases the lock, and forks one copy of itself for each replica
-.B slapd
-to be updated.  Each child process binds to the slave 
-.B slapd
-as the
-DN given by the
-.I binddn
-option to the
-.I replica
-directive in the
-.B slapd
-config file, and sends the changes.
-.LP
-See
-.BR slapd (8)
-for details on the standalone LDAP daemon.
-.LP
-Note that slurpd reads
-.B replication
-directive from
-.BR slapd.conf (5),
-but uses
-.BR ldap.conf (5)
-to obtain other configuration settings (such as TLS settings).
-.SH OPTIONS
-.TP
-.BI \-d " debug\-level"
-Turn on debugging as defined by
-.I debug\-level.
-If this option is specified, even with a zero argument,
-.B slurpd
-will not fork or disassociate from the invoking terminal.  Some general
-operation and status messages are printed for any value of \fIdebug\-level\fP.
-\fIdebug\-level\fP is taken as a bit string, with each bit corresponding to a
-different kind of debugging information.  See <ldap.h> for details.
-.TP
-.BI \-f " slapd\-config\-file"
-Specifies the slapd configuration file.  The default is
-.BR ETCDIR/slapd.conf .
-.TP
-.BI \-r " slapd\-replog\-file"
-Specifies the name of the 
-.B slapd
-replication logfile.  Normally, the name
-of the replication log file is read from the 
-.B slapd
-configuration file.  The file should be located in a directory
-with limited read/write/execute access.
-The
-.B \-r
-option allows you to override this.  In conjunction with the
-.B \-o
-option, you can process a replication log file in a "one\-shot" mode.  For
-example, if 
-.B slurpd
-has encountered errors in processing a replication log,
-you can run it in one\-shot mode and give the rejection file name as
-the argument to the \-r option, once you've resolved the problem which caused
-the replication to fail.
-.TP
-.B \-o
-Run in "one\-shot" mode.  Normally, 
-.B slurpd
-processes the replog file
-and then watches for more replication entries to be appended.  In
-one\-shot mode, 
-.B slurpd
-processes a replication log and exits.
-.TP
-.BI \-t " temp\-dir"
-.B slurpd
-copies the replication log to a working directory before processing it.
-The directory permissions should limit read/write/execute access as
-temporary files may contain sensitive information.
-This option allows you to specify the location of these temporary files. 
-The default is
-.BR LOCALSTATEDIR/openldap-slurp .
-.SH EXAMPLES
-To start 
-.I slurpd
-and have it fork and detach from the terminal and process
-the replication logs generated by
-.I slapd,
-just type:
-.LP
-.nf
-.ft tt
-	LIBEXECDIR/slurpd
-.ft
-.fi
-.LP
-To start 
-.I slurpd
-with an alternate 
-.I slapd
-configuration file, and turn
-on voluminous debugging which will be printed on standard error, type:
-.LP
-.nf
-.ft tt
-	LIBEXECDIR/slurpd -f ETCDIR/slapd.conf -d 255
-.ft
-.fi
-.LP
-.SH "SEE ALSO"
-.BR ldap (3),
-.BR ldap.conf (5),
-.BR slapd.conf (5),
-.BR slapd.replog (5),
-.BR slapd (8)
-.LP
-"OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
-.SH ACKNOWLEDGEMENTS
-.B OpenLDAP
-is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
-.B OpenLDAP
-is derived from University of Michigan LDAP 3.3 Release.  

Modified: openldap/trunk/include/Makefile.in
===================================================================
--- openldap/trunk/include/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # include Makefile.in for OpenLDAP
-# $OpenLDAP: pkg/ldap/include/Makefile.in,v 1.30.2.4 2007/01/02 21:43:46 kurt Exp $
+# $OpenLDAP: pkg/ldap/include/Makefile.in,v 1.33.2.2 2007/08/31 23:13:53 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -50,6 +50,8 @@
 		$(SED) -e 's/\\\\/\\\\\\\\\\\\\\\\/g'`; \
 	    libexecdir=`cygpath -w $(libexecdir) | \
 		$(SED) -e 's/\\\\/\\\\\\\\\\\\\\\\/g'`; \
+	    moduledir=`cygpath -w $(moduledir) | \
+		$(SED) -e 's/\\\\/\\\\\\\\\\\\\\\\/g'`; \
 	    localstatedir=`cygpath -w $(localstatedir) | \
 		$(SED) -e 's/\\\\/\\\\\\\\\\\\\\\\/g'`; \
 	else \
@@ -58,6 +60,7 @@
 	    bindir=$(bindir); \
 	    sbindir=$(sbindir); \
 	    libexecdir=$(libexecdir); \
+	    moduledir=$(moduledir); \
 	    localstatedir=$(localstatedir); \
 	    localedir=$(localedir); \
 	fi; \
@@ -67,6 +70,7 @@
 			-e "s;%BINDIR%;$$bindir;" \
 			-e "s;%SBINDIR%;$$sbindir;" \
 			-e "s;%LIBEXECDIR%;$$libexecdir;" \
+			-e "s;%MODULEDIR%;$$moduledir;" \
 			-e "s;%RUNDIR%;$$localstatedir;" \
 			-e "s;%LOCALEDIR%;$$localedir;" \
 			 $(LDAP_CONFIG) >> $@; \

Modified: openldap/trunk/include/ac/alloca.h
===================================================================
--- openldap/trunk/include/ac/alloca.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/alloca.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic alloca.h */
-/* $OpenLDAP: pkg/ldap/include/ac/alloca.h,v 1.16.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/alloca.h,v 1.18.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -26,7 +26,7 @@
 #ifdef __GNUC__
 # define alloca __builtin_alloca
 #else
-# if HAVE_ALLOCA_H
+# ifdef HAVE_ALLOCA_H
 #  include <alloca.h>
 # else
 #  ifdef _AIX

Modified: openldap/trunk/include/ac/assert.h
===================================================================
--- openldap/trunk/include/ac/assert.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/assert.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic assert.h */
-/* $OpenLDAP: pkg/ldap/include/ac/assert.h,v 1.19.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/assert.h,v 1.21.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/bytes.h
===================================================================
--- openldap/trunk/include/ac/bytes.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/bytes.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic bytes.h */
-/* $OpenLDAP: pkg/ldap/include/ac/bytes.h,v 1.18.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/bytes.h,v 1.20.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/crypt.h
===================================================================
--- openldap/trunk/include/ac/crypt.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/crypt.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic crypt.h */
-/* $OpenLDAP: pkg/ldap/include/ac/crypt.h,v 1.8.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/crypt.h,v 1.10.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -20,7 +20,7 @@
 #include <ac/unistd.h>
 
 /* crypt() may be defined in a separate include file */
-#if HAVE_CRYPT_H
+#ifdef HAVE_CRYPT_H
 #	include <crypt.h>
 #else
 	extern char *(crypt)();

Modified: openldap/trunk/include/ac/ctype.h
===================================================================
--- openldap/trunk/include/ac/ctype.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/ctype.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic ctype.h */
-/* $OpenLDAP: pkg/ldap/include/ac/ctype.h,v 1.14.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/ctype.h,v 1.16.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/dirent.h
===================================================================
--- openldap/trunk/include/ac/dirent.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/dirent.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic dirent.h */
-/* $OpenLDAP: pkg/ldap/include/ac/dirent.h,v 1.12.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/dirent.h,v 1.14.2.3 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -17,19 +17,33 @@
 #ifndef _AC_DIRENT_H
 #define _AC_DIRENT_H
 
-#if HAVE_DIRENT_H
+#ifdef HAVE_DIRENT_H
 # include <dirent.h>
 # define NAMLEN(dirent) strlen((dirent)->d_name)
+#elif defined(_MSC_VER)
+#include <windows.h>
+#ifndef MAX_PATH
+#define MAX_PATH	260
+#endif
+struct dirent {
+	char *d_name;
+};
+typedef struct DIR {
+	HANDLE dir;
+	struct dirent data;
+	int first;
+	char buf[MAX_PATH+1];
+} DIR;
 #else
 # define dirent direct
 # define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
+# ifdef HAVE_SYS_NDIR_H
 #  include <sys/ndir.h>
 # endif
-# if HAVE_SYS_DIR_H
+# ifdef HAVE_SYS_DIR_H
 #  include <sys/dir.h>
 # endif
-# if HAVE_NDIR_H
+# ifdef HAVE_NDIR_H
 #  include <ndir.h>
 # endif
 #endif

Modified: openldap/trunk/include/ac/errno.h
===================================================================
--- openldap/trunk/include/ac/errno.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/errno.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic errno.h */
-/* $OpenLDAP: pkg/ldap/include/ac/errno.h,v 1.28.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/errno.h,v 1.30.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -27,7 +27,7 @@
 	/* no sys_errlist */
 #	define		sys_nerr	0
 #	define		sys_errlist	((char **)0)
-#elif DECL_SYS_ERRLIST
+#elif defined( DECL_SYS_ERRLIST )
 	/* have sys_errlist but need declaration */
 	LDAP_LIBC_V(int)      sys_nerr;
 	LDAP_LIBC_V(char)    *sys_errlist[];

Modified: openldap/trunk/include/ac/fdset.h
===================================================================
--- openldap/trunk/include/ac/fdset.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/fdset.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* redefine FD_SET */
-/* $OpenLDAP: pkg/ldap/include/ac/fdset.h,v 1.3.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/fdset.h,v 1.5.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Deleted: openldap/trunk/include/ac/krb.h
===================================================================
--- openldap/trunk/include/ac/krb.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/krb.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,37 +0,0 @@
-/* Generic krb.h */
-/* $OpenLDAP: pkg/ldap/include/ac/krb.h,v 1.15.2.3 2007/01/02 21:43:47 kurt Exp $ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-/* Kerberos IV */
-
-#ifndef _AC_KRB_H
-#define _AC_KRB_H
-
-#if defined( HAVE_KRB4 )
-
-#if defined( HAVE_KERBEROSIV_KRB_H )
-#include <kerberosIV/krb.h>
-#elif defined( HAVE_KRB_H )
-#include <krb.h>
-#endif
-
-#if defined( HAVE_KERBEROSIV_DES_H )
-#include <kerberosIV/des.h>
-#elif defined( HAVE_DES_H )
-#include <des.h>
-#endif
-
-#endif /* HAVE_KRB4 */
-#endif /* _AC_KRB_H */

Deleted: openldap/trunk/include/ac/krb5.h
===================================================================
--- openldap/trunk/include/ac/krb5.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/krb5.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,26 +0,0 @@
-/* Generic krb.h */
-/* $OpenLDAP: pkg/ldap/include/ac/krb5.h,v 1.8.2.3 2007/01/02 21:43:47 kurt Exp $ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-/* Kerberos V */
-
-#ifndef _AC_KRB5_H
-#define _AC_KRB5_H
-
-#if defined( HAVE_KRB5 )
-#include <krb5.h>
-#endif /* HAVE_KRB5 */
-
-#endif /* _AC_KRB5_H */

Modified: openldap/trunk/include/ac/localize.h
===================================================================
--- openldap/trunk/include/ac/localize.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/localize.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* localize.h (i18n/l10n) */
-/* $OpenLDAP: pkg/ldap/include/ac/localize.h,v 1.5.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/localize.h,v 1.7.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/param.h
===================================================================
--- openldap/trunk/include/ac/param.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/param.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic param.h */
-/* $OpenLDAP: pkg/ldap/include/ac/param.h,v 1.11.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/param.h,v 1.13.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/regex.h
===================================================================
--- openldap/trunk/include/ac/regex.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/regex.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic Regex */
-/* $OpenLDAP: pkg/ldap/include/ac/regex.h,v 1.15.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/regex.h,v 1.17.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/setproctitle.h
===================================================================
--- openldap/trunk/include/ac/setproctitle.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/setproctitle.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic setproctitle.h */
-/* $OpenLDAP: pkg/ldap/include/ac/setproctitle.h,v 1.19.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/setproctitle.h,v 1.21.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/signal.h
===================================================================
--- openldap/trunk/include/ac/signal.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/signal.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic signal.h */
-/* $OpenLDAP: pkg/ldap/include/ac/signal.h,v 1.23.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/signal.h,v 1.25.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/socket.h
===================================================================
--- openldap/trunk/include/ac/socket.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/socket.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic socket.h */
-/* $OpenLDAP: pkg/ldap/include/ac/socket.h,v 1.65.2.4 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/socket.h,v 1.67.2.3 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -23,6 +23,8 @@
 
 #ifdef HAVE_POLL_H
 #include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
 #endif
 
 #ifdef HAVE_SYS_SOCKET_H
@@ -125,7 +127,7 @@
 #		define tcp_write( s, buf, len )	netwrite( s, buf, len )
 #	endif /* NCSA */
 
-#elif HAVE_CLOSESOCKET
+#elif defined(HAVE_CLOSESOCKET)
 #	define tcp_close( s )		closesocket( s )
 
 #	ifdef __BEOS__
@@ -211,16 +213,32 @@
 #	endif
 #endif
 
-#ifndef HAVE_GETPEEREID
-LDAP_LUTIL_F( int ) getpeereid( int s, uid_t *, gid_t * );
+#if defined(LDAP_PF_LOCAL) && \
+	!defined(HAVE_GETPEEREID) && \
+	!defined(HAVE_GETPEERUCRED) && \
+	!defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && \
+	defined(HAVE_SENDMSG) && (defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTSLEN) || \
+	defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL))
+#	define LDAP_PF_LOCAL_SENDMSG 1
 #endif
 
+#ifdef HAVE_GETPEEREID
+#define	LUTIL_GETPEEREID( s, uid, gid, bv )	getpeereid( s, uid, gid )
+#elif defined(LDAP_PF_LOCAL_SENDMSG)
+struct berval;
+LDAP_LUTIL_F( int ) lutil_getpeereid( int s, uid_t *, gid_t *, struct berval *bv );
+#define	LUTIL_GETPEEREID( s, uid, gid, bv )	lutil_getpeereid( s, uid, gid, bv )
+#else
+LDAP_LUTIL_F( int ) lutil_getpeereid( int s, uid_t *, gid_t * );
+#define	LUTIL_GETPEEREID( s, uid, gid, bv )	lutil_getpeereid( s, uid, gid )
+#endif
+
 /* DNS RFC defines max host name as 255. New systems seem to use 1024 */
 #ifndef NI_MAXHOST
 #define	NI_MAXHOST	256
 #endif
 
-#ifdef HAVE_POLL_H
+#ifdef HAVE_POLL
 # ifndef INFTIM
 #  define INFTIM (-1)
 # endif

Modified: openldap/trunk/include/ac/stdarg.h
===================================================================
--- openldap/trunk/include/ac/stdarg.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/stdarg.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic stdarg.h */
-/* $OpenLDAP: pkg/ldap/include/ac/stdarg.h,v 1.17.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/stdarg.h,v 1.19.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/stdlib.h
===================================================================
--- openldap/trunk/include/ac/stdlib.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/stdlib.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic stdlib.h */
-/* $OpenLDAP: pkg/ldap/include/ac/stdlib.h,v 1.17.2.4 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/stdlib.h,v 1.19.2.3 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/string.h
===================================================================
--- openldap/trunk/include/ac/string.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/string.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic string.h */
-/* $OpenLDAP: pkg/ldap/include/ac/string.h,v 1.44.2.7 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/string.h,v 1.51.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/sysexits.h
===================================================================
--- openldap/trunk/include/ac/sysexits.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/sysexits.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic sysexits */
-/* $OpenLDAP: pkg/ldap/include/ac/sysexits.h,v 1.10.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/sysexits.h,v 1.12.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/syslog.h
===================================================================
--- openldap/trunk/include/ac/syslog.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/syslog.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic syslog.h */
-/* $OpenLDAP: pkg/ldap/include/ac/syslog.h,v 1.15.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/syslog.h,v 1.17.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/termios.h
===================================================================
--- openldap/trunk/include/ac/termios.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/termios.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic termios.h */
-/* $OpenLDAP: pkg/ldap/include/ac/termios.h,v 1.16.2.4 2007/09/22 23:09:11 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/termios.h,v 1.18.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ac/time.h
===================================================================
--- openldap/trunk/include/ac/time.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/time.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic time.h */
-/* $OpenLDAP: pkg/ldap/include/ac/time.h,v 1.16.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/time.h,v 1.18.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -17,10 +17,10 @@
 #ifndef _AC_TIME_H
 #define _AC_TIME_H
 
-#if TIME_WITH_SYS_TIME
+#ifdef TIME_WITH_SYS_TIME
 # include <sys/time.h>
 # include <time.h>
-#elif HAVE_SYS_TIME_H
+#elif defined(HAVE_SYS_TIME_H)
 # include <sys/time.h>
 # ifdef HAVE_SYS_TIMEB_H
 #  include <sys/timeb.h>

Modified: openldap/trunk/include/ac/unistd.h
===================================================================
--- openldap/trunk/include/ac/unistd.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/unistd.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic unistd.h */
-/* $OpenLDAP: pkg/ldap/include/ac/unistd.h,v 1.35.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/unistd.h,v 1.37.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -17,15 +17,15 @@
 #ifndef _AC_UNISTD_H
 #define _AC_UNISTD_H
 
-#if HAVE_SYS_TYPES_H
+#ifdef HAVE_SYS_TYPES_H
 #	include <sys/types.h>
 #endif
 
-#if HAVE_UNISTD_H
+#ifdef HAVE_UNISTD_H
 #	include <unistd.h>
 #endif
 
-#if HAVE_PROCESS_H
+#ifdef HAVE_PROCESS_H
 #	include <process.h>
 #endif
 
@@ -45,7 +45,7 @@
 #endif
 
 /* getopt() defines may be in separate include file */
-#if HAVE_GETOPT_H
+#ifdef HAVE_GETOPT_H
 #	include <getopt.h>
 
 #elif !defined(HAVE_GETOPT)

Modified: openldap/trunk/include/ac/wait.h
===================================================================
--- openldap/trunk/include/ac/wait.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ac/wait.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* Generic wait.h */
-/* $OpenLDAP: pkg/ldap/include/ac/wait.h,v 1.14.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ac/wait.h,v 1.16.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -19,7 +19,7 @@
 
 #include <sys/types.h>
 
-#if HAVE_SYS_WAIT_H
+#ifdef HAVE_SYS_WAIT_H
 # include <sys/wait.h>
 #endif
 

Modified: openldap/trunk/include/avl.h
===================================================================
--- openldap/trunk/include/avl.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/avl.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* avl.h - avl tree definitions */
-/* $OpenLDAP: pkg/ldap/include/avl.h,v 1.24.2.4 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/avl.h,v 1.29.2.3 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -59,6 +59,8 @@
 #define EH 	0
 #define RH 	1
 
+#define avl_bf2str(bf)	((bf) == -1 ? "LH" : (bf) == 0 ? "EH" : (bf) == 1 ? "RH" : "(unknown)" )
+
 /* thread bits */
 #define	AVL_THREAD	0
 #define	AVL_CHILD	1
@@ -132,6 +134,9 @@
 LDAP_AVL_F( Avlnode* )
 tavl_find2 LDAP_P((Avlnode *, const void*, AVL_CMP));
 
+LDAP_AVL_F( Avlnode* )
+tavl_find3 LDAP_P((Avlnode *, const void*, AVL_CMP, int *ret));
+
 #define	TAVL_DIR_LEFT	0
 #define	TAVL_DIR_RIGHT	1
 

Modified: openldap/trunk/include/getopt-compat.h
===================================================================
--- openldap/trunk/include/getopt-compat.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/getopt-compat.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* getopt-compat.h -- getopt(3) compatibility header */
-/* $OpenLDAP: pkg/ldap/include/getopt-compat.h,v 1.17.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/getopt-compat.h,v 1.19.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/lber.h
===================================================================
--- openldap/trunk/include/lber.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/lber.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/lber.h,v 1.94.2.5 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/lber.h,v 1.99.2.3 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -138,8 +138,12 @@
 #define LBER_SB_OPT_NEEDS_WRITE		12
 #define LBER_SB_OPT_GET_MAX_INCOMING	13
 #define LBER_SB_OPT_SET_MAX_INCOMING	14
+
+/* Only meaningful ifdef LDAP_PF_LOCAL_SENDMSG */
+#define LBER_SB_OPT_UNGET_BUF	15
+
 /* Largest option used by the library */
-#define LBER_SB_OPT_OPT_MAX		14
+#define LBER_SB_OPT_OPT_MAX		15
 
 /* LBER IO operations stacking levels */
 #define LBER_SBIOD_LEVEL_PROVIDER	10
@@ -267,11 +271,14 @@
 	char *buf,
 	ber_len_t *len ));
 
+#define	LBER_BV_ALLOC	0x01	/* allocate/copy result, otherwise in-place */
+#define	LBER_BV_NOTERM	0x02	/* omit NUL-terminator if parsing in-place */
+
 LBER_F( ber_tag_t )
 ber_get_stringbv LDAP_P((
 	BerElement *ber,
 	struct berval *bv,
-	int alloc ));
+	int options ));
 
 LBER_F( ber_tag_t )
 ber_get_stringa LDAP_P((
@@ -316,9 +323,19 @@
 	LDAP_CONST char *fmt,
 	... ));
 
+LBER_F( int )
+ber_decode_oid LDAP_P((
+	struct berval *in,
+	struct berval *out ));
+
 /*
  * in encode.c
  */
+LBER_F( int )
+ber_encode_oid LDAP_P((
+	struct berval *in,
+	struct berval *out ));
+
 typedef int (*BEREncodeCallback) LDAP_P((
 	BerElement *ber,
 	void *data ));
@@ -402,6 +419,11 @@
  */
 
 LBER_F( ber_slen_t )
+ber_skip_data LDAP_P((
+	BerElement *ber,
+	ber_len_t len ));
+
+LBER_F( ber_slen_t )
 ber_read LDAP_P((
 	BerElement *ber,
 	char *buf,
@@ -423,11 +445,21 @@
 ber_free_buf LDAP_P(( BerElement *ber ));
 
 LBER_F( int )
-ber_flush LDAP_P((
+ber_flush2 LDAP_P((
 	Sockbuf *sb,
 	BerElement *ber,
 	int freeit ));
+#define LBER_FLUSH_FREE_NEVER		(0x0)	/* traditional behavior */
+#define LBER_FLUSH_FREE_ON_SUCCESS	(0x1)	/* traditional behavior */
+#define LBER_FLUSH_FREE_ON_ERROR	(0x2)
+#define LBER_FLUSH_FREE_ALWAYS		(LBER_FLUSH_FREE_ON_SUCCESS|LBER_FLUSH_FREE_ON_ERROR)
 
+LBER_F( int )
+ber_flush LDAP_P((
+	Sockbuf *sb,
+	BerElement *ber,
+	int freeit )); /* DEPRECATED */
+
 LBER_F( BerElement * )
 ber_alloc LDAP_P(( void )); /* DEPRECATED */
 
@@ -622,10 +654,6 @@
 #define LBER_ERROR_PARAM	0x1
 #define LBER_ERROR_MEMORY	0x2
 
-#ifdef LDAP_DEVEL
-#define LDAP_NULL_IS_NULL
-#endif
-
 LDAP_END_DECL
 
 #endif /* _LBER_H */

Modified: openldap/trunk/include/lber_pvt.h
===================================================================
--- openldap/trunk/include/lber_pvt.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/lber_pvt.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/lber_pvt.h,v 1.30.2.5 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/lber_pvt.h,v 1.35.2.3 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -145,6 +145,9 @@
 LBER_F( int )
 ber_bvarray_add_x LDAP_P(( BerVarray *p, BerValue *bv, void *ctx ));
 
+LBER_F( int )
+ber_bvarray_dup_x LDAP_P(( BerVarray *dst, BerVarray src, void *ctx ));
+
 #if 0
 #define ber_bvstrcmp(v1,v2) \
 	((v1)->bv_len < (v2)->bv_len \
@@ -172,26 +175,26 @@
 #define ber_bvrchr(bv,c) \
 	((char *) memrchr( (bv)->bv_val, (c), (bv)->bv_len ))
 
-#define ber_bvchr_right(dst,bv,c) \
+#define ber_bvchr_post(dst,bv,c) \
 	do { \
 		(dst)->bv_val = memchr( (bv)->bv_val, (c), (bv)->bv_len ); \
 		(dst)->bv_len = (dst)->bv_val ? (bv)->bv_len - ((dst)->bv_val - (bv)->bv_val) : 0; \
 	} while (0)
 
-#define ber_bvchr_left(dst,bv,c) \
+#define ber_bvchr_pre(dst,bv,c) \
 	do { \
 		(dst)->bv_val = memchr( (bv)->bv_val, (c), (bv)->bv_len ); \
 		(dst)->bv_len = (dst)->bv_val ? ((dst)->bv_val - (bv)->bv_val) : (bv)->bv_len; \
 		(dst)->bv_val = (bv)->bv_val; \
 	} while (0)
 
-#define ber_bvrchr_right(dst,bv,c) \
+#define ber_bvrchr_post(dst,bv,c) \
 	do { \
 		(dst)->bv_val = memrchr( (bv)->bv_val, (c), (bv)->bv_len ); \
 		(dst)->bv_len = (dst)->bv_val ? (bv)->bv_len - ((dst)->bv_val - (bv)->bv_val) : 0; \
 	} while (0)
 
-#define ber_bvrchr_left(dst,bv,c) \
+#define ber_bvrchr_pre(dst,bv,c) \
 	do { \
 		(dst)->bv_val = memrchr( (bv)->bv_val, (c), (bv)->bv_len ); \
 		(dst)->bv_len = (dst)->bv_val ? ((dst)->bv_val - (bv)->bv_val) : (bv)->bv_len; \

Modified: openldap/trunk/include/lber_types.hin
===================================================================
--- openldap/trunk/include/lber_types.hin	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/lber_types.hin	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/lber_types.hin,v 1.2.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/lber_types.hin,v 1.3.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ldap.h
===================================================================
--- openldap/trunk/include/ldap.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap.h,v 1.263.2.25 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap.h,v 1.312.2.8 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  * 
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -76,7 +76,7 @@
 #define LDAP_ALL_USER_ATTRIBUTES	"*"
 #define LDAP_ALL_OPERATIONAL_ATTRIBUTES	"+" /* RFC 3673 */
 
-/* RFC 2251:  maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) -- */
+/* RFC 4511:  maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) -- */
 #define LDAP_MAXINT (2147483647)
 
 /*
@@ -95,16 +95,17 @@
 #define LDAP_OPT_REFERRALS			0x0008
 #define LDAP_OPT_RESTART			0x0009
 /* 0x0a - 0x10 not defined */
-#define LDAP_OPT_PROTOCOL_VERSION	0x0011
-#define LDAP_OPT_SERVER_CONTROLS	0x0012
-#define LDAP_OPT_CLIENT_CONTROLS	0x0013
+#define LDAP_OPT_PROTOCOL_VERSION		0x0011
+#define LDAP_OPT_SERVER_CONTROLS		0x0012
+#define LDAP_OPT_CLIENT_CONTROLS		0x0013
 /* 0x14 not defined */
-#define LDAP_OPT_API_FEATURE_INFO	0x0015
+#define LDAP_OPT_API_FEATURE_INFO		0x0015
 /* 0x16 - 0x2f not defined */
 #define LDAP_OPT_HOST_NAME			0x0030
-#define LDAP_OPT_RESULT_CODE		0x0031
-#define LDAP_OPT_ERROR_NUMBER		LDAP_OPT_RESULT_CODE
-#define LDAP_OPT_ERROR_STRING		0x0032
+#define LDAP_OPT_RESULT_CODE			0x0031
+#define LDAP_OPT_ERROR_NUMBER			LDAP_OPT_RESULT_CODE
+#define LDAP_OPT_DIAGNOSTIC_MESSAGE		0x0032
+#define LDAP_OPT_ERROR_STRING			LDAP_OPT_DIAGNOSTIC_MESSAGE
 #define LDAP_OPT_MATCHED_DN			0x0033
 /* 0x0034 - 0x3fff not defined */
 
@@ -120,10 +121,12 @@
 #define LDAP_OPT_URI				0x5006
 #define LDAP_OPT_REFERRAL_URLS      0x5007  /* Referral URLs */
 #define LDAP_OPT_SOCKBUF            0x5008  /* sockbuf */
+#define LDAP_OPT_DEFBASE		0x5009	/* searchbase */
+#define	LDAP_OPT_CONNECT_ASYNC		0x5010	/* create connections asynchronously */
 
 /* OpenLDAP TLS options */
 #define LDAP_OPT_X_TLS				0x6000
-#define LDAP_OPT_X_TLS_CTX			0x6001	/* SSL CTX */
+#define LDAP_OPT_X_TLS_CTX			0x6001	/* OpenSSL CTX */
 #define LDAP_OPT_X_TLS_CACERTFILE	0x6002
 #define LDAP_OPT_X_TLS_CACERTDIR	0x6003
 #define LDAP_OPT_X_TLS_CERTFILE		0x6004
@@ -137,6 +140,8 @@
 #define LDAP_OPT_X_TLS_CONNECT_CB	0x600c
 #define LDAP_OPT_X_TLS_CONNECT_ARG	0x600d
 #define LDAP_OPT_X_TLS_DHFILE		0x600e
+#define LDAP_OPT_X_TLS_NEWCTX		0x600f
+#define LDAP_OPT_X_TLS_CRLFILE		0x6010	/* GNUtls only */
 
 #define LDAP_OPT_X_TLS_NEVER	0
 #define LDAP_OPT_X_TLS_HARD		1
@@ -209,11 +214,10 @@
 #define LDAP_CONTROL_SUBENTRIES		"1.3.6.1.4.1.4203.1.10.1"  /* RFC 3672 */
 
 #define LDAP_CONTROL_VALUESRETURNFILTER "1.2.826.0.1.3344810.2.3"/* RFC 3876 */
-#define LDAP_CONTROL_X_VALUESRETURNFILTER "1.2.826.0.1.334810.2.3"/* bad OID */
 
-#define LDAP_CONTROL_ASSERT				"1.3.6.1.1.12"			/* RFC TBD */
-#define LDAP_CONTROL_PRE_READ			"1.3.6.1.1.13.1"		/* RFC TBD */
-#define LDAP_CONTROL_POST_READ			"1.3.6.1.1.13.2"		/* RFC TBD */
+#define LDAP_CONTROL_ASSERT				"1.3.6.1.1.12"			/* RFC 4528 */
+#define LDAP_CONTROL_PRE_READ			"1.3.6.1.1.13.1"		/* RFC 4527 */
+#define LDAP_CONTROL_POST_READ			"1.3.6.1.1.13.2"		/* RFC 4527 */
 
 /*  standard track - not implemented in slapd(8) */
 #define LDAP_CONTROL_SORTREQUEST    "1.2.840.113556.1.4.473" /* RFC 2891 */
@@ -222,19 +226,7 @@
 /*	non-standard track controls */
 #define LDAP_CONTROL_PAGEDRESULTS	"1.2.840.113556.1.4.319"   /* RFC 2696 */
 
-/* Password policy Controls *//* work in progress */
-/* ITS#3458: released; disabled by default */
-#define LDAP_CONTROL_PASSWORDPOLICYREQUEST	"1.3.6.1.4.1.42.2.27.8.5.1"
-#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE	"1.3.6.1.4.1.42.2.27.8.5.1"
-
-/* various works in progress */
-#define LDAP_CONTROL_NOOP				"1.3.6.1.4.1.4203.666.5.2"
-#define LDAP_CONTROL_NO_SUBORDINATES	"1.3.6.1.4.1.4203.666.5.11"
-#define LDAP_CONTROL_MANAGEDIT			"1.3.6.1.4.1.4203.666.5.12"
-#define LDAP_CONTROL_SLURP				"1.3.6.1.4.1.4203.666.5.13"
-#define LDAP_CONTROL_VALSORT			"1.3.6.1.4.1.4203.666.5.14"
-
-/* LDAP Sync -- draft-zeilenga-ldup-sync *//* submitted for publication */
+/* LDAP Content Synchronization Operation -- RFC 4533 */
 #define LDAP_SYNC_OID			"1.3.6.1.4.1.4203.1.9.1"
 #define LDAP_CONTROL_SYNC		LDAP_SYNC_OID ".1"
 #define LDAP_CONTROL_SYNC_STATE	LDAP_SYNC_OID ".2"
@@ -264,17 +256,31 @@
 #define LDAP_SYNC_MODIFY				2
 #define LDAP_SYNC_DELETE				3
 
+
+/* Password policy Controls *//* work in progress */
+/* ITS#3458: released; disabled by default */
+#define LDAP_CONTROL_PASSWORDPOLICYREQUEST	"1.3.6.1.4.1.42.2.27.8.5.1"
+#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE	"1.3.6.1.4.1.42.2.27.8.5.1"
+
+/* various works in progress */
+#define LDAP_CONTROL_NOOP				"1.3.6.1.4.1.4203.666.5.2"
+#define LDAP_CONTROL_NO_SUBORDINATES	"1.3.6.1.4.1.4203.666.5.11"
+#define LDAP_CONTROL_RELAX				"1.3.6.1.4.1.4203.666.5.12"
+#define LDAP_CONTROL_MANAGEDIT			LDAP_CONTROL_RELAX
+#define LDAP_CONTROL_SLURP				"1.3.6.1.4.1.4203.666.5.13"
+#define LDAP_CONTROL_VALSORT			"1.3.6.1.4.1.4203.666.5.14"
+#define LDAP_CONTROL_DONTUSECOPY		"1.3.6.1.4.1.4203.666.5.15"
+
+
 /* LDAP Chaining Behavior Control *//* work in progress */
 /* <draft-sermersheim-ldap-chaining>;
  * see also LDAP_NO_REFERRALS_FOUND, LDAP_CANNOT_CHAIN */
-#ifdef LDAP_DEVEL
 #define LDAP_CONTROL_X_CHAINING_BEHAVIOR	"1.3.6.1.4.1.4203.666.11.3"
 
 #define	LDAP_CHAINING_PREFERRED				0
 #define	LDAP_CHAINING_REQUIRED				1
 #define LDAP_REFERRALS_PREFERRED			2
 #define LDAP_REFERRALS_REQUIRED				3
-#endif
 
 /* MS Active Directory controls (for compatibility) */
 #define LDAP_CONTROL_X_INCREMENTAL_VALUES	"1.2.840.113556.1.4.802"
@@ -283,11 +289,22 @@
 #define LDAP_CONTROL_X_SEARCH_OPTIONS		"1.2.840.113556.1.4.1340"
 #define LDAP_SEARCH_FLAG_DOMAIN_SCOPE 1 /* do not generate referrals */
 #define LDAP_SEARCH_FLAG_PHANTOM_ROOT 2 /* search all subordinate NCs */
+#define LDAP_CONTROL_X_TREE_DELETE		"1.2.840.113556.1.4.805"
 
 /* MS Active Directory controls - not implemented in slapd(8) */
-#define LDAP_CONTROL_X_TREE_DELETE		"1.2.840.113556.1.4.805"
 #define LDAP_CONTROL_X_EXTENDED_DN		"1.2.840.113556.1.4.529"
 
+#ifdef LDAP_DEVEL
+/* <draft-wahl-ldap-session> */
+#define LDAP_CONTROL_X_SESSION_TRACKING		"1.3.6.1.4.1.21008.108.63.1"
+#define LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_SESSION_ID \
+						LDAP_CONTROL_X_SESSION_TRACKING ".1"
+#define LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_MULTI_SESSION_ID \
+						LDAP_CONTROL_X_SESSION_TRACKING ".2"
+#define LDAP_CONTROL_X_SESSION_TRACKING_USERNAME \
+						LDAP_CONTROL_X_SESSION_TRACKING ".3"
+#endif /* LDAP_DEVEL */
+
 /* various expired works */
 /* LDAP Duplicated Entry Control Extension *//* not implemented in slapd(8) */
 #define LDAP_CONTROL_DUPENT_REQUEST		"2.16.840.1.113719.1.27.101.1"
@@ -298,10 +315,10 @@
 /* LDAP Persistent Search Control *//* not implemented in slapd(8) */
 #define LDAP_CONTROL_PERSIST_REQUEST				"2.16.840.1.113730.3.4.3"
 #define LDAP_CONTROL_PERSIST_ENTRY_CHANGE_NOTICE	"2.16.840.1.113730.3.4.7"
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_ADD		0x1
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_DELETE	0x2
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_MODIFY	0x4
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_RENAME	0x8
+#define LDAP_CONTROL_PERSIST_ENTRY_CHANGE_ADD		0x1
+#define LDAP_CONTROL_PERSIST_ENTRY_CHANGE_DELETE	0x2
+#define LDAP_CONTROL_PERSIST_ENTRY_CHANGE_MODIFY	0x4
+#define LDAP_CONTROL_PERSIST_ENTRY_CHANGE_RENAME	0x8
 
 /* LDAP VLV *//* not implemented in slapd(8) */
 #define LDAP_CONTROL_VLVREQUEST    	"2.16.840.1.113730.3.4.9"
@@ -309,11 +326,11 @@
 
 
 /* LDAP Unsolicited Notifications */
-#define	LDAP_NOTICE_OF_DISCONNECTION	"1.3.6.1.4.1.1466.20036" /* RFC 2251 */
+#define	LDAP_NOTICE_OF_DISCONNECTION	"1.3.6.1.4.1.1466.20036" /* RFC 4511 */
 #define LDAP_NOTICE_DISCONNECT LDAP_NOTICE_OF_DISCONNECTION
 
 /* LDAP Extended Operations */
-#define LDAP_EXOP_START_TLS		"1.3.6.1.4.1.1466.20037"	/* RFC 2830 */
+#define LDAP_EXOP_START_TLS		"1.3.6.1.4.1.1466.20037"	/* RFC 4511 */
 
 #define LDAP_EXOP_MODIFY_PASSWD	"1.3.6.1.4.1.4203.1.11.1"	/* RFC 3062 */
 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID	((ber_tag_t) 0x80U)
@@ -321,29 +338,43 @@
 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW	((ber_tag_t) 0x82U)
 #define LDAP_TAG_EXOP_MODIFY_PASSWD_GEN	((ber_tag_t) 0x80U)
 
-#define LDAP_EXOP_CANCEL		"1.3.6.1.1.8"				/* RFC 3909 */
+#define LDAP_EXOP_CANCEL		"1.3.6.1.1.8"					/* RFC 3909 */
 #define LDAP_EXOP_X_CANCEL		LDAP_EXOP_CANCEL
 
-/* various works in progress */
-#define LDAP_EXOP_WHO_AM_I		"1.3.6.1.4.1.4203.1.11.3"
+#define	LDAP_EXOP_REFRESH		"1.3.6.1.4.1.1466.101.119.1"	/* RFC 2589 */
+#define	LDAP_TAG_EXOP_REFRESH_REQ_DN	((ber_tag_t) 0x80U)
+#define	LDAP_TAG_EXOP_REFRESH_REQ_TTL	((ber_tag_t) 0x81U)
+#define	LDAP_TAG_EXOP_REFRESH_RES_TTL	((ber_tag_t) 0x80U)
+
+#define LDAP_EXOP_WHO_AM_I		"1.3.6.1.4.1.4203.1.11.3"		/* RFC 4532 */
 #define LDAP_EXOP_X_WHO_AM_I	LDAP_EXOP_WHO_AM_I
 
-#define LDAP_EXOP_X_TURN		"1.3.6.1.4.1.4203.666.6.4"
+/* various works in progress */
+#define LDAP_EXOP_TURN		"1.3.6.1.1.19"				/* RFC 4531 */
+#define LDAP_EXOP_X_TURN	LDAP_EXOP_TURN
 
-/* LDAP Grouping of Related Operations *//* a work in progress */
-#ifdef LDAP_DEVEL
-#define LDAP_X_GROUPING_BASE		"1.3.6.1.4.1.4203.666.10.3"
-#define LDAP_EXOP_GROUPING_CREATE	LDAP_X_GROUPING_BASE ".1"
-#define LDAP_EXOP_GROUPING_END		LDAP_X_GROUPING_BASE ".2"
-#define LDAP_NOTICE_GROUPING_END	LDAP_X_GROUPING_BASE ".3"
-#define LDAP_EXOP_GROUPING_ACTION	LDAP_X_GROUPING_BASE ".4"
-#define LDAP_NOTICE_GROUPING_INFO	LDAP_X_GROUPING_BASE ".5"
-#define LDAP_CONTROL_GROUPING		LDAP_X_GROUPING_BASE ".6"
-#endif
+/* LDAP Distributed Procedures <draft-sermersheim-ldap-distproc> */
+/* a work in progress */
+#define LDAP_X_DISTPROC_BASE		"1.3.6.1.4.1.4203.666.11.6"
+#define LDAP_EXOP_X_CHAINEDREQUEST	LDAP_X_DISTPROC_BASE ".1"
+#define LDAP_FEATURE_X_CANCHAINOPS	LDAP_X_DISTPROC_BASE ".2"
+#define LDAP_CONTROL_X_RETURNCONTREF	LDAP_X_DISTPROC_BASE ".3"
+#define LDAP_URLEXT_X_LOCALREFOID	LDAP_X_DISTPROC_BASE ".4"
+#define LDAP_URLEXT_X_REFTYPEOID	LDAP_X_DISTPROC_BASE ".5"
+#define LDAP_URLEXT_X_SEARCHEDSUBTREEOID \
+					LDAP_X_DISTPROC_BASE ".6"
+#define LDAP_URLEXT_X_FAILEDNAMEOID	LDAP_X_DISTPROC_BASE ".7"
+#define LDAP_URLEXT_X_LOCALREF		"x-localReference"
+#define LDAP_URLEXT_X_REFTYPE		"x-referenceType"
+#define LDAP_URLEXT_X_SEARCHEDSUBTREE	"x-searchedSubtree"
+#define LDAP_URLEXT_X_FAILEDNAME	"x-failedName"
 
-/* LDAP Grouping Types *//* a work in progress */
 #ifdef LDAP_DEVEL
-#define LDAP_GROUP_TRANSACTION		 "1.3.6.1.4.1.4203.666.10.4"
+#define LDAP_X_TXN						"1.3.6.1.4.1.4203.666.11.7" /* tmp */
+#define LDAP_EXOP_X_TXN_START			LDAP_X_TXN ".1"
+#define LDAP_CONTROL_X_TXN_SPEC			LDAP_X_TXN ".2"
+#define LDAP_EXOP_X_TXN_END				LDAP_X_TXN ".3"
+#define LDAP_EXOP_X_TXN_ABORTED_NOTICE	LDAP_X_TXN ".4"
 #endif
 
 /* LDAP Features */
@@ -355,12 +386,10 @@
 #define LDAP_FEATURE_LANGUAGE_RANGE_OPTIONS "1.3.6.1.4.1.4203.1.5.5"
 #define LDAP_FEATURE_MODIFY_INCREMENT "1.3.6.1.1.14"
 
-#ifdef LDAP_DEVEL
 /* LDAP Experimental (works in progress) Features */
 #define LDAP_FEATURE_SUBORDINATE_SCOPE \
 	"1.3.6.1.4.1.4203.666.8.1" /* "children" */
 #define LDAP_FEATURE_CHILDREN_SCOPE LDAP_FEATURE_SUBORDINATE_SCOPE
-#endif
 
 /*
  * specific LDAP instantiations of BER types we know about
@@ -535,7 +564,7 @@
 
 #define LDAP_SECURITY_ERROR(n)	LDAP_RANGE((n),0x2F,0x32) /* 47-50 */
 
-#define LDAP_PROXY_AUTHZ_FAILURE	0x2F /* LDAPv3 proxy authorization */
+#define LDAP_X_PROXY_AUTHZ_FAILURE	0x2F /* LDAPv3 proxy authorization */
 #define LDAP_INAPPROPRIATE_AUTH		0x30
 #define LDAP_INVALID_CREDENTIALS	0x31
 #define LDAP_INSUFFICIENT_ACCESS	0x32
@@ -576,6 +605,8 @@
 /* Assertion control (122) */ 
 #define LDAP_ASSERTION_FAILED		0x7A
 
+/* Proxied Authorization Denied (123) */ 
+#define LDAP_PROXIED_AUTHORIZATION_DENIED		0x7B
 
 /* Experimental result codes */
 #define LDAP_E_ERROR(n)	LDAP_RANGE((n),0x1000,0x3FFF)
@@ -597,10 +628,19 @@
  * see <draft-sermersheim-ldap-chaining> ) */
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 #define	LDAP_X_NO_REFERRALS_FOUND		0x4110
-#define LDAP_X_CANNOT_CHAIN				0x4111
+#define LDAP_X_CANNOT_CHAIN			0x4111
 #endif
 
+/* for Distributed Procedures (see <draft-sermersheim-ldap-distproc>) */
+#ifdef LDAP_X_DISTPROC_BASE
+#define LDAP_X_INVALIDREFERENCE			0x4112
+#endif
 
+#ifdef LDAP_X_TXN
+#define LDAP_X_TXN_SPECIFY_OKAY		0x4120
+#define LDAP_X_TXN_ID_INVALID		0x4121
+#endif
+
 /* API Error Codes
  *
  * Based on draft-ietf-ldap-c-api-xx
@@ -626,6 +666,7 @@
 #define LDAP_MORE_RESULTS_TO_RETURN		(-15)	/* Obsolete */
 #define LDAP_CLIENT_LOOP				(-16)
 #define LDAP_REFERRAL_LIMIT_EXCEEDED	(-17)
+#define	LDAP_X_CONNECTING			(-18)
 
 
 /*
@@ -709,6 +750,138 @@
 #define LDAP_URL_ERR_BADEXTS	0x0a	/* bad or missing extensions */
 
 /*
+ * LDAP sync (RFC4533) API
+ */
+
+typedef struct ldap_sync_t ldap_sync_t;
+
+typedef enum {
+	/* these are private - the client should never see them */
+	LDAP_SYNC_CAPI_NONE		= -1,
+
+	LDAP_SYNC_CAPI_PHASE_FLAG	= 0x10U,
+	LDAP_SYNC_CAPI_IDSET_FLAG	= 0x20U,
+	LDAP_SYNC_CAPI_DONE_FLAG	= 0x40U,
+
+	/* these are passed to ls_search_entry() */
+	LDAP_SYNC_CAPI_PRESENT		= LDAP_SYNC_PRESENT,
+	LDAP_SYNC_CAPI_ADD		= LDAP_SYNC_ADD,
+	LDAP_SYNC_CAPI_MODIFY		= LDAP_SYNC_MODIFY,
+	LDAP_SYNC_CAPI_DELETE		= LDAP_SYNC_DELETE,
+
+	/* these are passed to ls_intermediate() */
+	LDAP_SYNC_CAPI_PRESENTS		= ( LDAP_SYNC_CAPI_PHASE_FLAG | LDAP_SYNC_CAPI_PRESENT ),
+	LDAP_SYNC_CAPI_DELETES		= ( LDAP_SYNC_CAPI_PHASE_FLAG | LDAP_SYNC_CAPI_DELETE ),
+
+	LDAP_SYNC_CAPI_PRESENTS_IDSET	= ( LDAP_SYNC_CAPI_PRESENTS | LDAP_SYNC_CAPI_IDSET_FLAG ),
+	LDAP_SYNC_CAPI_DELETES_IDSET	= ( LDAP_SYNC_CAPI_DELETES | LDAP_SYNC_CAPI_IDSET_FLAG ),
+
+	LDAP_SYNC_CAPI_DONE		= ( LDAP_SYNC_CAPI_DONE_FLAG | LDAP_SYNC_CAPI_PRESENTS )
+} ldap_sync_refresh_t;
+
+/*
+ * Called when an entry is returned by ldap_result().
+ * If phase is LDAP_SYNC_CAPI_ADD or LDAP_SYNC_CAPI_MODIFY,
+ * the entry has been either added or modified, and thus
+ * the complete view of the entry should be in the LDAPMessage.
+ * If phase is LDAP_SYNC_CAPI_PRESENT or LDAP_SYNC_CAPI_DELETE,
+ * only the DN should be in the LDAPMessage.
+ */
+typedef int (*ldap_sync_search_entry_f) LDAP_P((
+	ldap_sync_t			*ls,
+	LDAPMessage			*msg,
+	struct berval			*entryUUID,
+	ldap_sync_refresh_t		phase ));
+
+/*
+ * Called when a reference is returned; the client should know 
+ * what to do with it.
+ */
+typedef int (*ldap_sync_search_reference_f) LDAP_P((
+	ldap_sync_t			*ls,
+	LDAPMessage			*msg ));
+
+/*
+ * Called when specific intermediate/final messages are returned.
+ * If phase is LDAP_SYNC_CAPI_PRESENTS or LDAP_SYNC_CAPI_DELETES,
+ * a "presents" or "deletes" phase begins.
+ * If phase is LDAP_SYNC_CAPI_DONE, a special "presents" phase
+ * with refreshDone set to "TRUE" has been returned, to indicate
+ * that the refresh phase of a refreshAndPersist is complete.
+ * In the above cases, syncUUIDs is NULL.
+ *
+ * If phase is LDAP_SYNC_CAPI_PRESENTS_IDSET or 
+ * LDAP_SYNC_CAPI_DELETES_IDSET, syncUUIDs is an array of UUIDs
+ * that are either present or have been deleted.
+ */
+typedef int (*ldap_sync_intermediate_f) LDAP_P((
+	ldap_sync_t			*ls,
+	LDAPMessage			*msg,
+	BerVarray			syncUUIDs,
+	ldap_sync_refresh_t		phase ));
+
+/*
+ * Called when a searchResultDone is returned.  In refreshAndPersist,
+ * this can only occur if the search for any reason is being terminated
+ * by the server.
+ */
+typedef int (*ldap_sync_search_result_f) LDAP_P((
+	ldap_sync_t			*ls,
+	LDAPMessage			*msg,
+	int				refreshDeletes ));
+
+/*
+ * This structure contains all information about the persistent search;
+ * the caller is responsible for connecting, setting version, binding, tls...
+ */
+struct ldap_sync_t {
+	/* conf search params */
+	char				*ls_base;
+	int				ls_scope;
+	char				*ls_filter;
+	char				**ls_attrs;
+	int				ls_timelimit;
+	int				ls_sizelimit;
+
+	/* poll timeout */
+	int				ls_timeout;
+
+	/* helpers - add as appropriate */
+	ldap_sync_search_entry_f	ls_search_entry;
+	ldap_sync_search_reference_f	ls_search_reference;
+	ldap_sync_intermediate_f	ls_intermediate;
+	ldap_sync_search_result_f	ls_search_result;
+
+	/* set by the caller as appropriate */
+	void				*ls_private;
+
+	/* conn stuff */
+	LDAP				*ls_ld;
+
+	/* --- the parameters below are private - do not modify --- */
+
+	/* FIXME: make the structure opaque, and provide an interface
+	 * to modify the public values? */
+
+	/* result stuff */
+	int				ls_msgid;
+
+	/* sync stuff */
+	/* needed by refreshOnly */
+	int				ls_reloadHint;
+
+	/* opaque - need to pass between sessions, updated by the API */
+	struct berval			ls_cookie;
+
+	/* state variable - do not modify */
+	ldap_sync_refresh_t		ls_refreshPhase;
+};
+
+/*
+ * End of LDAP sync (RFC4533) API
+ */
+
+/*
  * The API draft spec says we should declare (or cause to be declared)
  * 'struct timeval'.   We don't.  See IETF LDAPext discussions.
  */
@@ -752,21 +925,50 @@
 	LDAP_NEXTREF_PROC *nextref_proc,
 	void *params ));
 
+/* V3 URLLIST Function Callback Prototype */
+typedef int (LDAP_URLLIST_PROC) LDAP_P((
+	LDAP *ld, 
+	LDAPURLDesc **urllist,
+	LDAPURLDesc **url,
+	void *params ));
+
+LDAP_F( int )
+ldap_set_urllist_proc LDAP_P((
+	LDAP *ld,
+	LDAP_URLLIST_PROC *urllist_proc,
+	void *params ));
+
 /*
  * in controls.c:
  */
+#if LDAP_DEPRECATED	
 LDAP_F( int )
-ldap_create_control LDAP_P((
+ldap_create_control LDAP_P((	/* deprecated, use ldap_control_create */
 	LDAP_CONST char *requestOID,
 	BerElement *ber,
 	int iscritical,
 	LDAPControl **ctrlp ));
 
 LDAP_F( LDAPControl * )
-ldap_find_control LDAP_P((
+ldap_find_control LDAP_P((	/* deprecated, use ldap_control_find */
 	LDAP_CONST char *oid,
 	LDAPControl **ctrls ));
+#endif
 
+LDAP_F( int )
+ldap_control_create LDAP_P((
+	LDAP_CONST char *requestOID,
+	int iscritical,
+	struct berval *value,
+	int dupval,
+	LDAPControl **ctrlp ));
+
+LDAP_F( LDAPControl * )
+ldap_control_find LDAP_P((
+	LDAP_CONST char *oid,
+	LDAPControl **ctrls,
+	LDAPControl ***nextctrlp ));
+
 LDAP_F( void )
 ldap_control_free LDAP_P((
 	LDAPControl *ctrl ));
@@ -775,6 +977,14 @@
 ldap_controls_free LDAP_P((
 	LDAPControl **ctrls ));
 
+LDAP_F( LDAPControl ** )
+ldap_controls_dup LDAP_P((
+	LDAPControl *LDAP_CONST *controls ));
+
+LDAP_F( LDAPControl * )
+ldap_control_dup LDAP_P((
+	LDAP_CONST LDAPControl *c ));
+
 /*
  * in dnssrv.c:
  */
@@ -832,112 +1042,7 @@
 	LDAPControl		***serverctrls,
 	int				freeit ));
 
-/*
- * in groupings.c:
- */
-#ifdef LDAP_EXOP_GROUPING_CREATE
 
-LDAP_F( int )
-ldap_grouping_create LDAP_P((
-	LDAP			*ld,
-	LDAP_CONST char	*grpoid,
-	struct berval	*grpdata,
-	LDAPControl		**serverctrls,
-	LDAPControl		**clientctrls,
-	int				*msgidp ));
-
-LDAP_F( int )
-ldap_grouping_create_s LDAP_P((
-	LDAP			*ld,
-	LDAP_CONST char	*grpoid,
-	struct berval	*grpdata,
-	LDAPControl		**serverctrls,
-	LDAPControl		**clientctrls,
-	struct berval	**retgrpcookiep,
-	struct berval	**retgrpdatap ));
-
-LDAP_F( int )
-ldap_parse_grouping_create_result LDAP_P((
-	LDAP			*ld,
-	LDAPMessage		*res,
-	struct berval	**retgrpcookiep,
-	struct berval	**retgrpdatap,
-	LDAPControl		***serverctrls,
-	int				freeit ));
-
-LDAP_F( int )
-ldap_grouping_end LDAP_P((
-	LDAP			*ld,
-	LDAP_CONST char	*grpoid,
-	struct berval	*grpdata,
-	LDAPControl		**serverctrls,
-	LDAPControl		**clientctrls,
-	int				*msgidp ));
-
-LDAP_F( int )
-ldap_grouping_end_s LDAP_P((
-	LDAP			*ld,
-	LDAP_CONST char	*grpoid,
-	struct berval	*grpdata,
-	LDAPControl		**serverctrls,
-	LDAPControl		**clientctrls,
-	struct berval	**retgrpdatap ));
-
-LDAP_F( int )
-ldap_parse_grouping_end_result LDAP_P((
-	LDAP			*ld,
-	LDAPMessage		*res,
-	struct berval	**retgrpdatap,
-	LDAPControl		***serverctrls,
-	int				freeit ));
-
-LDAP_F( int )
-ldap_grouping_action_operation LDAP_P((
-	LDAP			*ld,
-	LDAP_CONST char	*grpoid,
-	struct berval	*grpdata,
-	LDAPControl		**serverctrls,
-	LDAPControl		**clientctrls,
-	int				*msgidp ));
-
-LDAP_F( int )
-ldap_grouping_action_operation_s LDAP_P((
-	LDAP			*ld,
-	LDAP_CONST char	*grpoid,
-	struct berval	*grpdata,
-	LDAPControl		**serverctrls,
-	LDAPControl		**clientctrls,
-	struct berval	**retgrpcookiep,
-	struct berval	**retgrpdatap ));
-
-LDAP_F( int )
-ldap_parse_grouping_action_result LDAP_P((
-	LDAP			*ld,
-	LDAPMessage		*res,
-	struct berval	**retgrpcookiep,
-	struct berval	**retgrpdatap,
-	LDAPControl		***serverctrls,
-	int				freeit ));
-
-LDAP_F( int )
-ldap_parse_grouping_end_notice LDAP_P((
-	LDAP			*ld,
-	LDAPMessage		*res,
-	struct berval	**retdatap,
-	struct berval	**retgrpcookiep,
-	struct berval	**retgrpdatap,
-	int				freeit ));
-
-LDAP_F( int )
-ldap_parse_grouping_info_notice LDAP_P((
-	LDAP			*ld,
-	LDAPMessage		*res,
-	struct berval	**retdatap,
-	struct berval	**retgrpcookiep,
-	struct berval	**retgrpdatap,
-	int				freeit ));
-#endif
-
 /*
  * in abandon.c:
  */
@@ -955,7 +1060,6 @@
 	int msgid ));
 #endif
 
-
 /*
  * in add.c:
  */
@@ -1085,35 +1189,6 @@
 	LDAP_CONST char *who,
 	LDAP_CONST char *passwd ));
 
-
-/*
- * in kbind.c:
- *	(deprecated - use SASL instead)
- */
-LDAP_F( int )
-ldap_kerberos_bind_s LDAP_P((	/* deprecated */
-	LDAP *ld,
-	LDAP_CONST char *who ));
-
-LDAP_F( int )
-ldap_kerberos_bind1 LDAP_P((	/* deprecated */
-	LDAP *ld,
-	LDAP_CONST char *who ));
-
-LDAP_F( int )
-ldap_kerberos_bind1_s LDAP_P((	/* deprecated */
-	LDAP *ld,
-	LDAP_CONST char *who ));
-
-LDAP_F( int )
-ldap_kerberos_bind2 LDAP_P((	/* deprecated */
-	LDAP *ld,
-	LDAP_CONST char *who ));
-
-LDAP_F( int )
-ldap_kerberos_bind2_s LDAP_P((	/* deprecated */
-	LDAP *ld,
-	LDAP_CONST char *who ));
 #endif
 
 
@@ -1643,7 +1718,7 @@
 	char **vals ));
 
 LDAP_F( void )
-ldap_value_free LDAP_P((	/* deprecated, use ldap_values_free_len */
+ldap_value_free LDAP_P((	/* deprecated, use ldap_value_free_len */
 	char **vals ));
 #endif
 
@@ -1913,119 +1988,125 @@
 	LDAPControl **cctrl ));
 
 /*
+ * LDAP Paged Results
+ *	in pagectrl.c
+ */
+#define LDAP_API_FEATURE_PAGED_RESULTS 2000
+
+LDAP_F( int )
+ldap_create_page_control_value LDAP_P((
+	LDAP *ld,
+	ber_int_t pagesize,
+	struct berval *cookie,
+	struct berval *value ));
+
+LDAP_F( int )
+ldap_create_page_control LDAP_P((
+	LDAP *ld,
+	ber_int_t pagesize,
+	struct berval *cookie,
+	int iscritical,
+	LDAPControl **ctrlp ));
+
+#if LDAP_DEPRECATED
+LDAP_F( int )
+ldap_parse_page_control LDAP_P((
+	/* deprecated, use ldap_parse_pageresponse_control */
+	LDAP *ld,
+	LDAPControl **ctrls,
+	ber_int_t *count,
+	struct berval **cookie ));
+#endif
+
+LDAP_F( int )
+ldap_parse_pageresponse_control LDAP_P((
+	LDAP *ld,
+	LDAPControl *ctrl,
+	ber_int_t *count,
+	struct berval *cookie ));
+
+/*
  * LDAP Server Side Sort
  *	in sortctrl.c
  */
-#define LDAP_API_FEATURE_SERVER_SIDE_SORT 1000
+#define LDAP_API_FEATURE_SERVER_SIDE_SORT 2000
 
 /* structure for a sort-key */
 typedef struct ldapsortkey {
-	char *  attributeType;
-	char *  orderingRule;
-	int     reverseOrder;
+	char *attributeType;
+	char *orderingRule;
+	int reverseOrder;
 } LDAPSortKey;
 
 LDAP_F( int )
 ldap_create_sort_keylist LDAP_P((
 	LDAPSortKey ***sortKeyList,
-	char        *keyString ));
+	char *keyString ));
 
 LDAP_F( void )
 ldap_free_sort_keylist LDAP_P((
 	LDAPSortKey **sortkeylist ));
 
 LDAP_F( int )
+ldap_create_sort_control_value LDAP_P((
+	LDAP *ld,
+	LDAPSortKey **keyList,
+	struct berval *value ));
+
+LDAP_F( int )
 ldap_create_sort_control LDAP_P((
 	LDAP *ld,
 	LDAPSortKey **keyList,
-	int ctl_iscritical,
+	int iscritical,
 	LDAPControl **ctrlp ));
 
 LDAP_F( int )
-ldap_parse_sort_control LDAP_P((
-	LDAP           *ld,
-	LDAPControl    **ctrlp,
-	unsigned long  *result,
-	char           **attribute ));
+ldap_parse_sortresponse_control LDAP_P((
+	LDAP *ld,
+	LDAPControl *ctrl,
+	ber_int_t *result,
+	char **attribute ));
 
-
 /*
  * LDAP Virtual List View
  *	in vlvctrl.c
  */
-#define LDAP_API_FEATURE_VIRTUAL_LIST_VIEW 1000
+#define LDAP_API_FEATURE_VIRTUAL_LIST_VIEW 2000
 
 /* structure for virtual list */
 typedef struct ldapvlvinfo {
-	int             ldvlv_version;
-    unsigned long   ldvlv_before_count;
-    unsigned long   ldvlv_after_count;
-    unsigned long   ldvlv_offset;
-    unsigned long   ldvlv_count;
+	ber_int_t ldvlv_version;
+    ber_int_t ldvlv_before_count;
+    ber_int_t ldvlv_after_count;
+    ber_int_t ldvlv_offset;
+    ber_int_t ldvlv_count;
     struct berval *	ldvlv_attrvalue;
     struct berval *	ldvlv_context;
     void *			ldvlv_extradata;
 } LDAPVLVInfo;
 
 LDAP_F( int )
+ldap_create_vlv_control_value LDAP_P((
+	LDAP *ld,
+	LDAPVLVInfo *ldvlistp,
+	struct berval *value));
+
+LDAP_F( int )
 ldap_create_vlv_control LDAP_P((
 	LDAP *ld,
 	LDAPVLVInfo *ldvlistp,
 	LDAPControl **ctrlp ));
 
 LDAP_F( int )
-ldap_parse_vlv_control LDAP_P((
+ldap_parse_vlvresponse_control LDAP_P((
 	LDAP          *ld,
-	LDAPControl   **ctrls,
-	unsigned long *target_posp,
-	unsigned long *list_countp,
+	LDAPControl   *ctrls,
+	ber_int_t *target_posp,
+	ber_int_t *list_countp,
 	struct berval **contextp,
 	int           *errcodep ));
 
 /*
- * LDAP Transactions
- *	in txn.c
- */
-#ifdef LDAP_GROUP_TRANSACTION
-LDAP_F( int )
-ldap_parse_txn_create LDAP_P((
-	LDAP *ld,
-	LDAPMessage *res,
-	struct berval **cookie ));
-
-LDAP_F( int )
-ldap_txn_create LDAP_P((
-	LDAP *ld,
-	LDAPControl		**sctrls,
-	LDAPControl		**cctrls,
-	int				*msgidp ));
-
-LDAP_F( int )
-ldap_txn_create_s LDAP_P((
-	LDAP *ld,
-	struct berval **cookie,
-	LDAPControl **sctrls,
-	LDAPControl **cctrls ));
-
-LDAP_F( int )
-ldap_txn_end LDAP_P((
-	LDAP *ld,
-	struct berval *cookie,
-	int commit,
-	LDAPControl		**sctrls,
-	LDAPControl		**cctrls,
-	int				*msgidp ));
-
-LDAP_F( int )
-ldap_txn_end_s LDAP_P((
-	LDAP *ld,
-	struct berval *cookie,
-	int commit,
-	LDAPControl **sctrls,
-	LDAPControl **cctrls ));
-#endif
-
-/*
  * LDAP Who Am I?
  *	in whoami.c
  */
@@ -2110,13 +2191,157 @@
 ldap_parse_passwordpolicy_control LDAP_P((
         LDAP *ld,
         LDAPControl *ctrl,
-        int *expirep,
-        int *gracep,
+        ber_int_t *expirep,
+        ber_int_t *gracep,
         LDAPPasswordPolicyError *errorp ));
 
 LDAP_F( const char * )
 ldap_passwordpolicy_err2txt LDAP_P(( LDAPPasswordPolicyError ));
 #endif /* LDAP_CONTROL_PASSWORDPOLICYREQUEST */
 
+/*
+ * LDAP Dynamic Directory Services Refresh -- RFC 2589
+ *	in dds.c
+ */
+#define LDAP_API_FEATURE_REFRESH 1000
+
+LDAP_F( int )
+ldap_parse_refresh LDAP_P((
+	LDAP *ld,
+	LDAPMessage *res,
+	ber_int_t *newttl ));
+
+LDAP_F( int )
+ldap_refresh LDAP_P(( LDAP *ld,
+	struct berval	*dn,
+	ber_int_t ttl,
+	LDAPControl		**sctrls,
+	LDAPControl		**cctrls,
+	int				*msgidp ));
+
+LDAP_F( int )
+ldap_refresh_s LDAP_P((
+	LDAP *ld,
+	struct berval	*dn,
+	ber_int_t ttl,
+	ber_int_t *newttl,
+	LDAPControl **sctrls,
+	LDAPControl **cctrls ));
+
+/*
+ * LDAP Transactions
+ */
+#ifdef LDAP_X_TXN
+LDAP_F( int )
+ldap_txn_start LDAP_P(( LDAP *ld,
+	LDAPControl		**sctrls,
+	LDAPControl		**cctrls,
+	int				*msgidp ));
+
+LDAP_F( int )
+ldap_txn_start_s LDAP_P(( LDAP *ld,
+	LDAPControl **sctrl,
+	LDAPControl **cctrl,
+	struct berval **rettxnid ));
+
+LDAP_F( int )
+ldap_txn_end LDAP_P(( LDAP *ld,
+	int	commit,
+	struct berval	*txnid,
+	LDAPControl		**sctrls,
+	LDAPControl		**cctrls,
+	int				*msgidp ));
+
+LDAP_F( int )
+ldap_txn_end_s LDAP_P(( LDAP *ld,
+	int	commit,
+	struct berval *txnid,
+	LDAPControl **sctrl,
+	LDAPControl **cctrl,
+	int *retidp ));
+#endif
+
+/*
+ * in ldap_sync.c
+ */
+
+/*
+ * initialize the persistent search structure
+ */
+LDAP_F( ldap_sync_t * )
+ldap_sync_initialize LDAP_P((
+	ldap_sync_t	*ls ));
+
+/*
+ * destroy the persistent search structure
+ */
+LDAP_F( void )
+ldap_sync_destroy LDAP_P((
+	ldap_sync_t	*ls,
+	int		freeit ));
+
+/*
+ * initialize a refreshOnly sync
+ */
+LDAP_F( int )
+ldap_sync_init LDAP_P((
+	ldap_sync_t	*ls,
+	int		mode ));
+
+/*
+ * initialize a refreshOnly sync
+ */
+LDAP_F( int )
+ldap_sync_init_refresh_only LDAP_P((
+	ldap_sync_t	*ls ));
+
+/*
+ * initialize a refreshAndPersist sync
+ */
+LDAP_F( int )
+ldap_sync_init_refresh_and_persist LDAP_P((
+	ldap_sync_t	*ls ));
+
+/*
+ * poll for new responses
+ */
+LDAP_F( int )
+ldap_sync_poll LDAP_P((
+	ldap_sync_t	*ls ));
+
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+
+/*
+ * in stctrl.c
+ */
+LDAP_F( int )
+ldap_create_session_tracking_value LDAP_P((
+	LDAP		*ld,
+	char		*sessionSourceIp,
+	char		*sessionSourceName,
+	char		*formatOID,
+	struct berval	*sessionTrackingIdentifier,
+	struct berval	*value ));
+
+LDAP_F( int )
+ldap_create_session_tracking LDAP_P((
+	LDAP		*ld,
+	char		*sessionSourceIp,
+	char		*sessionSourceName,
+	char		*formatOID,
+	struct berval	*sessionTrackingIdentifier,
+	LDAPControl	**ctrlp ));
+
+LDAP_F( int )
+ldap_parse_session_tracking_control LDAP_P((
+	LDAP *ld,
+	LDAPControl *ctrl,
+	struct berval *ip,
+	struct berval *name,
+	struct berval *oid,
+	struct berval *id ));
+
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
+
 LDAP_END_DECL
 #endif /* _LDAP_H */

Modified: openldap/trunk/include/ldap_cdefs.h
===================================================================
--- openldap/trunk/include/ldap_cdefs.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_cdefs.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_cdefs.h,v 1.26.2.4 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_cdefs.h,v 1.29.2.3 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  * 
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -157,11 +157,6 @@
 #	define LDAP_AVL_V(type)		extern type
 #endif
 
-/* LDBM library */
-/* Not exported/imported any more */
-#	define LDAP_LDBM_F(type)	extern type
-#	define LDAP_LDBM_V(type)	extern type
-
 /* LDIF library */
 #if defined(_WIN32) && defined(SLAPD_IMPORT)
 #	define LDAP_LDIF_F(type)	extern __declspec(dllimport) type

Modified: openldap/trunk/include/ldap_config.hin
===================================================================
--- openldap/trunk/include/ldap_config.hin	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_config.hin	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_config.hin,v 1.2.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_config.hin,v 1.3.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -59,6 +59,9 @@
 #ifndef LDAP_LIBEXECDIR
 #define LDAP_LIBEXECDIR		"%LIBEXECDIR%"
 #endif
+#ifndef LDAP_MODULEDIR
+#define LDAP_MODULEDIR		"%MODULEDIR%"
+#endif
 #ifndef LDAP_RUNDIR
 #define LDAP_RUNDIR			"%RUNDIR%"
 #endif

Modified: openldap/trunk/include/ldap_defaults.h
===================================================================
--- openldap/trunk/include/ldap_defaults.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_defaults.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_defaults.h,v 1.30.2.4 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_defaults.h,v 1.33.2.3 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  * 
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -56,8 +56,6 @@
 #define SLAPD_DEFAULT_SIZELIMIT		500
 	/* default timelimit to spend on a search */
 #define SLAPD_DEFAULT_TIMELIMIT		3600
-	/* minimum max ids that a single index entry can map to in ldbm */
-#define SLAPD_LDBM_MIN_MAXIDS		(8192-4)
 
 /* the following DNs must be normalized! */
 	/* dn of the default subschema subentry */

Modified: openldap/trunk/include/ldap_features.hin
===================================================================
--- openldap/trunk/include/ldap_features.hin	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_features.hin	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_features.hin,v 1.2.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_features.hin,v 1.3.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -54,9 +54,6 @@
 /* is -lldap_r available or not */
 #undef LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE
 
-/* LDAP v2 Kerberos Bind */
-#undef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-
 /* LDAP v2 Referrals */
 #undef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
 

Modified: openldap/trunk/include/ldap_int_thread.h
===================================================================
--- openldap/trunk/include/ldap_int_thread.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_int_thread.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldap_int_thread.h - ldap internal thread wrappers header file */
-/* $OpenLDAP: pkg/ldap/include/ldap_int_thread.h,v 1.13.2.4 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_int_thread.h,v 1.20.2.4 2007/11/07 20:58:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  * 
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -44,6 +44,7 @@
 typedef pthread_t		ldap_int_thread_t;
 typedef pthread_mutex_t		ldap_int_thread_mutex_t;
 typedef pthread_cond_t		ldap_int_thread_cond_t;
+typedef pthread_key_t		ldap_int_thread_key_t;
 
 #define ldap_int_thread_equal(a, b)	pthread_equal((a), (b))
 
@@ -63,7 +64,7 @@
 #define LDAP_THREAD_HAVE_SETCONCURRENCY 1
 #endif
 
-#if 0 && defined( HAVE_PTHREAD_RWLOCK_DESTROY )
+#if defined( HAVE_PTHREAD_RWLOCK_DESTROY )
 #define LDAP_THREAD_HAVE_RDWR 1
 typedef pthread_rwlock_t ldap_int_thread_rdwr_t;
 #endif
@@ -88,6 +89,7 @@
 typedef cthread_t		ldap_int_thread_t;
 typedef struct mutex		ldap_int_thread_mutex_t;
 typedef struct condition	ldap_int_thread_cond_t;
+typedef cthread_key_t		ldap_int_thread_key_t;
 
 LDAP_END_DECL
 
@@ -106,6 +108,7 @@
 typedef pth_t		ldap_int_thread_t;
 typedef pth_mutex_t	ldap_int_thread_mutex_t;
 typedef pth_cond_t	ldap_int_thread_cond_t;
+typedef pth_key_t	ldap_int_thread_key_t;
 
 #if 0
 #define LDAP_THREAD_HAVE_RDWR 1
@@ -129,6 +132,7 @@
 typedef thread_t		ldap_int_thread_t;
 typedef mutex_t			ldap_int_thread_mutex_t;
 typedef cond_t			ldap_int_thread_cond_t;
+typedef thread_key_t	ldap_int_thread_key_t;
 
 #define HAVE_REENTRANT_FUNCTIONS 1
 
@@ -181,6 +185,7 @@
 typedef unsigned long	ldap_int_thread_t;
 typedef HANDLE	ldap_int_thread_mutex_t;
 typedef HANDLE	ldap_int_thread_cond_t;
+typedef DWORD	ldap_int_thread_key_t;
 
 LDAP_END_DECL
 
@@ -201,6 +206,7 @@
 typedef int			ldap_int_thread_t;
 typedef int			ldap_int_thread_mutex_t;
 typedef int			ldap_int_thread_cond_t;
+typedef int			ldap_int_thread_key_t;
 
 #define LDAP_THREAD_HAVE_TPOOL 1
 typedef int			ldap_int_thread_pool_t;
@@ -227,6 +233,7 @@
 typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t;
 #endif
 
+typedef struct ldap_int_thread_rmutex_s * ldap_int_thread_rmutex_t;
 LDAP_END_DECL
 
 
@@ -247,14 +254,31 @@
 #define LDAP_UINTPTR_T	unsigned long
 #endif
 
-typedef union {
-	unsigned char			*ptr;
-	LDAP_UINTPTR_T			num;
+typedef enum {
+	ldap_debug_magic =	-(int) (((unsigned)-1)/19)
+} ldap_debug_magic_t;
+
+typedef enum {
+	/* Could fill in "locked" etc here later */
+	ldap_debug_state_inited = (int) (((unsigned)-1)/11),
+	ldap_debug_state_destroyed
+} ldap_debug_state_t;
+
+typedef struct {
+	/* Enclosed in magic numbers in the hope of catching overwrites */
+	ldap_debug_magic_t	magic;	/* bit pattern to recognize usages  */
+	LDAP_UINTPTR_T		self;	/* ~(LDAP_UINTPTR_T)&(this struct) */
+	union ldap_debug_mem_u {	/* Dummy memory reference */
+		unsigned char	*ptr;
+		LDAP_UINTPTR_T	num;
+	} mem;
+	ldap_debug_state_t	state;	/* doubles as another magic number */
 } ldap_debug_usage_info_t;
 
 typedef struct {
 	ldap_int_thread_mutex_t	wrapped;
 	ldap_debug_usage_info_t	usage;
+	ldap_int_thread_t	owner;
 } ldap_debug_thread_mutex_t;
 
 typedef struct {
@@ -267,6 +291,17 @@
 	ldap_debug_usage_info_t	usage;
 } ldap_debug_thread_rdwr_t;
 
+#ifndef NDEBUG
+#define	LDAP_INT_THREAD_ASSERT_MUTEX_OWNER(mutex) \
+	ldap_debug_thread_assert_mutex_owner( \
+		__FILE__, __LINE__, "owns(" #mutex ")", mutex )
+LDAP_F(void) ldap_debug_thread_assert_mutex_owner LDAP_P((
+	LDAP_CONST char *file,
+	int line,
+	LDAP_CONST char *msg,
+	ldap_debug_thread_mutex_t *mutex ));
+#endif /* NDEBUG */
+
 LDAP_END_DECL
 
 #endif /* LDAP_THREAD_DEBUG_WRAP */

Modified: openldap/trunk/include/ldap_log.h
===================================================================
--- openldap/trunk/include/ldap_log.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_log.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_log.h,v 1.35.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_log.h,v 1.40.2.4 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  * 
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -23,8 +23,8 @@
  * is provided ``as is'' without express or implied warranty.
  */
 
-#ifndef _LDAP_LOG_H
-#define _LDAP_LOG_H
+#ifndef LDAP_LOG_H
+#define LDAP_LOG_H
 
 #include <stdio.h>
 #include <ldap_cdefs.h>
@@ -39,19 +39,71 @@
  * debugging levels begin with LDAP_LEVEL_ENTRY
  *
  */
-#define LDAP_LEVEL_EMERG       0
-#define LDAP_LEVEL_ALERT       1
-#define LDAP_LEVEL_CRIT        2
-#define LDAP_LEVEL_ERR         3
-#define LDAP_LEVEL_WARNING     4
-#define LDAP_LEVEL_NOTICE      5
-#define LDAP_LEVEL_INFO        6
-#define LDAP_LEVEL_ENTRY       7  /* log function entry points */
-#define LDAP_LEVEL_ARGS        8  /* log function call parameters */
-#define LDAP_LEVEL_RESULTS     9  /* Log function results */
-#define LDAP_LEVEL_DETAIL1    10  /* log level 1 function operational details */
-#define LDAP_LEVEL_DETAIL2    11  /* Log level 2 function operational details */
 
+/*
+ * The "OLD_DEBUG" means that all logging occurs at LOG_DEBUG
+ */
+
+#ifdef OLD_DEBUG
+/* original behavior: all logging occurs at the same severity level */
+#if defined(LDAP_DEBUG) && defined(LDAP_SYSLOG)
+#define LDAP_LEVEL_EMERG	ldap_syslog_level
+#define LDAP_LEVEL_ALERT	ldap_syslog_level
+#define LDAP_LEVEL_CRIT		ldap_syslog_level
+#define LDAP_LEVEL_ERR		ldap_syslog_level
+#define LDAP_LEVEL_WARNING	ldap_syslog_level
+#define LDAP_LEVEL_NOTICE	ldap_syslog_level
+#define LDAP_LEVEL_INFO		ldap_syslog_level
+#define LDAP_LEVEL_DEBUG	ldap_syslog_level
+#else /* !LDAP_DEBUG || !LDAP_SYSLOG */
+#define LDAP_LEVEL_EMERG	(7)
+#define LDAP_LEVEL_ALERT	(7)
+#define LDAP_LEVEL_CRIT		(7)
+#define LDAP_LEVEL_ERR		(7)
+#define LDAP_LEVEL_WARNING	(7)
+#define LDAP_LEVEL_NOTICE	(7)
+#define LDAP_LEVEL_INFO		(7)
+#define LDAP_LEVEL_DEBUG	(7)
+#endif /* !LDAP_DEBUG || !LDAP_SYSLOG */
+
+#else /* ! OLD_DEBUG */
+/* map syslog onto LDAP severity levels */
+#ifdef LOG_DEBUG
+#define LDAP_LEVEL_EMERG	LOG_EMERG
+#define LDAP_LEVEL_ALERT	LOG_ALERT
+#define LDAP_LEVEL_CRIT		LOG_CRIT
+#define LDAP_LEVEL_ERR		LOG_ERR
+#define LDAP_LEVEL_WARNING	LOG_WARNING
+#define LDAP_LEVEL_NOTICE	LOG_NOTICE
+#define LDAP_LEVEL_INFO		LOG_INFO
+#define LDAP_LEVEL_DEBUG	LOG_DEBUG
+#else /* ! LOG_DEBUG */
+#define LDAP_LEVEL_EMERG	(0)
+#define LDAP_LEVEL_ALERT	(1)
+#define LDAP_LEVEL_CRIT		(2)
+#define LDAP_LEVEL_ERR		(3)
+#define LDAP_LEVEL_WARNING	(4)
+#define LDAP_LEVEL_NOTICE	(5)
+#define LDAP_LEVEL_INFO		(6)
+#define LDAP_LEVEL_DEBUG	(7)
+#endif /* ! LOG_DEBUG */
+#endif /* ! OLD_DEBUG */
+#if 0
+/* in case we need to reuse the unused bits of severity */
+#define	LDAP_LEVEL_MASK(s)	((s) & 0x7)
+#else
+#define	LDAP_LEVEL_MASK(s)	(s)
+#endif
+
+/* (yet) unused */
+#define LDAP_LEVEL_ENTRY	(0x08)	/* log function entry points */
+#define LDAP_LEVEL_ARGS		(0x10)	/* log function call parameters */
+#define LDAP_LEVEL_RESULTS	(0x20)	/* Log function results */
+#define LDAP_LEVEL_DETAIL1	(0x40)	/* log level 1 function operational details */
+#define LDAP_LEVEL_DETAIL2	(0x80)	/* Log level 2 function operational details */
+/* end of (yet) unused */
+
+/* original subsystem selection mechanism */
 #define LDAP_DEBUG_TRACE	0x0001
 #define LDAP_DEBUG_PACKETS	0x0002
 #define LDAP_DEBUG_ARGS		0x0004
@@ -64,8 +116,10 @@
 #define LDAP_DEBUG_STATS2	0x0200
 #define LDAP_DEBUG_SHELL	0x0400
 #define LDAP_DEBUG_PARSE	0x0800
-#define LDAP_DEBUG_CACHE    0x1000
-#define LDAP_DEBUG_INDEX    0x2000
+#if 0 /* no longer used (nor supported) */
+#define LDAP_DEBUG_CACHE	0x1000
+#define LDAP_DEBUG_INDEX	0x2000
+#endif
 #define LDAP_DEBUG_SYNC		0x4000
 
 #define LDAP_DEBUG_NONE		0x8000
@@ -77,49 +131,117 @@
      * This is a bogus extern declaration for the compiler. No need to ensure
      * a 'proper' dllimport.
      */
-#   ifndef ldap_debug
-     extern int	ldap_debug;
-#   endif /* !ldap_debug */
+#ifndef ldap_debug
+extern int	ldap_debug;
+#endif /* !ldap_debug */
 
-#   ifdef LDAP_SYSLOG
-    extern int	ldap_syslog;
-    extern int	ldap_syslog_level;
+#ifdef LDAP_SYSLOG
+extern int	ldap_syslog;
+extern int	ldap_syslog_level;
 
-#	ifdef HAVE_EBCDIC
-#	define syslog	eb_syslog
-	extern void eb_syslog(int pri, const char *fmt, ...);
-#	endif
+#ifdef HAVE_EBCDIC
+#define syslog	eb_syslog
+extern void eb_syslog(int pri, const char *fmt, ...);
+#endif /* HAVE_EBCDIC */
 
-#   endif /* LDAP_SYSLOG */
+#endif /* LDAP_SYSLOG */
 
 /* this doesn't below as part of ldap.h */
-#   ifdef LDAP_SYSLOG
-#   define Debug( level, fmt, arg1, arg2, arg3 )	\
+#ifdef LDAP_SYSLOG
+#define Log0( level, severity, fmt )	\
 	do { \
 		if ( ldap_debug & (level) ) \
+			lutil_debug( ldap_debug, (level), (fmt) ); \
+		if ( ldap_syslog & (level) ) \
+			syslog( LDAP_LEVEL_MASK((severity)), (fmt) ); \
+	} while ( 0 )
+#define Log1( level, severity, fmt, arg1 )	\
+	do { \
+		if ( ldap_debug & (level) ) \
+			lutil_debug( ldap_debug, (level), (fmt), (arg1) ); \
+		if ( ldap_syslog & (level) ) \
+			syslog( LDAP_LEVEL_MASK((severity)), (fmt), (arg1) ); \
+	} while ( 0 )
+#define Log2( level, severity, fmt, arg1, arg2 ) \
+	do { \
+		if ( ldap_debug & (level) ) \
+			lutil_debug( ldap_debug, (level), (fmt), (arg1), (arg2) ); \
+		if ( ldap_syslog & (level) ) \
+			syslog( LDAP_LEVEL_MASK((severity)), (fmt), (arg1), (arg2) ); \
+	} while ( 0 )
+#define Log3( level, severity, fmt, arg1, arg2, arg3 ) \
+	do { \
+		if ( ldap_debug & (level) ) \
 			lutil_debug( ldap_debug, (level), (fmt), (arg1), (arg2), (arg3) ); \
 		if ( ldap_syslog & (level) ) \
-			syslog( ldap_syslog_level, (fmt), (arg1), (arg2), (arg3) ); \
+			syslog( LDAP_LEVEL_MASK((severity)), (fmt), (arg1), (arg2), (arg3) ); \
 	} while ( 0 )
+#define Log4( level, severity, fmt, arg1, arg2, arg3, arg4 ) \
+	do { \
+		if ( ldap_debug & (level) ) \
+			lutil_debug( ldap_debug, (level), (fmt), (arg1), (arg2), (arg3), (arg4) ); \
+		if ( ldap_syslog & (level) ) \
+			syslog( LDAP_LEVEL_MASK((severity)), (fmt), (arg1), (arg2), (arg3), (arg4) ); \
+	} while ( 0 )
+#define Log5( level, severity, fmt, arg1, arg2, arg3, arg4, arg5 ) \
+	do { \
+		if ( ldap_debug & (level) ) \
+			lutil_debug( ldap_debug, (level), (fmt), (arg1), (arg2), (arg3), (arg4), (arg5) ); \
+		if ( ldap_syslog & (level) ) \
+			syslog( LDAP_LEVEL_MASK((severity)), (fmt), (arg1), (arg2), (arg3), (arg4), (arg5) ); \
+	} while ( 0 )
+#define Debug( level, fmt, arg1, arg2, arg3 )	\
+	Log3( (level), ldap_syslog_level, (fmt), (arg1), (arg2), (arg3) )
+#define LogTest(level) ( ( ldap_debug | ldap_syslog ) & (level) )
 
-#   else
-#       define Debug( level, fmt, arg1, arg2, arg3 ) \
+#else /* ! LDAP_SYSLOG */
+#define Log0( level, severity, fmt ) \
 	do { \
 		if ( ldap_debug & (level) ) \
+	    		lutil_debug( ldap_debug, (level), (fmt) ); \
+	} while ( 0 )
+#define Log1( level, severity, fmt, arg1 ) \
+	do { \
+		if ( ldap_debug & (level) ) \
+	    		lutil_debug( ldap_debug, (level), (fmt), (arg1) ); \
+	} while ( 0 )
+#define Log2( level, severity, fmt, arg1, arg2 ) \
+	do { \
+		if ( ldap_debug & (level) ) \
+	    		lutil_debug( ldap_debug, (level), (fmt), (arg1), (arg2) ); \
+	} while ( 0 )
+#define Log3( level, severity, fmt, arg1, arg2, arg3 ) \
+	do { \
+		if ( ldap_debug & (level) ) \
 	    		lutil_debug( ldap_debug, (level), (fmt), (arg1), (arg2), (arg3) ); \
 	} while ( 0 )
-#   endif
+#define Log4( level, severity, fmt, arg1, arg2, arg3, arg4 ) \
+	do { \
+		if ( ldap_debug & (level) ) \
+	    		lutil_debug( ldap_debug, (level), (fmt), (arg1), (arg2), (arg3), (arg4) ); \
+	} while ( 0 )
+#define Log5( level, severity, fmt, arg1, arg2, arg3, arg4, arg5 ) \
+	do { \
+		if ( ldap_debug & (level) ) \
+	    		lutil_debug( ldap_debug, (level), (fmt), (arg1), (arg2), (arg3), (arg4), (arg5) ); \
+	} while ( 0 )
+#define Debug( level, fmt, arg1, arg2, arg3 ) \
+		Log3( (level), 0, (fmt), (arg1), (arg2), (arg3) )
+#define LogTest(level) ( ldap_debug & (level) )
+#endif /* ! LDAP_SYSLOG */
+#else /* ! LDAP_DEBUG */
+/* TODO: in case LDAP_DEBUG is undefined, make sure logs with appropriate
+ * severity gets thru anyway */
+#define Log0( level, severity, fmt ) ((void)0)
+#define Log1( level, severity, fmt, arg1 ) ((void)0)
+#define Log2( level, severity, fmt, arg1, arg2 ) ((void)0)
+#define Log3( level, severity, fmt, arg1, arg2, arg3 ) ((void)0)
+#define Log4( level, severity, fmt, arg1, arg2, arg3, arg4 ) ((void)0)
+#define Log5( level, severity, fmt, arg1, arg2, arg3, arg4, arg5 ) ((void)0)
+#define Debug( level, fmt, arg1, arg2, arg3 ) ((void)0)
+#define LogTest(level) ( 0 )
+#endif /* ! LDAP_DEBUG */
 
-#else /* LDAP_DEBUG */
-#   define Debug( level, fmt, arg1, arg2, arg3 )
-
-#endif /* LDAP_DEBUG */
-
-#ifndef LDAP_LOG
-#define LDAP_LOG(a, b, fmt, arg1, arg2, arg3)
-#define LDAP_LOGS_TEST(a, b) 0
-#endif
-
 LDAP_LUTIL_F(int) lutil_debug_file LDAP_P(( FILE *file ));
 
 LDAP_LUTIL_F(void) lutil_debug LDAP_P((
@@ -128,4 +250,4 @@
 
 LDAP_END_DECL
 
-#endif /* _LDAP_LOG_H */
+#endif /* LDAP_LOG_H */

Modified: openldap/trunk/include/ldap_pvt.h
===================================================================
--- openldap/trunk/include/ldap_pvt.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_pvt.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_pvt.h,v 1.82.2.8 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_pvt.h,v 1.91.2.4 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  * 
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -27,6 +27,7 @@
 #define LDAP_PROTO_TCP 1 /* ldap://  */
 #define LDAP_PROTO_UDP 2 /* reserved */
 #define LDAP_PROTO_IPC 3 /* ldapi:// */
+#define LDAP_PROTO_EXT 4 /* user-defined socket/sockbuf */
 
 LDAP_F ( int )
 ldap_pvt_url_scheme2proto LDAP_P((
@@ -41,11 +42,49 @@
 
 struct ldap_url_desc; /* avoid pulling in <ldap.h> */
 
+#define LDAP_PVT_URL_PARSE_NONE			(0x00U)
+#define LDAP_PVT_URL_PARSE_NOEMPTY_HOST		(0x01U)
+#define LDAP_PVT_URL_PARSE_DEF_PORT		(0x02U)
+#define LDAP_PVT_URL_PARSE_NOEMPTY_DN		(0x04U)
+#define LDAP_PVT_URL_PARSE_NODEF_SCOPE		(0x08U)
+#define	LDAP_PVT_URL_PARSE_HISTORIC		(LDAP_PVT_URL_PARSE_NODEF_SCOPE | \
+						 LDAP_PVT_URL_PARSE_NOEMPTY_HOST | \
+						 LDAP_PVT_URL_PARSE_DEF_PORT)
+
 LDAP_F( int )
 ldap_url_parse_ext LDAP_P((
 	LDAP_CONST char *url,
-	struct ldap_url_desc **ludpp ));
+	struct ldap_url_desc **ludpp,
+	unsigned flags ));
 
+LDAP_F (int) ldap_url_parselist LDAP_P((	/* deprecated, use ldap_url_parselist_ext() */
+	struct ldap_url_desc **ludlist,
+	const char *url ));
+
+LDAP_F (int) ldap_url_parselist_ext LDAP_P((
+	struct ldap_url_desc **ludlist,
+	const char *url,
+	const char *sep,
+	unsigned flags ));
+
+LDAP_F (char *) ldap_url_list2urls LDAP_P((
+	struct ldap_url_desc *ludlist ));
+
+LDAP_F (void) ldap_free_urllist LDAP_P((
+	struct ldap_url_desc *ludlist ));
+
+LDAP_F (int) ldap_pvt_scope2bv LDAP_P ((
+	int scope, struct berval *bv ));
+
+LDAP_F (LDAP_CONST char *) ldap_pvt_scope2str LDAP_P ((
+	int scope ));
+
+LDAP_F (int) ldap_pvt_bv2scope LDAP_P ((
+	struct berval *bv ));
+
+LDAP_F (int) ldap_pvt_str2scope LDAP_P ((
+	LDAP_CONST char * ));
+
 LDAP_F( char * )
 ldap_pvt_ctime LDAP_P((
 	const time_t *tp,
@@ -156,12 +195,10 @@
 
 /* controls.c */
 struct ldapcontrol;
-LDAP_F (struct ldapcontrol *) ldap_control_dup LDAP_P((
-	const struct ldapcontrol *ctrl ));
-
-LDAP_F (struct ldapcontrol **) ldap_controls_dup LDAP_P((
-	struct ldapcontrol *const *ctrls ));
-
+LDAP_F (int)
+ldap_pvt_put_control LDAP_P((
+	const struct ldapcontrol *c,
+	BerElement *ber ));
 LDAP_F (int) ldap_pvt_get_controls LDAP_P((
 	BerElement *be,
 	struct ldapcontrol ***ctrlsp));
@@ -193,14 +230,21 @@
 struct ldap;
 struct ldapmsg;
 
-LDAP_F (int) ldap_open_internal_connection LDAP_P((
-	struct ldap **ldp, ber_socket_t *fdp ));
+/* abandon */
+LDAP_F ( int ) ldap_pvt_discard LDAP_P((
+	struct ldap *ld, ber_int_t msgid ));
 
 /* messages.c */
 LDAP_F( BerElement * )
 ldap_get_message_ber LDAP_P((
 	struct ldapmsg * ));
 
+/* open */
+LDAP_F (int) ldap_open_internal_connection LDAP_P((
+	struct ldap **ldp, ber_socket_t *fdp ));
+LDAP_F (int) ldap_init_fd LDAP_P((
+	ber_socket_t fd, int proto, LDAP_CONST char *url, struct ldap **ldp ));
+
 /* search.c */
 LDAP_F( int ) ldap_pvt_put_filter LDAP_P((
 	BerElement *ber,
@@ -246,9 +290,8 @@
 LDAP_F (int) ldap_pvt_tls_accept LDAP_P(( Sockbuf *sb, void *ctx_arg ));
 LDAP_F (int) ldap_pvt_tls_inplace LDAP_P(( Sockbuf *sb ));
 LDAP_F (void *) ldap_pvt_tls_sb_ctx LDAP_P(( Sockbuf *sb ));
+LDAP_F (void) ldap_pvt_tls_ctx_free LDAP_P(( void * ));
 
-LDAP_F (int) ldap_pvt_tls_init_default_ctx LDAP_P(( void ));
-
 typedef int LDAPDN_rewrite_dummy LDAP_P (( void *dn, unsigned flags ));
 
 typedef int (LDAP_TLS_CONNECT_CB) LDAP_P (( struct ldap *ld, void *ssl,
@@ -273,7 +316,7 @@
  * If none is available, unsigned long data is used.
  */
 
-#if USE_MP_BIGNUM
+#ifdef USE_MP_BIGNUM
 /*
  * Use OpenSSL's BIGNUM
  */
@@ -299,7 +342,7 @@
 #define ldap_pvt_mp_clear(mp) \
 	do { BN_free((mp)); (mp) = 0; } while (0)
 
-#elif USE_MP_GMP
+#elif defined(USE_MP_GMP)
 /*
  * Use GNU's multiple precision library
  */
@@ -328,13 +371,13 @@
  * Use unsigned long long
  */
 
-#if USE_MP_LONG_LONG
+#ifdef USE_MP_LONG_LONG
 typedef	unsigned long long	ldap_pvt_mp_t;
 #define	LDAP_PVT_MP_INIT	(0LL)
-#elif USE_MP_LONG
+#elif defined(USE_MP_LONG)
 typedef	unsigned long		ldap_pvt_mp_t;
 #define	LDAP_PVT_MP_INIT	(0L)
-#elif HAVE_LONG_LONG
+#elif defined(HAVE_LONG_LONG)
 typedef	unsigned long long	ldap_pvt_mp_t;
 #define	LDAP_PVT_MP_INIT	(0LL)
 #else

Modified: openldap/trunk/include/ldap_pvt_thread.h
===================================================================
--- openldap/trunk/include/ldap_pvt_thread.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_pvt_thread.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldap_pvt_thread.h - ldap threads header file */
-/* $OpenLDAP: pkg/ldap/include/ldap_pvt_thread.h,v 1.41.2.7 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_pvt_thread.h,v 1.51.2.6 2007/11/07 20:58:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  * 
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -33,6 +33,8 @@
 typedef ldap_int_thread_cond_t		ldap_pvt_thread_cond_t;
 typedef ldap_int_thread_rdwr_t		ldap_pvt_thread_rdwr_t;
 #endif
+typedef ldap_int_thread_rmutex_t	ldap_pvt_thread_rmutex_t;
+typedef ldap_int_thread_key_t	ldap_pvt_thread_key_t;
 #endif /* !LDAP_PVT_THREAD_H_DONE */
 
 #define ldap_pvt_thread_equal		ldap_int_thread_equal
@@ -117,9 +119,33 @@
 LDAP_F( int )
 ldap_pvt_thread_mutex_unlock LDAP_P(( ldap_pvt_thread_mutex_t *mutex ));
 
+LDAP_F( int )
+ldap_pvt_thread_rmutex_init LDAP_P(( ldap_pvt_thread_rmutex_t *rmutex ));
+
+LDAP_F( int )
+ldap_pvt_thread_rmutex_destroy LDAP_P(( ldap_pvt_thread_rmutex_t *rmutex ));
+
+LDAP_F( int )
+ldap_pvt_thread_rmutex_lock LDAP_P(( ldap_pvt_thread_rmutex_t *rmutex,
+	ldap_pvt_thread_t owner));
+
+LDAP_F( int )
+ldap_pvt_thread_rmutex_trylock LDAP_P(( ldap_pvt_thread_rmutex_t *rmutex,
+	ldap_pvt_thread_t owner));
+
+LDAP_F( int )
+ldap_pvt_thread_rmutex_unlock LDAP_P(( ldap_pvt_thread_rmutex_t *rmutex,
+	ldap_pvt_thread_t owner));
+
 LDAP_F( ldap_pvt_thread_t )
 ldap_pvt_thread_self LDAP_P(( void ));
 
+#ifdef	LDAP_INT_THREAD_ASSERT_MUTEX_OWNER
+#define	LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER LDAP_INT_THREAD_ASSERT_MUTEX_OWNER
+#else
+#define	LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER(mutex) ((void) 0)
+#endif
+
 LDAP_F( int )
 ldap_pvt_thread_rdwr_init LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
@@ -144,6 +170,18 @@
 LDAP_F( int )
 ldap_pvt_thread_rdwr_wunlock LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
+LDAP_F( int )
+ldap_pvt_thread_key_create LDAP_P((ldap_pvt_thread_key_t *keyp));
+
+LDAP_F( int )
+ldap_pvt_thread_key_destroy LDAP_P((ldap_pvt_thread_key_t key));
+
+LDAP_F( int )
+ldap_pvt_thread_key_setdata LDAP_P((ldap_pvt_thread_key_t key, void *data));
+
+LDAP_F( int )
+ldap_pvt_thread_key_getdata LDAP_P((ldap_pvt_thread_key_t key, void **data));
+
 #ifdef LDAP_DEBUG
 LDAP_F( int )
 ldap_pvt_thread_rdwr_readers LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
@@ -182,7 +220,30 @@
 	ldap_pvt_thread_pool_t *pool,
 	int max_threads ));
 
+#ifndef LDAP_PVT_THREAD_H_DONE
+typedef enum {
+	LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN = -1,
+	LDAP_PVT_THREAD_POOL_PARAM_MAX,
+	LDAP_PVT_THREAD_POOL_PARAM_MAX_PENDING,
+	LDAP_PVT_THREAD_POOL_PARAM_OPEN,
+	LDAP_PVT_THREAD_POOL_PARAM_STARTING,
+	LDAP_PVT_THREAD_POOL_PARAM_ACTIVE,
+	LDAP_PVT_THREAD_POOL_PARAM_PAUSING,
+	LDAP_PVT_THREAD_POOL_PARAM_PENDING,
+	LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD,
+	LDAP_PVT_THREAD_POOL_PARAM_ACTIVE_MAX,
+	LDAP_PVT_THREAD_POOL_PARAM_PENDING_MAX,
+	LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD_MAX,
+	LDAP_PVT_THREAD_POOL_PARAM_STATE
+} ldap_pvt_thread_pool_param_t;
+#endif /* !LDAP_PVT_THREAD_H_DONE */
+
 LDAP_F( int )
+ldap_pvt_thread_pool_query LDAP_P((
+	ldap_pvt_thread_pool_t *pool,
+	ldap_pvt_thread_pool_param_t param, void *value ));
+
+LDAP_F( int )
 ldap_pvt_thread_pool_backload LDAP_P((
 	ldap_pvt_thread_pool_t *pool ));
 
@@ -222,7 +283,10 @@
 LDAP_F( void )
 ldap_pvt_thread_pool_context_reset LDAP_P(( void *key ));
 
+LDAP_F( ldap_pvt_thread_t )
+ldap_pvt_thread_pool_tid LDAP_P(( void *ctx ));
+
 LDAP_END_DECL
 
 #define LDAP_PVT_THREAD_H_DONE
-#endif /* _LDAP_THREAD_H */
+#endif /* _LDAP_PVT_THREAD_H */

Modified: openldap/trunk/include/ldap_pvt_uc.h
===================================================================
--- openldap/trunk/include/ldap_pvt_uc.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_pvt_uc.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_pvt_uc.h,v 1.28.2.4 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_pvt_uc.h,v 1.31.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ldap_queue.h
===================================================================
--- openldap/trunk/include/ldap_queue.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_queue.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldap_queue.h -- queue macros */
-/* $OpenLDAP: pkg/ldap/include/ldap_queue.h,v 1.11.2.4 2007/01/13 11:19:07 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_queue.h,v 1.13.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ldap_rq.h
===================================================================
--- openldap/trunk/include/ldap_rq.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_rq.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_rq.h,v 1.9.2.5 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_rq.h,v 1.14.2.3 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ldap_schema.h
===================================================================
--- openldap/trunk/include/ldap_schema.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_schema.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_schema.h,v 1.34.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_schema.h,v 1.36.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ldap_utf8.h
===================================================================
--- openldap/trunk/include/ldap_utf8.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldap_utf8.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldap_utf8.h,v 1.11.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldap_utf8.h,v 1.13.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/ldif.h
===================================================================
--- openldap/trunk/include/ldif.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/ldif.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/ldif.h,v 1.23.2.7 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/ldif.h,v 1.31.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/lutil.h
===================================================================
--- openldap/trunk/include/lutil.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/lutil.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/lutil.h,v 1.57.2.8 2007/10/04 20:02:09 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/include/lutil.h,v 1.63.2.4 2007/12/03 15:04:30 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -158,6 +158,7 @@
 	int tm_mon;	/* month 0-11 */
 	int tm_year;	/* year - 1900 */
 	int tm_usec;	/* microseconds */
+	int tm_usub;	/* submicro */
 } lutil_tm;
 
 typedef struct lutil_timet {
@@ -166,14 +167,20 @@
 	unsigned int tt_usec;	/* microseconds */
 } lutil_timet;
 
+/* Parse a timestamp string into a structure */
 LDAP_LUTIL_F( int )
 lutil_parsetime LDAP_P((
 	char *atm, struct lutil_tm * ));
 
+/* Convert structured time to time in seconds since 1900 */
 LDAP_LUTIL_F( int )
 lutil_tm2time LDAP_P((
 	struct lutil_tm *, struct lutil_timet * ));
 
+/* Get current time as a structured time */
+LDAP_LUTIL_F( void )
+lutil_gettime LDAP_P(( struct lutil_tm * ));
+
 #ifdef _WIN32
 LDAP_LUTIL_F( void )
 lutil_slashpath LDAP_P(( char* path ));
@@ -298,6 +305,10 @@
 #define lutil_atoul(v, s)	lutil_atoulx((v), (s), 10)
 
 LDAP_LUTIL_F (int)
+lutil_str2bin( struct berval *in, struct berval *out, void *ctx );
+
+/* Parse and unparse time intervals */
+LDAP_LUTIL_F (int)
 lutil_parse_time( const char *in, unsigned long *tp );
 
 LDAP_LUTIL_F (int)

Modified: openldap/trunk/include/lutil_hash.h
===================================================================
--- openldap/trunk/include/lutil_hash.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/lutil_hash.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/lutil_hash.h,v 1.6.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/lutil_hash.h,v 1.8.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/lutil_ldap.h
===================================================================
--- openldap/trunk/include/lutil_ldap.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/lutil_ldap.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/lutil_ldap.h,v 1.9.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/lutil_ldap.h,v 1.11.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/lutil_lockf.h
===================================================================
--- openldap/trunk/include/lutil_lockf.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/lutil_lockf.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/lutil_lockf.h,v 1.15.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/lutil_lockf.h,v 1.17.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/lutil_md5.h
===================================================================
--- openldap/trunk/include/lutil_md5.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/lutil_md5.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/lutil_md5.h,v 1.22.2.3 2007/01/02 21:43:46 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/lutil_md5.h,v 1.24.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/lutil_sha1.h
===================================================================
--- openldap/trunk/include/lutil_sha1.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/lutil_sha1.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/lutil_sha1.h,v 1.26.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/lutil_sha1.h,v 1.28.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/include/portable.hin
===================================================================
--- openldap/trunk/include/portable.hin	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/portable.hin	2007-12-15 10:25:31 UTC (rev 892)
@@ -129,18 +129,12 @@
 /* define if you have Cyrus SASL */
 #undef HAVE_CYRUS_SASL
 
-/* Define to 1 if you have the <db_185.h> header file. */
-#undef HAVE_DB_185_H
-
 /* Define to 1 if you have the <db.h> header file. */
 #undef HAVE_DB_H
 
-/* define if you have Kerberos des_debug */
-#undef HAVE_DES_DEBUG
+/* define if your system supports /dev/poll */
+#undef HAVE_DEVPOLL
 
-/* Define to 1 if you have the <des.h> header file. */
-#undef HAVE_DES_H
-
 /* Define to 1 if you have the <direct.h> header file. */
 #undef HAVE_DIRECT_H
 
@@ -190,12 +184,6 @@
 /* Define to 1 if you have the `gai_strerror' function. */
 #undef HAVE_GAI_STRERROR
 
-/* define if GNU DBM is available */
-#undef HAVE_GDBM
-
-/* Define to 1 if you have the <gdbm.h> header file. */
-#undef HAVE_GDBM_H
-
 /* Define to 1 if you have the `getaddrinfo' function. */
 #undef HAVE_GETADDRINFO
 
@@ -232,6 +220,9 @@
 /* Define to 1 if you have the `getpeereid' function. */
 #undef HAVE_GETPEEREID
 
+/* Define to 1 if you have the `getpeerucred' function. */
+#undef HAVE_GETPEERUCRED
+
 /* Define to 1 if you have the `getpwnam' function. */
 #undef HAVE_GETPWNAM
 
@@ -247,21 +238,24 @@
 /* Define to 1 if you have the <gmp.h> header file. */
 #undef HAVE_GMP_H
 
+/* define if you have GNUtls */
+#undef HAVE_GNUTLS
+
+/* Define to 1 if you have the <gnutls/gnutls.h> header file. */
+#undef HAVE_GNUTLS_GNUTLS_H
+
 /* if you have GNU Pth */
 #undef HAVE_GNU_PTH
 
 /* Define to 1 if you have the <grp.h> header file. */
 #undef HAVE_GRP_H
 
-/* define if you have HEIMDAL Kerberos */
-#undef HAVE_HEIMDAL_KERBEROS
-
-/* Define to 1 if you have the <heim_err.h> header file. */
-#undef HAVE_HEIM_ERR_H
-
 /* Define to 1 if you have the `hstrerror' function. */
 #undef HAVE_HSTRERROR
 
+/* define if you actually have ICU */
+#undef HAVE_ICU
+
 /* define to you inet_aton(3) is available */
 #undef HAVE_INET_ATON
 
@@ -277,39 +271,12 @@
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
+/* Define to 1 if you have the `ioctl' function. */
+#undef HAVE_IOCTL
+
 /* Define to 1 if you have the <io.h> header file. */
 #undef HAVE_IO_H
 
-/* define if you have Kerberos */
-#undef HAVE_KERBEROS
-
-/* Define to 1 if you have the <kerberosIV/des.h> header file. */
-#undef HAVE_KERBEROSIV_DES_H
-
-/* Define to 1 if you have the <kerberosIV/krb.h> header file. */
-#undef HAVE_KERBEROSIV_KRB_H
-
-/* define if you have Kerberos IV */
-#undef HAVE_KRB4
-
-/* define if you have Kerberos V with IV support */
-#undef HAVE_KRB425
-
-/* define if you have Kerberos V */
-#undef HAVE_KRB5
-
-/* Define to 1 if you have the <krb5.h> header file. */
-#undef HAVE_KRB5_H
-
-/* Define to 1 if you have the <krb-archaeology.h> header file. */
-#undef HAVE_KRB_ARCHAEOLOGY_H
-
-/* Define to 1 if you have the <krb.h> header file. */
-#undef HAVE_KRB_H
-
-/* define if you have Kth Kerberos */
-#undef HAVE_KTH_KERBEROS
-
 /* Define to 1 if you have the `gen' library (-lgen). */
 #undef HAVE_LIBGEN
 
@@ -373,12 +340,6 @@
 /* Define to 1 if you have the <malloc.h> header file. */
 #undef HAVE_MALLOC_H
 
-/* define if MDBM is available */
-#undef HAVE_MDBM
-
-/* Define to 1 if you have the <mdbm.h> header file. */
-#undef HAVE_MDBM_H
-
 /* Define to 1 if you have the `memcpy' function. */
 #undef HAVE_MEMCPY
 
@@ -400,12 +361,6 @@
 /* define this if you have mkversion */
 #undef HAVE_MKVERSION
 
-/* define if NDBM is available */
-#undef HAVE_NDBM
-
-/* Define to 1 if you have the <ndbm.h> header file. */
-#undef HAVE_NDBM_H
-
 /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
 #undef HAVE_NDIR_H
 
@@ -472,7 +427,7 @@
 /* Define to 1 if you have the `pthread_kill_other_threads_np' function. */
 #undef HAVE_PTHREAD_KILL_OTHER_THREADS_NP
 
-/* Define to 1 if you have the `pthread_rwlock_destroy' function. */
+/* define if you have pthread_rwlock_destroy function */
 #undef HAVE_PTHREAD_RWLOCK_DESTROY
 
 /* Define to 1 if you have the `pthread_setconcurrency' function. */
@@ -661,6 +616,18 @@
 /* Define to 1 if `st_blksize' is member of `struct stat'. */
 #undef HAVE_STRUCT_STAT_ST_BLKSIZE
 
+/* Define to 1 if `st_fstype' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_FSTYPE
+
+/* define to 1 if st_fstype is char * */
+#undef HAVE_STRUCT_STAT_ST_FSTYPE_CHAR
+
+/* define to 1 if st_fstype is int */
+#undef HAVE_STRUCT_STAT_ST_FSTYPE_INT
+
+/* Define to 1 if `st_vfstype' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_VFSTYPE
+
 /* Define to 1 if you have the <synch.h> header file. */
 #undef HAVE_SYNCH_H
 
@@ -673,6 +640,9 @@
 /* Define to 1 if you have the <syslog.h> header file. */
 #undef HAVE_SYSLOG_H
 
+/* Define to 1 if you have the <sys/devpoll.h> header file. */
+#undef HAVE_SYS_DEVPOLL_H
+
 /* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
    */
 #undef HAVE_SYS_DIR_H
@@ -692,6 +662,9 @@
 /* Define to 1 if you have the <sys/filio.h> header file. */
 #undef HAVE_SYS_FILIO_H
 
+/* Define to 1 if you have the <sys/fstyp.h> header file. */
+#undef HAVE_SYS_FSTYP_H
+
 /* Define to 1 if you have the <sys/ioctl.h> header file. */
 #undef HAVE_SYS_IOCTL_H
 
@@ -702,6 +675,12 @@
 /* Define to 1 if you have the <sys/param.h> header file. */
 #undef HAVE_SYS_PARAM_H
 
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#undef HAVE_SYS_POLL_H
+
+/* Define to 1 if you have the <sys/privgrp.h> header file. */
+#undef HAVE_SYS_PRIVGRP_H
+
 /* Define to 1 if you have the <sys/resource.h> header file. */
 #undef HAVE_SYS_RESOURCE_H
 
@@ -735,6 +714,9 @@
 /* Define to 1 if you have the <sys/uuid.h> header file. */
 #undef HAVE_SYS_UUID_H
 
+/* Define to 1 if you have the <sys/vmount.h> header file. */
+#undef HAVE_SYS_VMOUNT_H
+
 /* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
 #undef HAVE_SYS_WAIT_H
 
@@ -765,15 +747,24 @@
 /* define if you have TLS */
 #undef HAVE_TLS
 
+/* Define to 1 if you have the <unicode/utypes.h> header file. */
+#undef HAVE_UNICODE_UTYPES_H
+
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
 /* Define to 1 if you have the <utime.h> header file. */
 #undef HAVE_UTIME_H
 
+/* define if you have uuid_generate() */
+#undef HAVE_UUID_GENERATE
+
 /* define if you have uuid_to_str() */
 #undef HAVE_UUID_TO_STR
 
+/* Define to 1 if you have the <uuid/uuid.h> header file. */
+#undef HAVE_UUID_UUID_H
+
 /* Define to 1 if you have the `vprintf' function. */
 #undef HAVE_VPRINTF
 
@@ -820,9 +811,6 @@
 #undef LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE
 
 /* define to LDAP VENDOR VERSION */
-#undef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-
-/* define to LDAP VENDOR VERSION */
 #undef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
 
 /* define this to add debugging code */
@@ -858,18 +846,15 @@
 /* Patch */
 #undef LDAP_VENDOR_VERSION_PATCH
 
-/* define this to use DBBTREE w/ LDBM backend */
-#undef LDBM_USE_DBBTREE
-
-/* define this to use DBHASH w/ LDBM backend */
-#undef LDBM_USE_DBHASH
-
 /* define if memcmp is not 8-bit clean or is otherwise broken */
 #undef NEED_MEMCMP_REPLACEMENT
 
 /* define if you have (or want) no threads */
 #undef NO_THREADS
 
+/* define to use the original debug style */
+#undef OLD_DEBUG
+
 /* Package */
 #undef OPENLDAP_PACKAGE
 
@@ -942,9 +927,6 @@
 /* define to support LDAP backend */
 #undef SLAPD_LDAP
 
-/* define to support LDBM backend */
-#undef SLAPD_LDBM
-
 /* define to support LAN Manager passwords */
 #undef SLAPD_LMHASH
 
@@ -963,9 +945,6 @@
 /* define to support cn=Monitor backend */
 #undef SLAPD_MONITOR
 
-/* define to support multimaster replication */
-#undef SLAPD_MULTIMASTER
-
 /* define to support NULL backend */
 #undef SLAPD_NULL
 
@@ -975,17 +954,20 @@
 /* define for Audit Logging overlay */
 #undef SLAPD_OVER_AUDITLOG
 
-/* define for Deny Operation overlay */
-#undef SLAPD_OVER_DENYOP
+/* define for Attribute Constraint overlay */
+#undef SLAPD_OVER_CONSTRAINT
 
+/* define for Dynamic Directory Services overlay */
+#undef SLAPD_OVER_DDS
+
 /* define for Dynamic Group overlay */
 #undef SLAPD_OVER_DYNGROUP
 
 /* define for Dynamic List overlay */
 #undef SLAPD_OVER_DYNLIST
 
-/* define for Last Modification overlay */
-#undef SLAPD_OVER_LASTMOD
+/* define for Reverse Group Membership overlay */
+#undef SLAPD_OVER_MEMBEROF
 
 /* define for Password Policy overlay */
 #undef SLAPD_OVER_PPOLICY
@@ -1002,6 +984,9 @@
 /* define for Rewrite/Remap overlay */
 #undef SLAPD_OVER_RWM
 
+/* define for Sequential Modify overlay */
+#undef SLAPD_OVER_SEQMOD
+
 /* define for Syncrepl Provider overlay */
 #undef SLAPD_OVER_SYNCPROV
 
@@ -1035,6 +1020,9 @@
 /* define to support SQL backend */
 #undef SLAPD_SQL
 
+/* define to support run-time loadable ACL */
+#undef SLAP_DYNACL
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 

Modified: openldap/trunk/include/rewrite.h
===================================================================
--- openldap/trunk/include/rewrite.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/rewrite.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/rewrite.h,v 1.12.2.4 2007/01/02 21:43:47 kurt Exp $
+/* $OpenLDAP: pkg/ldap/include/rewrite.h,v 1.15.2.2 2007/08/31 23:13:53 quanah Exp $
  */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
@@ -253,6 +253,46 @@
                 struct rewrite_info *info
 );
 
+/*
+ * Mapping implementations
+ */
+
+struct rewrite_mapper;
+
+typedef void * (rewrite_mapper_config)(
+	const char *fname,
+	int lineno,
+	int argc,
+	char **argv );
+
+typedef int (rewrite_mapper_apply)(
+	void *ctx,
+	const char *arg,
+	struct berval *retval );
+
+typedef int (rewrite_mapper_destroy)(
+	void *ctx );
+
+typedef struct rewrite_mapper {
+	char *rm_name;
+	rewrite_mapper_config *rm_config;
+	rewrite_mapper_apply *rm_apply;
+	rewrite_mapper_destroy *rm_destroy;
+} rewrite_mapper;
+
+/* For dynamic loading and unloading of mappers */
+LDAP_REWRITE_F (int)
+rewrite_mapper_register(
+	const rewrite_mapper *map );
+
+LDAP_REWRITE_F (int)
+rewrite_mapper_unregister(
+	const rewrite_mapper *map );
+
+LDAP_REWRITE_F (const rewrite_mapper *)
+rewrite_mapper_find(
+	const char *name );
+
 LDAP_END_DECL
 
 #endif /* REWRITE_H */

Modified: openldap/trunk/include/slapi-plugin.h
===================================================================
--- openldap/trunk/include/slapi-plugin.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/slapi-plugin.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/slapi-plugin.h,v 1.37.2.6 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/slapi-plugin.h,v 1.52.2.4 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -31,9 +31,9 @@
 typedef struct slapi_value		Slapi_Value;
 typedef struct slapi_valueset		Slapi_ValueSet;
 typedef struct slapi_filter		Slapi_Filter;
-typedef struct slap_backend_db		Slapi_Backend;
-typedef struct slap_op			Slapi_Operation;
-typedef struct slap_conn		Slapi_Connection;
+typedef struct BackendDB		Slapi_Backend;
+typedef struct Operation		Slapi_Operation;
+typedef struct Connection		Slapi_Connection;
 typedef struct slapi_dn			Slapi_DN;
 typedef struct slapi_rdn		Slapi_RDN;
 typedef struct slapi_mod		Slapi_Mod;
@@ -528,9 +528,11 @@
 #define SLAPI_X_CONN_SSF			1303
 #define SLAPI_X_CONN_SASL_CONTEXT		1304
 #define SLAPI_X_OPERATION_DELETE_GLUE_PARENT	1305
-#define SLAPI_X_MANAGEDIT			1306
+#define SLAPI_X_RELAX			1306
+#define SLAPI_X_MANAGEDIT			SLAPI_X_RELAX
 #define SLAPI_X_OPERATION_NO_SCHEMA_CHECK	1307
 #define SLAPI_X_ADD_STRUCTURAL_CLASS		1308
+#define SLAPI_X_OPERATION_NO_SUBORDINATE_GLUE	1309
 
 /*  Authentication types */
 #define SLAPD_AUTH_NONE   "none"
@@ -648,6 +650,7 @@
 #define SLAPI_PLUGIN_BE_POST_DELETE_FN		553
 
 #define SLAPI_OPERATION_TYPE			590
+#define SLAPI_OPERATION_MSGID			591
 
 #define SLAPI_PLUGIN_MR_FILTER_CREATE_FN	600
 #define SLAPI_PLUGIN_MR_INDEXER_CREATE_FN	601
@@ -703,6 +706,7 @@
 #define SLAPI_OPERATION_ID                      742
 #define SLAPI_CONN_CERT                         743
 #define SLAPI_CONN_AUTHMETHOD                   746
+#define SLAPI_IS_INTERNAL_OPERATION 		748
 
 #define SLAPI_RESULT_CODE                       881
 #define SLAPI_RESULT_TEXT                       882
@@ -724,6 +728,20 @@
 #define SLAPI_X_GROUP_OPERATION_DN		1252 /* asserted value */
 #define SLAPI_X_GROUP_TARGET_ENTRY		1253 /* target entry */
 
+/* internal preoperation extensions */
+#define SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN	1260
+#define SLAPI_PLUGIN_INTERNAL_PRE_UNBIND_FN	1261
+#define SLAPI_PLUGIN_INTERNAL_PRE_SEARCH_FN	1262
+#define SLAPI_PLUGIN_INTERNAL_PRE_COMPARE_FN	1263
+#define SLAPI_PLUGIN_INTERNAL_PRE_ABANDON_FN	1264
+
+/* internal postoperation extensions */
+#define SLAPI_PLUGIN_INTERNAL_POST_BIND_FN	1270
+#define SLAPI_PLUGIN_INTERNAL_POST_UNBIND_FN	1271
+#define SLAPI_PLUGIN_INTERNAL_POST_SEARCH_FN	1272
+#define SLAPI_PLUGIN_INTERNAL_POST_COMPARE_FN	1273
+#define SLAPI_PLUGIN_INTERNAL_POST_ABANDON_FN	1274
+
 /* config stuff */
 #define SLAPI_CONFIG_FILENAME			40
 #define SLAPI_CONFIG_LINENO			41

Modified: openldap/trunk/include/sysexits-compat.h
===================================================================
--- openldap/trunk/include/sysexits-compat.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/include/sysexits-compat.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/include/sysexits-compat.h,v 1.9.2.3 2007/01/02 21:43:47 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/include/sysexits-compat.h,v 1.11.2.2 2007/08/31 23:13:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/Makefile.in
===================================================================
--- openldap/trunk/libraries/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Libraries Makefile for OpenLDAP
-# $OpenLDAP: pkg/ldap/libraries/Makefile.in,v 1.24.2.4 2007/01/02 21:43:48 kurt Exp $
+# $OpenLDAP: pkg/ldap/libraries/Makefile.in,v 1.26.2.2 2007/08/31 23:13:54 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblber/Makefile.in
===================================================================
--- openldap/trunk/libraries/liblber/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # LIBLBER
-# $OpenLDAP: pkg/ldap/libraries/liblber/Makefile.in,v 1.35.2.3 2007/01/02 21:43:48 kurt Exp $
+# $OpenLDAP: pkg/ldap/libraries/liblber/Makefile.in,v 1.37.2.3 2007/11/15 00:31:05 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -37,6 +37,7 @@
 XLIBS = $(LIBRARY) $(LDAP_LIBLUTIL_A)
 XXLIBS = 
 NT_LINK_LIBS = $(AC_LIBS)
+UNIX_LINK_LIBS = $(AC_LIBS)
 
 dtest:    $(XLIBS) dtest.o
 	$(LTLINK) -o $@ dtest.o $(LIBS)

Modified: openldap/trunk/libraries/liblber/assert.c
===================================================================
--- openldap/trunk/libraries/liblber/assert.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/assert.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblber/assert.c,v 1.11.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/assert.c,v 1.13.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblber/bprint.c
===================================================================
--- openldap/trunk/libraries/liblber/bprint.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/bprint.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblber/bprint.c,v 1.55.2.4 2007/08/27 10:11:31 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/bprint.c,v 1.57.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblber/debug.c
===================================================================
--- openldap/trunk/libraries/liblber/debug.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/debug.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblber/debug.c,v 1.18.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/debug.c,v 1.21.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -34,23 +34,6 @@
 
 static FILE *log_file = NULL;
 
-#ifdef LDAP_SYSLOG
-static int use_syslog = 0;
-
-static int debug2syslog(int l) {
-	switch (l) {
-	case LDAP_LEVEL_EMERG: return LOG_EMERG;
-	case LDAP_LEVEL_ALERT: return LOG_ALERT;
-	case LDAP_LEVEL_CRIT: return LOG_CRIT;
-	case LDAP_LEVEL_ERR: return LOG_ERR;
-	case LDAP_LEVEL_WARNING: return LOG_WARNING;
-	case LDAP_LEVEL_NOTICE: return LOG_NOTICE;
-	case LDAP_LEVEL_INFO: return LOG_INFO;
-	}
-	return LOG_DEBUG;
-}
-#endif
-
 int lutil_debug_file( FILE *file )
 {
 	log_file = file;

Modified: openldap/trunk/libraries/liblber/decode.c
===================================================================
--- openldap/trunk/libraries/liblber/decode.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/decode.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* decode.c - ber input decoding routines */
-/* $OpenLDAP: pkg/ldap/libraries/liblber/decode.c,v 1.101.2.5 2007/08/27 10:11:31 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/decode.c,v 1.105.2.3 2007/10/18 01:37:30 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -45,6 +45,52 @@
 	ber_int_t *num,
 	ber_len_t len ));
 
+/* out->bv_len should be the buffer size on input */
+int
+ber_decode_oid( BerValue *in, BerValue *out )
+{
+	const unsigned char *der;
+	unsigned long val;
+	unsigned val1;
+	ber_len_t i;
+	char *ptr;
+
+	assert( in != NULL );
+	assert( out != NULL );
+
+	/* need 4 chars/inbyte + \0 for input={7f 7f 7f...} */
+	if ( !out->bv_val || (out->bv_len+3)/4 <= in->bv_len )
+		return -1;
+
+	ptr = NULL;
+	der = (unsigned char *) in->bv_val;
+	val = 0;
+	for ( i=0; i < in->bv_len; i++ ) {
+		val |= der[i] & 0x7f;
+		if ( !( der[i] & 0x80 )) {
+			if ( ptr == NULL ) {
+				/* Initial "x.y": val=x*40+y, x<=2, y<40 if x=2 */
+				ptr = out->bv_val;
+				val1 = (val < 80 ? val/40 : 2);
+				val -= val1*40;
+				ptr += sprintf( ptr, "%u", val1 );
+			}
+			ptr += sprintf( ptr, ".%lu", val );
+			val = 0;
+		} else if ( val - 1UL < LBER_OID_COMPONENT_MAX >> 7 ) {
+			val <<= 7;
+		} else {
+			/* val would overflow, or is 0 from invalid initial 0x80 octet */
+			return -1;
+		}
+	}
+	if ( ptr == NULL || val != 0 )
+		return -1;
+
+	out->bv_len = ptr - out->bv_val;
+	return 0;
+}
+
 /* return the tag - LBER_DEFAULT returned means trouble */
 ber_tag_t
 ber_get_tag( BerElement *ber )
@@ -437,7 +483,7 @@
 }
 
 ber_tag_t
-ber_get_stringbv( BerElement *ber, struct berval *bv, int alloc )
+ber_get_stringbv( BerElement *ber, struct berval *bv, int option )
 {
 	ber_tag_t	tag;
 
@@ -455,7 +501,7 @@
 		return LBER_DEFAULT;
 	}
 
-	if ( alloc ) {
+	if ( option & LBER_BV_ALLOC ) {
 		bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1,
 			ber->ber_memctx );
 		if ( bv->bv_val == NULL ) {
@@ -474,14 +520,14 @@
 		ber->ber_ptr += bv->bv_len;
 	}
 	ber->ber_tag = *(unsigned char *)ber->ber_ptr;
-	bv->bv_val[bv->bv_len] = '\0';
+	if ( !( option & LBER_BV_NOTERM ))
+		bv->bv_val[bv->bv_len] = '\0';
 
 	return tag;
 }
 
-#ifdef LDAP_NULL_IS_NULL
 ber_tag_t
-ber_get_stringbv_null( BerElement *ber, struct berval *bv, int alloc )
+ber_get_stringbv_null( BerElement *ber, struct berval *bv, int option )
 {
 	ber_tag_t	tag;
 
@@ -505,7 +551,7 @@
 		return tag;
 	}
 
-	if ( alloc ) {
+	if ( option & LBER_BV_ALLOC ) {
 		bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1,
 			ber->ber_memctx );
 		if ( bv->bv_val == NULL ) {
@@ -524,11 +570,11 @@
 		ber->ber_ptr += bv->bv_len;
 	}
 	ber->ber_tag = *(unsigned char *)ber->ber_ptr;
-	bv->bv_val[bv->bv_len] = '\0';
+	if ( !( option & LBER_BV_NOTERM ))
+		bv->bv_val[bv->bv_len] = '\0';
 
 	return tag;
 }
-#endif /* LDAP_NULL_IS_NULL */
 
 ber_tag_t
 ber_get_stringa( BerElement *ber, char **buf )
@@ -538,13 +584,12 @@
 
 	assert( buf != NULL );
 
-	tag = ber_get_stringbv( ber, &bv, 1 );
+	tag = ber_get_stringbv( ber, &bv, LBER_BV_ALLOC );
 	*buf = bv.bv_val;
 
 	return tag;
 }
 
-#ifdef LDAP_NULL_IS_NULL
 ber_tag_t
 ber_get_stringa_null( BerElement *ber, char **buf )
 {
@@ -553,12 +598,11 @@
 
 	assert( buf != NULL );
 
-	tag = ber_get_stringbv_null( ber, &bv, 1 );
+	tag = ber_get_stringbv_null( ber, &bv, LBER_BV_ALLOC );
 	*buf = bv.bv_val;
 
 	return tag;
 }
-#endif /* LDAP_NULL_IS_NULL */
 
 ber_tag_t
 ber_get_stringal( BerElement *ber, struct berval **bv )
@@ -574,7 +618,7 @@
 		return LBER_DEFAULT;
 	}
 
-	tag = ber_get_stringbv( ber, *bv, 1 );
+	tag = ber_get_stringbv( ber, *bv, LBER_BV_ALLOC );
 	if ( tag == LBER_DEFAULT ) {
 		LBER_FREE( *bv );
 		*bv = NULL;
@@ -736,9 +780,11 @@
 
 	fmt_reset = fmt;
 
-	ber_log_printf( LDAP_DEBUG_TRACE, ber->ber_debug,
-		"ber_scanf fmt (%s) ber:\n", fmt );
-	ber_log_dump( LDAP_DEBUG_BER, ber->ber_debug, ber, 1 );
+	if ( ber->ber_debug & (LDAP_DEBUG_TRACE|LDAP_DEBUG_BER)) {
+		ber_log_printf( LDAP_DEBUG_TRACE, ber->ber_debug,
+			"ber_scanf fmt (%s) ber:\n", fmt );
+		ber_log_dump( LDAP_DEBUG_BER, ber->ber_debug, ber, 1 );
+	}
 
 	for ( rc = 0; *fmt && rc != LBER_DEFAULT; fmt++ ) {
 		/* When this is modified, remember to update
@@ -759,13 +805,11 @@
 			rc = ber_get_stringa( ber, ss );
 			break;
 
-#ifdef LDAP_NULL_IS_NULL
 		case 'A':	/* octet string - allocate storage as needed,
 				 * but return NULL if len == 0 */
 			ss = va_arg( ap, char ** );
 			rc = ber_get_stringa_null( ber, ss );
 			break;
-#endif /* LDAP_NULL_IS_NULL */
 
 		case 'b':	/* boolean */
 			i = va_arg( ap, ber_int_t * );
@@ -817,7 +861,7 @@
 
 		case 'o':	/* octet string in a supplied berval */
 			bval = va_arg( ap, struct berval * );
-			rc = ber_get_stringbv( ber, bval, 1 );
+			rc = ber_get_stringbv( ber, bval, LBER_BV_ALLOC );
 			break;
 
 		case 'O':	/* octet string - allocate & include length */
@@ -846,7 +890,7 @@
 			bgbvr cookie = { ChArray };
 			cookie.ber = ber;
 			cookie.res.c = va_arg( ap, char *** );
-			cookie.alloc = 1;
+			cookie.alloc = LBER_BV_ALLOC;
 			rc = ber_get_stringbvl( &cookie, NULL );
 			break;
 		}
@@ -856,7 +900,7 @@
 			bgbvr cookie = { BvVec };
 			cookie.ber = ber;
 			cookie.res.bv = va_arg( ap, struct berval *** );
-			cookie.alloc = 1;
+			cookie.alloc = LBER_BV_ALLOC;
 			rc = ber_get_stringbvl( &cookie, NULL );
 			break;
 		}
@@ -866,7 +910,7 @@
 			bgbvr cookie = { BvArray };
 			cookie.ber = ber;
 			cookie.res.ba = va_arg( ap, struct berval ** );
-			cookie.alloc = 1;
+			cookie.alloc = LBER_BV_ALLOC;
 			rc = ber_get_stringbvl( &cookie, NULL );
 			break;
 		}
@@ -920,9 +964,7 @@
 			} break;
 
 		case 'a':	/* octet string - allocate storage as needed */
-#ifdef LDAP_NULL_IS_NULL
 		case 'A':
-#endif /* LDAP_NULL_IS_NULL */
 			ss = va_arg( ap, char ** );
 			if ( *ss ) {
 				LBER_FREE( *ss );

Modified: openldap/trunk/libraries/liblber/dtest.c
===================================================================
--- openldap/trunk/libraries/liblber/dtest.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/dtest.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* dtest.c - lber decoding test program */
-/* $OpenLDAP: pkg/ldap/libraries/liblber/dtest.c,v 1.35.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/dtest.c,v 1.37.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblber/encode.c
===================================================================
--- openldap/trunk/libraries/liblber/encode.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/encode.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* encode.c - ber output encoding routines */
-/* $OpenLDAP: pkg/ldap/libraries/liblber/encode.c,v 1.61.2.4 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/encode.c,v 1.64.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -30,6 +30,7 @@
 
 #include "portable.h"
 
+#include <ctype.h>
 #include <stdio.h>
 
 #include <ac/stdlib.h>
@@ -177,6 +178,63 @@
 	return rc == i ?  i+1 : -1;
 }
 
+/* out->bv_len should be the buffer size on input */
+int
+ber_encode_oid( BerValue *in, BerValue *out )
+{
+	unsigned char *der;
+	unsigned long val1, val;
+	int i, j, len;
+	char *ptr, *end, *inend;
+
+	assert( in != NULL );
+	assert( out != NULL );
+
+	if ( !out->bv_val || out->bv_len < in->bv_len/2 )
+		return -1;
+
+	der = (unsigned char *) out->bv_val;
+	ptr = in->bv_val;
+	inend = ptr + in->bv_len;
+
+	/* OIDs start with <0-1>.<0-39> or 2.<any>, DER-encoded 40*val1+val2 */
+	if ( !isdigit( (unsigned char) *ptr )) return -1;
+	val1 = strtoul( ptr, &end, 10 );
+	if ( end == ptr || val1 > 2 ) return -1;
+	if ( *end++ != '.' || !isdigit( (unsigned char) *end )) return -1;
+	val = strtoul( end, &ptr, 10 );
+	if ( ptr == end ) return -1;
+	if ( val > (val1 < 2 ? 39 : LBER_OID_COMPONENT_MAX - 80) ) return -1;
+	val += val1 * 40;
+
+	for (;;) {
+		if ( ptr > inend ) return -1;
+
+		len = 0;
+		do {
+			der[len++] = (val & 0xff) | 0x80;
+		} while ( (val >>= 7) != 0 );
+		der[0] &= 0x7f;
+		for ( i = 0, j = len; i < --j; i++ ) {
+			unsigned char tmp = der[i];
+			der[i] = der[j];
+			der[j] = tmp;
+		}
+		der += len;
+		if ( ptr == inend )
+			break;
+
+		if ( *ptr++ != '.' ) return -1;
+		if ( !isdigit( (unsigned char) *ptr )) return -1;
+		val = strtoul( ptr, &end, 10 );
+		if ( end == ptr || val > LBER_OID_COMPONENT_MAX ) return -1;
+		ptr = end;
+	}
+
+	out->bv_len = (char *)der - out->bv_val;
+	return 0;
+}
+
 static int
 ber_put_int_or_enum(
 	BerElement *ber,

Modified: openldap/trunk/libraries/liblber/etest.c
===================================================================
--- openldap/trunk/libraries/liblber/etest.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/etest.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* etest.c - lber encoding test program */
-/* $OpenLDAP: pkg/ldap/libraries/liblber/etest.c,v 1.33.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/etest.c,v 1.35.2.3 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -171,8 +171,8 @@
 		return( EXIT_FAILURE );
 	}
 
-	if ( ber_flush( sb, ber, 1 ) == -1 ) {
-		perror( "ber_flush" );
+	if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) == -1 ) {
+		perror( "ber_flush2" );
 		return( EXIT_FAILURE );
 	}
 

Modified: openldap/trunk/libraries/liblber/idtest.c
===================================================================
--- openldap/trunk/libraries/liblber/idtest.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/idtest.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* idtest.c - ber decoding test program using isode libraries */
-/* $OpenLDAP: pkg/ldap/libraries/liblber/idtest.c,v 1.16.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/idtest.c,v 1.18.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblber/io.c
===================================================================
--- openldap/trunk/libraries/liblber/io.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/io.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* io.c - ber general i/o routines */
-/* $OpenLDAP: pkg/ldap/libraries/liblber/io.c,v 1.107.2.6 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/io.c,v 1.111.2.6 2007/10/18 01:37:30 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -48,6 +48,25 @@
 #include "ldap_log.h"
 
 ber_slen_t
+ber_skip_data(
+	BerElement *ber,
+	ber_len_t len )
+{
+	ber_len_t	actuallen, nleft;
+
+	assert( ber != NULL );
+
+	assert( LBER_VALID( ber ) );
+
+	nleft = ber_pvt_ber_remaining( ber );
+	actuallen = nleft < len ? nleft : len;
+	ber->ber_ptr += actuallen;
+	ber->ber_tag = *(unsigned char *)ber->ber_ptr;
+
+	return( (ber_slen_t) actuallen );
+}
+
+ber_slen_t
 ber_read(
 	BerElement *ber,
 	char *buf,
@@ -185,11 +204,8 @@
 void
 ber_free( BerElement *ber, int freebuf )
 {
-#ifdef LDAP_MEMORY_DEBUG
-	assert( ber != NULL );
-#endif
-
 	if( ber == NULL ) {
+		LDAP_MEMORY_DEBUG_ASSERT( ber != NULL );
 		return;
 	}
 
@@ -201,8 +217,16 @@
 int
 ber_flush( Sockbuf *sb, BerElement *ber, int freeit )
 {
+	return ber_flush2( sb, ber,
+		freeit ? LBER_FLUSH_FREE_ON_SUCCESS
+			: LBER_FLUSH_FREE_NEVER );
+}
+
+int
+ber_flush2( Sockbuf *sb, BerElement *ber, int freeit )
+{
 	ber_len_t	towrite;
-	ber_slen_t	rc;	
+	ber_slen_t	rc;
 
 	assert( sb != NULL );
 	assert( ber != NULL );
@@ -217,7 +241,7 @@
 
 	if ( sb->sb_debug ) {
 		ber_log_printf( LDAP_DEBUG_TRACE, sb->sb_debug,
-			"ber_flush: %ld bytes to sd %ld%s\n",
+			"ber_flush2: %ld bytes to sd %ld%s\n",
 			towrite, (long) sb->sb_fd,
 			ber->ber_rwptr != ber->ber_buf ?  " (re-flush)" : "" );
 		ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
@@ -231,16 +255,17 @@
 #else
 		rc = ber_int_sb_write( sb, ber->ber_rwptr, towrite );
 #endif
-		if (rc<=0) {
+		if ( rc <= 0 ) {
+			if ( freeit & LBER_FLUSH_FREE_ON_ERROR ) ber_free( ber, 1 );
 			return -1;
 		}
 		towrite -= rc;
 		ber->ber_rwptr += rc;
 	} 
 
-	if ( freeit ) ber_free( ber, 1 );
+	if ( freeit & LBER_FLUSH_FREE_ON_SUCCESS ) ber_free( ber, 1 );
 
-	return( 0 );
+	return 0;
 }
 
 BerElement *
@@ -463,8 +488,10 @@
 	assert( SOCKBUF_VALID( sb ) );
 	assert( LBER_VALID( ber ) );
 
-	ber_log_printf( LDAP_DEBUG_TRACE, ber->ber_debug,
-		"ber_get_next\n" );
+	if ( ber->ber_debug & LDAP_DEBUG_TRACE ) {
+		ber_log_printf( LDAP_DEBUG_TRACE, ber->ber_debug,
+			"ber_get_next\n" );
+	}
 
 	/*
 	 * Any ber element looks like this: tag length contents.

Modified: openldap/trunk/libraries/liblber/lber-int.h
===================================================================
--- openldap/trunk/libraries/liblber/lber-int.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/lber-int.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblber/lber-int.h,v 1.65.2.4 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/lber-int.h,v 1.68.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -47,6 +47,11 @@
 #ifdef LDAP_MEMORY_DEBUG
 LBER_V (long)	ber_int_meminuse;
 #endif
+#if defined(LDAP_MEMORY_DEBUG) && ((LDAP_MEMORY_DEBUG +0) & 2)
+# define LDAP_MEMORY_DEBUG_ASSERT assert
+#else
+# define LDAP_MEMORY_DEBUG_ASSERT(expr) ((void) 0)
+#endif
 
 struct lber_options {
 	short lbo_valid;
@@ -99,9 +104,13 @@
 #define	sb_options		sb_opts.lbo_options
 #define	sb_debug		sb_opts.lbo_debug
 	ber_socket_t		sb_fd;
+	ber_len_t			sb_max_incoming;
    	unsigned int		sb_trans_needs_read:1;
    	unsigned int		sb_trans_needs_write:1;
-	ber_len_t			sb_max_incoming;
+#ifdef LDAP_PF_LOCAL_SENDMSG
+	char				sb_ungetlen;
+	char				sb_ungetbuf[8];
+#endif
 };
 
 #define SOCKBUF_VALID( sb )	( (sb)->sb_valid == LBER_VALID_SOCKBUF )
@@ -117,6 +126,14 @@
 
 
 /*
+ * decode.c, encode.c
+ */
+
+/* Simplest OID max-DER-component to implement in both decode and encode */
+#define LBER_OID_COMPONENT_MAX ((unsigned long)-1 - 128)
+
+
+/*
  * io.c
  */
 LBER_F( int )

Modified: openldap/trunk/libraries/liblber/memory.c
===================================================================
--- openldap/trunk/libraries/liblber/memory.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/memory.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblber/memory.c,v 1.57.2.7 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/memory.c,v 1.64.2.3 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -24,14 +24,16 @@
 #include <stdio.h>
 #endif
 
-#if LDAP_MEMORY_DEBUG
+#ifdef LDAP_MEMORY_DEBUG
 /*
  * LDAP_MEMORY_DEBUG should only be enabled for the purposes of
  * debugging memory management within OpenLDAP libraries and slapd.
- * It should only be enabled by an experienced developer as it
- * causes the inclusion of numerous assert()'s, many of which may
- * be triggered by a prefectly valid program.
  *
+ * It should only be enabled by an experienced developer as it causes
+ * the inclusion of numerous assert()'s, many of which may be triggered
+ * by a prefectly valid program.  If LDAP_MEMORY_DEBUG & 2 is true,
+ * that includes asserts known to break both slapd and current clients.
+ *
  * The code behind this macro is subject to change as needed to
  * support this testing.
  */
@@ -71,6 +73,7 @@
  * put allocations/frees together.  It is then a simple matter to write a script
  * to find any allocations that don't have a buffer free function.
  */
+long ber_int_meminuse = 0;
 #ifdef LDAP_MEMORY_TRACE
 static ber_int_t sequence = 0;
 #endif
@@ -191,11 +194,8 @@
 {
 	void *new;
 
-#ifdef LDAP_MEMORY_DEBUG
-	assert( s != 0 );
-#endif
-
 	if( s == 0 ) {
+		LDAP_MEMORY_DEBUG_ASSERT( s != 0 );
 		return NULL;
 	}
 
@@ -247,11 +247,8 @@
 {
 	void *new;
 
-#ifdef LDAP_MEMORY_DEBUG
-	assert( n != 0 && s != 0);
-#endif
-
 	if( n == 0 || s == 0 ) {
+		LDAP_MEMORY_DEBUG_ASSERT( n != 0 && s != 0);
 		return NULL;
 	}
 
@@ -745,6 +742,33 @@
 }
 
 int
+ber_bvarray_dup_x( BerVarray *dst, BerVarray src, void *ctx )
+{
+	int i, j;
+	BerVarray new;
+
+	if ( !src ) {
+		*dst = NULL;
+		return 0;
+	}
+
+	for (i=0; !BER_BVISNULL( &src[i] ); i++) ;
+	new = ber_memalloc_x(( i+1 ) * sizeof(BerValue), ctx );
+	if ( !new )
+		return -1;
+	for (j=0; j<i; j++) {
+		ber_dupbv_x( &new[j], &src[j], ctx );
+		if ( BER_BVISNULL( &new[j] )) {
+			ber_bvarray_free_x( new, ctx );
+			return -1;
+		}
+	}
+	BER_BVZERO( &new[j] );
+	*dst = new;
+	return 0;
+}
+
+int
 ber_bvarray_add_x( BerVarray *a, BerValue *bv, void *ctx )
 {
 	int	n;
@@ -784,6 +808,7 @@
 
 	(*a)[n++] = *bv;
 	(*a)[n].bv_val = NULL;
+	(*a)[n].bv_len = 0;
 
 	return n;
 }

Modified: openldap/trunk/libraries/liblber/nt_err.c
===================================================================
--- openldap/trunk/libraries/liblber/nt_err.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/nt_err.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblber/nt_err.c,v 1.13.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/nt_err.c,v 1.15.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblber/options.c
===================================================================
--- openldap/trunk/libraries/liblber/options.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/options.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblber/options.c,v 1.37.2.5 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/options.c,v 1.43.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblber/sockbuf.c
===================================================================
--- openldap/trunk/libraries/liblber/sockbuf.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/sockbuf.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* sockbuf.c - i/o routines with support for adding i/o layers. */
-/* $OpenLDAP: pkg/ldap/libraries/liblber/sockbuf.c,v 1.60.2.8 2007/06/10 18:43:56 hallvard Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/sockbuf.c,v 1.65.2.3 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -150,6 +150,20 @@
 			ret = 1;
 			break;
 
+		case LBER_SB_OPT_UNGET_BUF:
+#ifdef LDAP_PF_LOCAL_SENDMSG
+			sb->sb_ungetlen = ((struct berval *)arg)->bv_len;
+			if ( sb->sb_ungetlen <= sizeof( sb->sb_ungetbuf )) {
+				AC_MEMCPY( sb->sb_ungetbuf, ((struct berval *)arg)->bv_val,
+					sb->sb_ungetlen );
+				ret = 1;
+			} else {
+				sb->sb_ungetlen = 0;
+				ret = -1;
+			}
+#endif
+			break;
+
 		default:
 			ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod, opt, arg );
 			break;
@@ -325,7 +339,7 @@
 int
 ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
 {
-#if HAVE_FCNTL
+#ifdef HAVE_FCNTL
 	int flags = fcntl( sd, F_GETFL);
 	if( nb ) {
 		flags |= O_NONBLOCK;
@@ -704,6 +718,24 @@
 	assert( sbiod != NULL);
 	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
 
+#ifdef LDAP_PF_LOCAL_SENDMSG
+	if ( sbiod->sbiod_sb->sb_ungetlen ) {
+		ber_len_t blen = sbiod->sbiod_sb->sb_ungetlen;
+		if ( blen > len )
+			blen = len;
+		AC_MEMCPY( buf, sbiod->sbiod_sb->sb_ungetbuf, blen );
+		buf = (char *) buf + blen;
+		len -= blen;
+		sbiod->sbiod_sb->sb_ungetlen -= blen;
+		if ( sbiod->sbiod_sb->sb_ungetlen ) {
+			AC_MEMCPY( sbiod->sbiod_sb->sb_ungetbuf,
+				sbiod->sbiod_sb->sb_ungetbuf+blen,
+				sbiod->sbiod_sb->sb_ungetlen );
+		}
+		if ( len == 0 )
+			return blen;
+	}
+#endif
 	return read( sbiod->sbiod_sb->sb_fd, buf, len );
 }
 

Modified: openldap/trunk/libraries/liblber/stdio.c
===================================================================
--- openldap/trunk/libraries/liblber/stdio.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblber/stdio.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblber/stdio.c,v 1.9.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblber/stdio.c,v 1.11.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/Makefile.in
===================================================================
--- openldap/trunk/libraries/libldap/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for LDAP -lldap
-# $OpenLDAP: pkg/ldap/libraries/libldap/Makefile.in,v 1.71.2.4 2007/01/02 21:43:48 kurt Exp $
+# $OpenLDAP: pkg/ldap/libraries/libldap/Makefile.in,v 1.79.2.3 2007/08/31 23:13:54 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -15,29 +15,29 @@
 
 LIBRARY = libldap.la
 
-PROGRAMS = apitest dntest ftest ltest
+PROGRAMS = apitest dntest ftest ltest urltest
 
 SRCS	= bind.c open.c result.c error.c compare.c search.c \
 	controls.c messages.c references.c extended.c cyrus.c \
 	modify.c add.c modrdn.c delete.c abandon.c \
-	sasl.c sbind.c kbind.c unbind.c cancel.c  \
+	sasl.c sbind.c unbind.c cancel.c  \
 	filter.c free.c sort.c passwd.c whoami.c \
 	getdn.c getentry.c getattr.c getvalues.c addentry.c \
-	request.c os-ip.c url.c sortctrl.c vlvctrl.c \
+	request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \
 	init.c options.c print.c string.c util-int.c schema.c \
 	charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \
-	turn.c groupings.c txn.c ppolicy.c
+	turn.c ppolicy.c dds.c txn.c ldap_sync.c stctrl.c
 
 OBJS	= bind.lo open.lo result.lo error.lo compare.lo search.lo \
 	controls.lo messages.lo references.lo extended.lo cyrus.lo \
 	modify.lo add.lo modrdn.lo delete.lo abandon.lo \
-	sasl.lo sbind.lo kbind.lo unbind.lo cancel.lo \
+	sasl.lo sbind.lo unbind.lo cancel.lo \
 	filter.lo free.lo sort.lo passwd.lo whoami.lo \
 	getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
-	request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \
+	request.lo os-ip.lo url.lo pagectrl.lo sortctrl.lo vlvctrl.lo \
 	init.lo options.lo print.lo string.lo util-int.lo schema.lo \
 	charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \
-	turn.lo groupings.lo txn.lo ppolicy.lo
+	turn.lo ppolicy.lo dds.lo txn.lo ldap_sync.lo stctrl.lo
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
@@ -57,6 +57,8 @@
 	$(LTLINK) -o $@ ftest.o $(LIBS)
 ltest:	$(XLIBS) test.o
 	$(LTLINK) -o $@ test.o $(LIBS)
+urltest: $(XLIBS) urltest.o
+	$(LTLINK) -o $@ urltest.o $(LIBS)
 
 CFFILES=ldap.conf
 

Modified: openldap/trunk/libraries/libldap/abandon.c
===================================================================
--- openldap/trunk/libraries/libldap/abandon.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/abandon.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* abandon.c */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/abandon.c,v 1.36.2.6 2007/06/08 07:43:26 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/abandon.c,v 1.41.2.5 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -16,15 +16,7 @@
 /* Portions  Copyright (c) 1990 Regents of the University of Michigan.
  * All rights reserved.
  */
-/* Portions Copyright (C) The Internet Society (1997).
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
-/*
- * An abandon request looks like this:
- *	AbandonRequest ::= MessageID
- */
-
 #include "portable.h"
 
 #include <stdio.h>
@@ -37,12 +29,20 @@
 
 #include "ldap-int.h"
 
-static int do_abandon LDAP_P((
+/*
+ * An abandon request looks like this:
+ *		AbandonRequest ::= [APPLICATION 16] MessageID
+ * and has no response.  (Source: RFC 4511)
+ */
+#include "lutil.h"
+
+static int
+do_abandon(
 	LDAP *ld,
 	ber_int_t origid,
 	ber_int_t msgid,
 	LDAPControl **sctrls,
-	LDAPControl **cctrls));
+	int sendabandon );
 
 /*
  * ldap_abandon_ext - perform an ldap extended abandon operation.
@@ -66,20 +66,24 @@
 	LDAPControl **sctrls,
 	LDAPControl **cctrls )
 {
-	int rc;
+	int	rc;
+
 	Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );
 
 	/* check client controls */
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
 #endif
+
 	rc = ldap_int_client_controls( ld, cctrls );
-	if( rc == LDAP_SUCCESS )
-		rc = do_abandon( ld, msgid, msgid, sctrls, cctrls );
+	if ( rc == LDAP_SUCCESS ) {
+		rc = do_abandon( ld, msgid, msgid, sctrls, 1 );
+	}
 
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
 #endif
+
 	return rc;
 }
 
@@ -104,34 +108,61 @@
 }
 
 
+int
+ldap_pvt_discard(
+	LDAP *ld,
+	ber_int_t msgid )
+{
+	int	rc;
+
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
+
+	rc = do_abandon( ld, msgid, msgid, NULL, 0 );
+
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
+
+	return rc;
+}
+
 static int
 do_abandon(
 	LDAP *ld,
 	ber_int_t origid,
 	ber_int_t msgid,
 	LDAPControl **sctrls,
-	LDAPControl **cctrls)
+	int sendabandon )
 {
 	BerElement	*ber;
-	int		i, err, sendabandon;
-	ber_int_t *old_abandon;
+	int		i, err;
 	Sockbuf		*sb;
 	LDAPRequest	*lr;
 
 	Debug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n",
 		origid, msgid, 0 );
 
-	sendabandon = 1;
-
 	/* find the request that we are abandoning */
-	for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
-		if ( lr->lr_msgid == msgid ) {	/* this message */
+start_again:;
+	lr = ld->ld_requests;
+	while ( lr != NULL ) {
+		/* this message */
+		if ( lr->lr_msgid == msgid ) {
 			break;
 		}
-		if ( lr->lr_origid == msgid ) {/* child:  abandon it */
-			(void) do_abandon( ld,
-				lr->lr_origid, lr->lr_msgid, sctrls, cctrls );
+
+		/* child: abandon it */
+		if ( lr->lr_origid == msgid && !lr->lr_abandoned ) {
+			(void)do_abandon( ld, lr->lr_origid, lr->lr_msgid,
+				sctrls, sendabandon );
+
+			/* restart, as lr may now be dangling... */
+			goto start_again;
 		}
+
+		lr = lr->lr_next;
 	}
 
 	if ( lr != NULL ) {
@@ -146,9 +177,9 @@
 		}
 	}
 
-/* ldap_msgdelete locks the res_mutex. Give up the req_mutex
- * while we're in there.
- */
+	/* ldap_msgdelete locks the res_mutex. Give up the req_mutex
+	 * while we're in there.
+	 */
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
 #endif
@@ -164,7 +195,8 @@
 	/* fetch again the request that we are abandoning */
 	if ( lr != NULL ) {
 		for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
-			if ( lr->lr_msgid == msgid ) {	/* this message */
+			/* this message */
+			if ( lr->lr_msgid == msgid ) {
 				break;
 			}
 		}
@@ -172,46 +204,48 @@
 
 	err = 0;
 	if ( sendabandon ) {
-		if( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
+		if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
 			/* not connected */
 			err = -1;
 			ld->ld_errno = LDAP_SERVER_DOWN;
 
-		} else if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
-			/* BER element alocation failed */
+		} else if ( ( ber = ldap_alloc_ber_with_options( ld ) ) == NULL ) {
+			/* BER element allocation failed */
 			err = -1;
 			ld->ld_errno = LDAP_NO_MEMORY;
 
 		} else {
-	/*
-	 * We already have the mutex in LDAP_R_COMPILE, so
-	 * don't try to get it again.
-	 *		LDAP_NEXT_MSGID(ld, i);
-	 */
+			/*
+			 * We already have the mutex in LDAP_R_COMPILE, so
+			 * don't try to get it again.
+			 *		LDAP_NEXT_MSGID(ld, i);
+			 */
+
 			i = ++(ld)->ld_msgid;
 #ifdef LDAP_CONNECTIONLESS
 			if ( LDAP_IS_UDP(ld) ) {
 				struct sockaddr sa = {0};
 				/* dummy, filled with ldo_peer in request.c */
-				err = ber_write( ber, &sa, sizeof( sa ), 0 );
+				err = ber_write( ber, &sa, sizeof(sa), 0 );
 			}
 			if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version ==
-				LDAP_VERSION2) {
-			    char *dn = ld->ld_options.ldo_cldapdn;
-			    if (!dn) dn = "";
-			    err = ber_printf( ber, "{isti",  /* '}' */
-				i, dn,
-				LDAP_REQ_ABANDON, msgid );
+				LDAP_VERSION2 )
+			{
+				char *dn = ld->ld_options.ldo_cldapdn;
+				if (!dn) dn = "";
+				err = ber_printf( ber, "{isti",  /* '}' */
+					i, dn,
+					LDAP_REQ_ABANDON, msgid );
 			} else
 #endif
 			{
-			    /* create a message to send */
-			    err = ber_printf( ber, "{iti",  /* '}' */
-				i,
-				LDAP_REQ_ABANDON, msgid );
+				/* create a message to send */
+				err = ber_printf( ber, "{iti",  /* '}' */
+					i,
+					LDAP_REQ_ABANDON, msgid );
 			}
 
-			if( err == -1 ) {
+			if ( err == -1 ) {
 				/* encoding error */
 				ld->ld_errno = LDAP_ENCODING_ERROR;
 
@@ -226,7 +260,7 @@
 					/* close '{' */
 					err = ber_printf( ber, /*{*/ "N}" );
 
-					if( err == -1 ) {
+					if ( err == -1 ) {
 						/* encoding error */
 						ld->ld_errno = LDAP_ENCODING_ERROR;
 					}
@@ -245,7 +279,7 @@
 					sb = ld->ld_sb;
 				}
 
-				if ( ber_flush( sb, ber, 1 ) != 0 ) {
+				if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) != 0 ) {
 					ld->ld_errno = LDAP_SERVER_DOWN;
 					err = -1;
 				} else {
@@ -259,8 +293,12 @@
 		if ( sendabandon || lr->lr_status == LDAP_REQST_WRITING ) {
 			ldap_free_connection( ld, lr->lr_conn, 0, 1 );
 		}
+
 		if ( origid == msgid ) {
 			ldap_free_request( ld, lr );
+
+		} else {
+			lr->lr_abandoned = 1;
 		}
 	}
 
@@ -270,34 +308,173 @@
 	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
 	ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
 #endif
+
+	/* use bisection */
 	i = 0;
-	if ( ld->ld_abandoned != NULL ) {
-		for ( ; ld->ld_abandoned[i] != -1; i++ )
-			;	/* NULL */
+	if ( ld->ld_nabandoned == 0 ||
+		ldap_int_bisect_find( ld->ld_abandoned, ld->ld_nabandoned, msgid, &i ) == 0 )
+	{
+		ldap_int_bisect_insert( &ld->ld_abandoned, &ld->ld_nabandoned, msgid, i );
 	}
 
-	old_abandon = ld->ld_abandoned;
-
-	ld->ld_abandoned = (ber_int_t *) LDAP_REALLOC( (char *)
-		ld->ld_abandoned, (i + 2) * sizeof(ber_int_t) );
-		
-	if ( ld->ld_abandoned == NULL ) {
-		ld->ld_abandoned = old_abandon;
-		ld->ld_errno = LDAP_NO_MEMORY;
-		goto done;
-	}
-
-	ld->ld_abandoned[i] = msgid;
-	ld->ld_abandoned[i + 1] = -1;
-
 	if ( err != -1 ) {
 		ld->ld_errno = LDAP_SUCCESS;
 	}
 
-done:;
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
 	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
 #endif
 	return( ld->ld_errno );
 }
+
+/*
+ * ldap_int_bisect_find
+ *
+ * args:
+ *	v:	array of length n (in)
+ *	n:	length of array v (in)
+ *	id:	value to look for (in)
+ *	idxp:	pointer to location of value/insert point
+ *
+ * return:
+ *	0:	not found
+ *	1:	found
+ *	-1:	error
+ */
+int
+ldap_int_bisect_find( ber_int_t *v, ber_len_t n, ber_int_t id, int *idxp )
+{
+	int		begin,
+			end,
+			rc = 0;
+
+	assert( n >= 0 );
+	assert( id >= 0 );
+
+	begin = 0;
+	end = n - 1;
+
+	if ( n > 0 ) {
+		if ( id < v[ begin ] ) {
+			*idxp = 0;
+
+		} else if ( id > v[ end ] ) {
+			*idxp = n;
+
+		} else {
+			int		pos;
+			ber_int_t	curid;
+	
+			while ( end >= begin ) {
+				pos = (begin + end)/2;
+				curid = v[ pos ];
+	
+				if ( id < curid ) {
+					end = pos - 1;
+	
+				} else if ( id > curid ) {
+					begin = pos + 1;
+	
+				} else {
+					/* already abandoned? */
+					*idxp = pos;
+					rc = 1;
+					break;
+				}
+			}
+	
+			if ( rc == 0 ) {
+				*idxp = pos + ( id > curid ? 1 : 0 );
+			}
+		}
+
+	} else {
+		*idxp = 0;
+	}
+
+	return rc;
+}
+
+/*
+ * ldap_int_bisect_insert
+ *
+ * args:
+ *	vp:	pointer to array of length *np (in/out)
+ *	np:	pointer to length of array *vp (in/out)
+ *	id:	value to insert (in)
+ *	idx:	location of insert point (as computed by ldap_int_bisect_find())
+ *
+ * return:
+ *	0:	inserted
+ *	-1:	error
+ */
+int
+ldap_int_bisect_insert( ber_int_t **vp, ber_len_t *np, int id, int idx )
+{
+	ber_int_t	*v;
+	ber_len_t	n;
+	int		i;
+
+	assert( vp != NULL );
+	assert( np != NULL );
+	assert( *np >= 0 );
+	assert( idx >= 0 );
+	assert( idx <= *np );
+
+	n = *np;
+
+	v = ber_memrealloc( *vp, sizeof( ber_int_t ) * ( n + 1 ) );
+	if ( v == NULL ) {
+		return -1;
+	}
+	*vp = v;
+
+	for ( i = n; i > idx; i-- ) {
+		v[ i ] = v[ i - 1 ];
+	}
+	v[ idx ] = id;
+	++(*np);
+
+	return 0;
+}
+
+/*
+ * ldap_int_bisect_delete
+ *
+ * args:
+ *	vp:	pointer to array of length *np (in/out)
+ *	np:	pointer to length of array *vp (in/out)
+ *	id:	value to delete (in)
+ *	idx:	location of value to delete (as computed by ldap_int_bisect_find())
+ *
+ * return:
+ *	0:	deleted
+ */
+int
+ldap_int_bisect_delete( ber_int_t **vp, ber_len_t *np, int id, int idx )
+{
+	ber_int_t	*v;
+	ber_len_t	n;
+	int		i;
+
+	assert( vp != NULL );
+	assert( np != NULL );
+	assert( *np >= 0 );
+	assert( idx >= 0 );
+	assert( idx < *np );
+
+	v = *vp;
+
+	assert( v[ idx ] == id );
+
+	--(*np);
+	n = *np;
+
+	for ( i = idx; i < n; i++ ) {
+		v[ i ] = v[ i + 1 ];
+	}
+
+	return 0;
+}
+

Modified: openldap/trunk/libraries/libldap/add.c
===================================================================
--- openldap/trunk/libraries/libldap/add.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/add.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* add.c */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/add.c,v 1.23.2.4 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/add.c,v 1.27.2.2 2007/08/31 23:13:54 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -16,21 +16,7 @@
 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
  * All rights reserved.
  */
-/* Portions Copyright (C) The Internet Society (1997).
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
-/*
- * An add request looks like this:
- *	AddRequest ::= SEQUENCE {
- *		entry	DistinguishedName,
- *		attrs	SEQUENCE OF SEQUENCE {
- *			type	AttributeType,
- *			values	SET OF AttributeValue
- *		}
- *	}
- */
-
 #include "portable.h"
 
 #include <stdio.h>
@@ -41,6 +27,30 @@
 
 #include "ldap-int.h"
 
+/* An LDAP Add Request/Response looks like this:
+ *        AddRequest ::= [APPLICATION 8] SEQUENCE {
+ *            entry           LDAPDN,
+ *            attributes      AttributeList }
+ *
+ *        AttributeList ::= SEQUENCE OF attribute Attribute
+ *
+ *        Attribute ::= PartialAttribute(WITH COMPONENTS {
+ *             ...,
+ *             vals (SIZE(1..MAX))})
+ *
+ *        PartialAttribute ::= SEQUENCE {
+ *             type       AttributeDescription,
+ *             vals       SET OF value AttributeValue }
+ *
+ *        AttributeDescription ::= LDAPString           
+ *             -- Constrained to <attributedescription> [RFC4512]
+ *                                      
+ *        AttributeValue ::= OCTET STRING
+ *        
+ *        AddResponse ::= [APPLICATION 9] LDAPResult 
+ * (Source: RFC 4511)
+ */
+
 /*
  * ldap_add - initiate an ldap add operation.  Parameters:
  *
@@ -198,7 +208,7 @@
 	if ( rc != LDAP_SUCCESS )
 		return( rc );
 
-	if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
+	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
 		return( ld->ld_errno );
 
 	return( ldap_result2error( ld, res, 1 ) );

Modified: openldap/trunk/libraries/libldap/addentry.c
===================================================================
--- openldap/trunk/libraries/libldap/addentry.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/addentry.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* addentry.c */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/addentry.c,v 1.14.2.4 2007/07/22 15:55:36 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/addentry.c,v 1.16.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/apitest.c
===================================================================
--- openldap/trunk/libraries/libldap/apitest.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/apitest.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* apitest.c -- OpenLDAP API Test Program */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/apitest.c,v 1.23.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/apitest.c,v 1.25.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/bind.c
===================================================================
--- openldap/trunk/libraries/libldap/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* bind.c */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/bind.c,v 1.22.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/bind.c,v 1.24.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -16,20 +16,28 @@
 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
  * All rights reserved.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+#include "ldap_log.h"
+
 /*
  *	BindRequest ::= SEQUENCE {
  *		version		INTEGER,
  *		name		DistinguishedName,	 -- who
  *		authentication	CHOICE {
  *			simple		[0] OCTET STRING -- passwd
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
- *			krbv42ldap	[1] OCTET STRING
- *			krbv42dsa	[2] OCTET STRING
-#endif
+ *			krbv42ldap	[1] OCTET STRING -- OBSOLETE
+ *			krbv42dsa	[2] OCTET STRING -- OBSOLETE
  *			sasl		[3] SaslCredentials	-- LDAPv3
  *		}
  *	}
@@ -39,27 +47,14 @@
  *		serverSaslCreds		OCTET STRING OPTIONAL -- LDAPv3
  *	}
  *
+ * (Source: RFC 2251)
  */
 
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/stdlib.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#include "ldap-int.h"
-#include "ldap_log.h"
-
 /*
  * ldap_bind - bind to the ldap server (and X.500).  The dn and password
  * of the entry to which to bind are supplied, along with the authentication
  * method to use.  The msgid of the bind request is returned on success,
- * -1 if there's trouble.  Note, the kerberos support assumes the user already
- * has a valid tgt for now.  ldap_result() should be called to find out the
+ * -1 if there's trouble.  ldap_result() should be called to find out the
  * outcome of the bind request.
  *
  * Example:
@@ -76,14 +71,6 @@
 	case LDAP_AUTH_SIMPLE:
 		return( ldap_simple_bind( ld, dn, passwd ) );
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-	case LDAP_AUTH_KRBV41:
-		return( ldap_kerberos_bind1( ld, dn ) );
-
-	case LDAP_AUTH_KRBV42:
-		return( ldap_kerberos_bind2( ld, dn ) );
-#endif
-
 	case LDAP_AUTH_SASL:
 		/* user must use ldap_sasl_bind */
 		/* FALL-THRU */
@@ -99,8 +86,7 @@
  * of the entry to which to bind are supplied, along with the authentication
  * method to use.  This routine just calls whichever bind routine is
  * appropriate and returns the result of the bind (e.g. LDAP_SUCCESS or
- * some other error indication).  Note, the kerberos support assumes the
- * user already has a valid tgt for now.
+ * some other error indication).
  *
  * Examples:
  *	ldap_bind_s( ld, "cn=manager, o=university of michigan, c=us",
@@ -121,17 +107,6 @@
 	case LDAP_AUTH_SIMPLE:
 		return( ldap_simple_bind_s( ld, dn, passwd ) );
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-	case LDAP_AUTH_KRBV4:
-		return( ldap_kerberos_bind_s( ld, dn ) );
-
-	case LDAP_AUTH_KRBV41:
-		return( ldap_kerberos_bind1_s( ld, dn ) );
-
-	case LDAP_AUTH_KRBV42:
-		return( ldap_kerberos_bind2_s( ld, dn ) );
-#endif
-
 	case LDAP_AUTH_SASL:
 		/* user must use ldap_sasl_bind */
 		/* FALL-THRU */

Modified: openldap/trunk/libraries/libldap/cancel.c
===================================================================
--- openldap/trunk/libraries/libldap/cancel.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/cancel.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/cancel.c,v 1.7.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/cancel.c,v 1.10.2.3 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -13,8 +13,8 @@
  * <http://www.OpenLDAP.org/license.html>.
  */
 /* ACKNOWLEDGEMENTS:
- * This program was orignally developed by Kurt D. Zeilenga for inclusion in
- * OpenLDAP Software.
+ * This program was originally developed by Kurt D. Zeilenga for inclusion
+ * in OpenLDAP Software.
  */
 
 /*
@@ -48,8 +48,8 @@
 	cancelidber = ber_alloc_t( LBER_USE_DER );
 	ber_printf( cancelidber, "{i}", cancelid );
 	ber_flatten( cancelidber, &cancelidvalp );
-	rc = ldap_extended_operation( ld, LDAP_EXOP_X_CANCEL,
-			cancelidvalp, sctrls, cctrls, msgidp );
+	rc = ldap_extended_operation( ld, LDAP_EXOP_CANCEL,
+		cancelidvalp, sctrls, cctrls, msgidp );
 	ber_free( cancelidber, 1 );
 	return rc;
 }
@@ -68,8 +68,8 @@
 	cancelidber = ber_alloc_t( LBER_USE_DER );
 	ber_printf( cancelidber, "{i}", cancelid );
 	ber_flatten( cancelidber, &cancelidvalp );
-	rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_CANCEL,
-			cancelidvalp, sctrls, cctrls, NULL, NULL );
+	rc = ldap_extended_operation_s( ld, LDAP_EXOP_CANCEL,
+		cancelidvalp, sctrls, cctrls, NULL, NULL );
 	ber_free( cancelidber, 1 );
 	return rc;
 }

Modified: openldap/trunk/libraries/libldap/charray.c
===================================================================
--- openldap/trunk/libraries/libldap/charray.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/charray.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* charray.c - routines for dealing with char * arrays */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/charray.c,v 1.14.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/charray.c,v 1.16.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/compare.c
===================================================================
--- openldap/trunk/libraries/libldap/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/compare.c,v 1.26.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/compare.c,v 1.29.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -15,20 +15,7 @@
 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
  * All rights reserved.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
-/* The compare request looks like this:
- *	CompareRequest ::= SEQUENCE {
- *		entry	DistinguishedName,
- *		ava	SEQUENCE {
- *			type	AttributeType,
- *			value	AttributeValue
- *		}
- *	}
- */
-
 #include "portable.h"
 
 #include <stdio.h>
@@ -40,6 +27,16 @@
 #include "ldap-int.h"
 #include "ldap_log.h"
 
+/* The compare request looks like this:
+ *	CompareRequest ::= SEQUENCE {
+ *		entry	DistinguishedName,
+ *		ava	SEQUENCE {
+ *			type	AttributeType,
+ *			value	AttributeValue
+ *		}
+ *	}
+ */
+
 /*
  * ldap_compare_ext - perform an ldap extended compare operation.  The dn
  * of the entry to compare to and the attribute and value to compare (in
@@ -156,7 +153,7 @@
 	if (  rc != LDAP_SUCCESS )
 		return( rc );
 
-	if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
+	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
 		return( ld->ld_errno );
 
 	return( ldap_result2error( ld, res, 1 ) );

Modified: openldap/trunk/libraries/libldap/controls.c
===================================================================
--- openldap/trunk/libraries/libldap/controls.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/controls.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/controls.c,v 1.45.2.4 2007/08/22 20:44:41 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/controls.c,v 1.48.2.4 2007/10/17 02:03:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -30,13 +30,19 @@
  * can be found in the file "build/LICENSE-2.0.1" in this distribution
  * of OpenLDAP Software.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
-/* LDAPv3 Controls (RFC2251)
+#include "portable.h"
+
+#include <ac/stdlib.h>
+
+#include <ac/time.h>
+#include <ac/string.h>
+
+#include "ldap-int.h"
+
+/* LDAPv3 Controls (RFC 4511)
  *
- *	Controls ::= SEQUENCE OF Control  
+ *	Controls ::= SEQUENCE OF control Control  
  *
  *	Control ::= SEQUENCE { 
  *		controlType		LDAPOID,
@@ -45,16 +51,36 @@
  *	}
  */
 
-#include "portable.h"
+int
+ldap_pvt_put_control(
+	const LDAPControl *c,
+	BerElement *ber )
+{
+	if ( ber_printf( ber, "{s" /*}*/, c->ldctl_oid ) == -1 ) {
+		return LDAP_ENCODING_ERROR;
+	}
 
-#include <ac/stdlib.h>
+	if ( c->ldctl_iscritical /* only if true */
+		&&  ( ber_printf( ber, "b",
+			(ber_int_t) c->ldctl_iscritical ) == -1 ) )
+	{
+		return LDAP_ENCODING_ERROR;
+	}
 
-#include <ac/time.h>
-#include <ac/string.h>
+	if ( !BER_BVISNULL( &c->ldctl_value ) /* only if we have a value */
+		&&  ( ber_printf( ber, "O", &c->ldctl_value ) == -1 ) )
+	{
+		return LDAP_ENCODING_ERROR;
+	}
 
-#include "ldap-int.h"
+	if ( ber_printf( ber, /*{*/"N}" ) == -1 ) {
+		return LDAP_ENCODING_ERROR;
+	}
 
+	return LDAP_SUCCESS;
+}
 
+
 /*
  * ldap_int_put_controls
  */
@@ -68,7 +94,7 @@
 	LDAPControl *const *c;
 
 	assert( ld != NULL );
-	assert( LDAP_VALID(ld) );
+	assert( LDAP_VALID( ld ) );
 	assert( ber != NULL );
 
 	if( ctrls == NULL ) {
@@ -101,34 +127,10 @@
 	}
 
 	for( c = ctrls ; *c != NULL; c++ ) {
-		if ( ber_printf( ber, "{s" /*}*/,
-			(*c)->ldctl_oid ) == -1 )
-		{
-			ld->ld_errno = LDAP_ENCODING_ERROR;
+		ld->ld_errno = ldap_pvt_put_control( *c, ber );
+		if ( ld->ld_errno != LDAP_SUCCESS ) {
 			return ld->ld_errno;
 		}
-
-		if( (*c)->ldctl_iscritical /* only if true */
-			&&  ( ber_printf( ber, "b",
-				(ber_int_t) (*c)->ldctl_iscritical ) == -1 ) )
-		{
-			ld->ld_errno = LDAP_ENCODING_ERROR;
-			return ld->ld_errno;
-		}
-
-		if( (*c)->ldctl_value.bv_val != NULL /* only if we have a value */
-			&&  ( ber_printf( ber, "O",
-				&((*c)->ldctl_value) ) == -1 ) )
-		{
-			ld->ld_errno = LDAP_ENCODING_ERROR;
-			return ld->ld_errno;
-		}
-
-
-		if( ber_printf( ber, /*{*/"N}" ) == -1 ) {
-			ld->ld_errno = LDAP_ENCODING_ERROR;
-			return ld->ld_errno;
-		}
 	}
 
 
@@ -235,7 +237,7 @@
 		if( tag == LBER_OCTETSTRING ) {
 			tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
 		} else {
-			tctrl->ldctl_value.bv_val = NULL;
+			BER_BVZERO( &tctrl->ldctl_value );
 		}
 
 		*ctrls = tctrls;
@@ -250,9 +252,7 @@
 void
 ldap_control_free( LDAPControl *c )
 {
-#ifdef LDAP_MEMORY_DEBUG
-	assert( c != NULL );
-#endif
+	LDAP_MEMORY_DEBUG_ASSERT( c != NULL );
 
 	if ( c != NULL ) {
 		if( c->ldctl_oid != NULL) {
@@ -273,9 +273,7 @@
 void
 ldap_controls_free( LDAPControl **controls )
 {
-#ifdef LDAP_MEMORY_DEBUG
-	assert( controls != NULL );
-#endif
+	LDAP_MEMORY_DEBUG_ASSERT( controls != NULL );
 
 	if ( controls != NULL ) {
 		int i;
@@ -339,7 +337,7 @@
 {
 	LDAPControl *new;
 
-	if ( c == NULL ) {
+	if ( c == NULL || c->ldctl_oid == NULL ) {
 		return NULL;
 	}
 
@@ -349,16 +347,11 @@
 		return NULL;
 	}
 
-	if( c->ldctl_oid != NULL ) {
-		new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
+	new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
 
-		if(new->ldctl_oid == NULL) {
-			LDAP_FREE( new );
-			return NULL;
-		}
-
-	} else {
-		new->ldctl_oid = NULL;
+	if(new->ldctl_oid == NULL) {
+		LDAP_FREE( new );
+		return NULL;
 	}
 
 	if( c->ldctl_value.bv_val != NULL ) {
@@ -389,7 +382,9 @@
 	return new;
 }
 
-
+/*
+ * Find a LDAPControl - deprecated
+ */
 LDAPControl *
 ldap_find_control(
 	LDAP_CONST char *oid,
@@ -409,21 +404,38 @@
 }
 
 /*
-   ldap_create_control
-   
-   Internal function to create an LDAP control from the encoded BerElement.
+ * Find a LDAPControl
+ */
+LDAPControl *
+ldap_control_find(
+	LDAP_CONST char *oid,
+	LDAPControl **ctrls,
+	LDAPControl ***nextctrlp )
+{
+	if ( oid == NULL || ctrls == NULL || *ctrls == NULL ) {
+		return NULL;
+	}
 
-   requestOID  (IN) The OID to use in creating the control.
-   
-   ber         (IN) The encoded BerElement to use in creating the control.
-   
-   iscritical  (IN) 0 - Indicates the control is not critical to the operation.
-					non-zero - The control is critical to the operation.
-				  
-   ctrlp      (OUT) Returns a pointer to the LDAPControl created.  This control
-					SHOULD be freed by calling ldap_control_free() when done.
----*/
+	for( ; *ctrls != NULL; ctrls++ ) {
+		if( strcmp( (*ctrls)->ldctl_oid, oid ) == 0 ) {
+			if ( nextctrlp != NULL ) {
+				*nextctrlp = ctrls + 1;
+			}
 
+			return *ctrls;
+		}
+	}
+
+	if ( nextctrlp != NULL ) {
+		*nextctrlp = NULL;
+	}
+
+	return NULL;
+}
+
+/*
+ * Create a LDAPControl, optionally from ber - deprecated
+ */
 int
 ldap_create_control(
 	LDAP_CONST char *requestOID,
@@ -434,7 +446,6 @@
 	LDAPControl *ctrl;
 
 	assert( requestOID != NULL );
-	assert( ber != NULL );
 	assert( ctrlp != NULL );
 
 	ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
@@ -442,8 +453,8 @@
 		return LDAP_NO_MEMORY;
 	}
 
-	BER_BVZERO( &ctrl->ldctl_value );
-	if ( ber != NULL && ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) {
+	BER_BVZERO(&ctrl->ldctl_value);
+	if ( ber && ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 )) {
 		LDAP_FREE( ctrl );
 		return LDAP_NO_MEMORY;
 	}
@@ -461,6 +472,54 @@
 }
 
 /*
+ * Create a LDAPControl, optionally from value
+ */
+int
+ldap_control_create(
+	LDAP_CONST char *requestOID,
+	int iscritical,
+	struct berval *value,
+	int dupval,
+	LDAPControl **ctrlp )
+{
+	LDAPControl *ctrl;
+
+	assert( requestOID != NULL );
+	assert( ctrlp != NULL );
+
+	ctrl = (LDAPControl *) LDAP_CALLOC( sizeof(LDAPControl), 1 );
+	if ( ctrl == NULL ) {
+		return LDAP_NO_MEMORY;
+	}
+
+	ctrl->ldctl_iscritical = iscritical;
+	if ( requestOID != NULL ) {
+		ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
+		if ( ctrl->ldctl_oid == NULL ) {
+			ldap_control_free( ctrl );
+			return LDAP_NO_MEMORY;
+		}
+	}
+
+	if ( value && !BER_BVISNULL( value ) ) {
+		if ( dupval ) {
+			ber_dupbv( &ctrl->ldctl_value, value );
+			if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
+				ldap_control_free( ctrl );
+				return LDAP_NO_MEMORY;
+			}
+
+		} else {
+			ctrl->ldctl_value = *value;
+		}
+	}
+
+	*ctrlp = ctrl;
+
+	return LDAP_SUCCESS;
+}
+
+/*
  * check for critical client controls and bitch if present
  * if we ever support critical controls, we'll have to
  * find a means for maintaining per API call control
@@ -471,7 +530,7 @@
 	LDAPControl *const *c;
 
 	assert( ld != NULL );
-	assert( LDAP_VALID(ld) );
+	assert( LDAP_VALID( ld ) );
 
 	if( ctrls == NULL ) {
 		/* use default server controls */

Modified: openldap/trunk/libraries/libldap/cyrus.c
===================================================================
--- openldap/trunk/libraries/libldap/cyrus.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/cyrus.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/cyrus.c,v 1.112.2.17 2007/10/08 09:53:53 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/cyrus.c,v 1.133.2.6 2007/10/08 09:52:25 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -165,7 +165,7 @@
 		return -1;
 	}
 	sasl_getprop( p->sasl_context, SASL_MAXOUTBUF,
-		(SASL_CONST void **) &p->sasl_maxbuf );
+		(SASL_CONST void **)(char *) &p->sasl_maxbuf );
 	    
 	sbiod->sbiod_pvt = p;
 
@@ -847,7 +847,7 @@
 
 	if( flags != LDAP_SASL_QUIET ) {
 		saslrc = sasl_getprop( ctx, SASL_USERNAME,
-			(SASL_CONST void **) &data );
+			(SASL_CONST void **)(char *) &data );
 		if( saslrc == SASL_OK && data && *data ) {
 			fprintf( stderr, "SASL username: %s\n", data );
 		}
@@ -861,7 +861,7 @@
 #endif
 	}
 
-	saslrc = sasl_getprop( ctx, SASL_SSF, (SASL_CONST void **) &ssf );
+	saslrc = sasl_getprop( ctx, SASL_SSF, (SASL_CONST void **)(char *) &ssf );
 	if( saslrc == SASL_OK ) {
 		if( flags != LDAP_SASL_QUIET ) {
 			fprintf( stderr, "SASL SSF: %lu\n",
@@ -869,9 +869,6 @@
 		}
 
 		if( ssf && *ssf ) {
-			if( flags != LDAP_SASL_QUIET ) {
-				fprintf( stderr, "SASL installing layers\n" );
-			}
 			if ( ld->ld_defconn->lconn_sasl_sockctx ) {
 				oldctx = ld->ld_defconn->lconn_sasl_sockctx;
 				sasl_dispose( &oldctx );
@@ -879,6 +876,10 @@
 			}
 			ldap_pvt_sasl_install( ld->ld_defconn->lconn_sb, ctx );
 			ld->ld_defconn->lconn_sasl_sockctx = ctx;
+
+			if( flags != LDAP_SASL_QUIET ) {
+				fprintf( stderr, "SASL data security layer installed.\n" );
+			}
 		}
 	}
 	ld->ld_defconn->lconn_sasl_authctx = ctx;
@@ -1159,7 +1160,7 @@
 			}
 
 			sc = sasl_getprop( ctx, SASL_SSF,
-				(SASL_CONST void **) &ssf );
+				(SASL_CONST void **)(char *) &ssf );
 
 			if ( sc != SASL_OK ) {
 				return -1;
@@ -1195,7 +1196,7 @@
 int
 ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
 {
-	if ( ld == NULL )
+	if ( ld == NULL || arg == NULL )
 		return -1;
 
 	switch ( option ) {
@@ -1269,7 +1270,7 @@
 {
 	ldap_pvt_thread_mutex_t *mutex;
 
-	mutex = (ldap_pvt_thread_mutex_t *) LDAP_MALLOC(
+	mutex = (ldap_pvt_thread_mutex_t *) LDAP_CALLOC( 1,
 		sizeof(ldap_pvt_thread_mutex_t) );
 
 	if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) {

Copied: openldap/trunk/libraries/libldap/dds.c (from rev 891, openldap/vendor/openldap-2.4.7/libraries/libldap/dds.c)
===================================================================
--- openldap/trunk/libraries/libldap/dds.c	                        (rev 0)
+++ openldap/trunk/libraries/libldap/dds.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,156 @@
+/* $OpenLDAP: pkg/ldap/libraries/libldap/dds.c,v 1.2.2.2 2007/08/31 23:13:55 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2005-2007 The OpenLDAP Foundation.
+ * Portions Copyright 2005-2006 SysNet s.n.c.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was developed by Pierangelo Masarati for inclusion
+ * in OpenLDAP Software */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+
+int
+ldap_parse_refresh( LDAP *ld, LDAPMessage *res, ber_int_t *newttl )
+{
+	int		rc;
+	struct berval	*retdata = NULL;
+	ber_tag_t	tag;
+	BerElement	*ber;
+
+	assert( ld != NULL );
+	assert( LDAP_VALID( ld ) );
+	assert( res != NULL );
+	assert( newttl != NULL );
+
+	*newttl = 0;
+
+	rc = ldap_parse_extended_result( ld, res, NULL, &retdata, 0 );
+
+	if ( rc != LDAP_SUCCESS ) {
+		return rc;
+	}
+
+	if ( ld->ld_errno != LDAP_SUCCESS ) {
+		return ld->ld_errno;
+	}
+
+	if ( retdata == NULL ) {
+		rc = ld->ld_errno = LDAP_DECODING_ERROR;
+		return rc;
+	}
+
+	ber = ber_init( retdata );
+	if ( ber == NULL ) {
+		rc = ld->ld_errno = LDAP_NO_MEMORY;
+		goto done;
+	}
+
+	/* check the tag */
+	tag = ber_scanf( ber, "{i}", newttl );
+	ber_free( ber, 1 );
+
+	if ( tag != LDAP_TAG_EXOP_REFRESH_RES_TTL ) {
+		*newttl = 0;
+		rc = ld->ld_errno = LDAP_DECODING_ERROR;
+	}
+
+done:;
+	if ( retdata ) {
+		ber_bvfree( retdata );
+	}
+
+	return rc;
+}
+
+int
+ldap_refresh(
+	LDAP		*ld,
+	struct berval	*dn,
+	ber_int_t		ttl,
+	LDAPControl	**sctrls,
+	LDAPControl	**cctrls,
+	int		*msgidp )
+{
+	struct berval	bv = { 0, NULL };
+        BerElement	*ber = NULL;
+	int		rc;
+
+	assert( ld != NULL );
+	assert( LDAP_VALID( ld ) );
+	assert( dn != NULL );
+	assert( msgidp != NULL );
+
+	*msgidp = -1;
+
+	ber = ber_alloc_t( LBER_USE_DER );
+
+	if ( ber == NULL ) {
+		ld->ld_errno = LDAP_NO_MEMORY;
+		return ld->ld_errno;
+	}
+
+	ber_printf( ber, "{tOtiN}",
+		LDAP_TAG_EXOP_REFRESH_REQ_DN, dn,
+		LDAP_TAG_EXOP_REFRESH_REQ_TTL, ttl );
+
+	rc = ber_flatten2( ber, &bv, 0 );
+
+	if ( rc < 0 ) {
+		rc = ld->ld_errno = LDAP_ENCODING_ERROR;
+		goto done;
+	}
+
+	rc = ldap_extended_operation( ld, LDAP_EXOP_REFRESH, &bv,
+		sctrls, cctrls, msgidp );
+
+done:;
+        ber_free( ber, 1 );
+
+	return rc;
+}
+
+int
+ldap_refresh_s(
+	LDAP		*ld,
+	struct berval	*dn,
+	ber_int_t		ttl,
+	ber_int_t		*newttl,
+	LDAPControl	**sctrls,
+	LDAPControl	**cctrls )
+{
+	int		rc;
+	int		msgid;
+	LDAPMessage	*res;
+
+	rc = ldap_refresh( ld, dn, ttl, sctrls, cctrls, &msgid );
+	if ( rc != LDAP_SUCCESS ) return rc;
+	
+	rc = ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *)NULL, &res );
+	if( rc == -1 || !res ) return ld->ld_errno;
+
+	rc = ldap_parse_refresh( ld, res, newttl );
+	if( rc != LDAP_SUCCESS ) {
+		ldap_msgfree( res );
+		return rc;
+	}
+
+	return ldap_result2error( ld, res, 1 );
+}
+

Modified: openldap/trunk/libraries/libldap/delete.c
===================================================================
--- openldap/trunk/libraries/libldap/delete.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/delete.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/delete.c,v 1.23.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/delete.c,v 1.26.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -15,16 +15,7 @@
 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
  * All rights reserved.
  */
-/*
- * Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
-/*
- * A delete request looks like this:
- *	DelRequet ::= DistinguishedName,
- */
-
 #include "portable.h"
 
 #include <stdio.h>
@@ -36,6 +27,12 @@
 #include "ldap-int.h"
 
 /*
+ * A delete request looks like this:
+ *	DelRequet ::= DistinguishedName,
+ */
+
+
+/*
  * ldap_delete_ext - initiate an ldap extended delete operation. Parameters:
  *
  *	ld		LDAP descriptor
@@ -123,7 +120,7 @@
 	if( rc != LDAP_SUCCESS )
 		return( ld->ld_errno );
 
-	if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
+	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
 		return( ld->ld_errno );
 
 	return( ldap_result2error( ld, res, 1 ) );

Modified: openldap/trunk/libraries/libldap/dnssrv.c
===================================================================
--- openldap/trunk/libraries/libldap/dnssrv.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/dnssrv.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/dnssrv.c,v 1.37.2.4 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/dnssrv.c,v 1.39.2.3 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -276,7 +276,7 @@
 		port = (p[4] << 8) | p[5];
 
 		if ( port == 0 || host[ 0 ] == '\0' ) {
-			goto add_size;
+		    goto add_size;
 		}
 
 		buflen = strlen(host) + STRLENOF(":65355 ");

Modified: openldap/trunk/libraries/libldap/dntest.c
===================================================================
--- openldap/trunk/libraries/libldap/dntest.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/dntest.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* dntest.c -- OpenLDAP DN API Test Program */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/dntest.c,v 1.24.2.4 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/dntest.c,v 1.27.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/error.c
===================================================================
--- openldap/trunk/libraries/libldap/error.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/error.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/error.c,v 1.64.2.9 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/error.c,v 1.76.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -12,9 +12,6 @@
  * top-level directory of the distribution or, alternatively, at
  * <http://www.OpenLDAP.org/license.html>.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
 #include "portable.h"
 
@@ -65,7 +62,6 @@
 	{LDAP_IS_LEAF, 					N_("Entry is a leaf")},
 	{LDAP_ALIAS_DEREF_PROBLEM,	 	N_("Alias dereferencing problem")},
 
-	{LDAP_PROXY_AUTHZ_FAILURE,		N_("Proxy Authorization Failure")},
 	{LDAP_INAPPROPRIATE_AUTH, 		N_("Inappropriate authentication")},
 	{LDAP_INVALID_CREDENTIALS, 		N_("Invalid credentials")},
 	{LDAP_INSUFFICIENT_ACCESS, 		N_("Insufficient access")},
@@ -83,7 +79,7 @@
 	{LDAP_RESULTS_TOO_LARGE,		N_("Results too large")},
 	{LDAP_AFFECTS_MULTIPLE_DSAS,	N_("Operation affects multiple DSAs")},
 
-	{LDAP_OTHER, 					N_("Internal (implementation specific) error")},
+	{LDAP_OTHER, 					N_("Other (e.g., implementation specific) error")},
 
 	{LDAP_CANCELLED,				N_("Cancelled")},
 	{LDAP_NO_SUCH_OPERATION,		N_("No Operation to Cancel")},
@@ -93,6 +89,9 @@
 	{LDAP_ASSERTION_FAILED,			N_("Assertion Failed")},
 	{LDAP_X_ASSERTION_FAILED,		N_("Assertion Failed (X)")},
 
+	{LDAP_PROXIED_AUTHORIZATION_DENIED, N_("Proxied Authorization Denied")},
+	{LDAP_X_PROXY_AUTHZ_FAILURE,		N_("Proxy Authorization Failure (X)")},
+
 	{LDAP_SYNC_REFRESH_REQUIRED,	N_("Content Sync Refresh Required")},
 	{LDAP_X_SYNC_REFRESH_REQUIRED,	N_("Content Sync Refresh Required (X)")},
 
@@ -324,24 +323,14 @@
 	ber = ber_dup( lm->lm_ber );
 
 	if ( ld->ld_version < LDAP_VERSION2 ) {
-#ifdef LDAP_NULL_IS_NULL
 		tag = ber_scanf( ber, "{iA}",
 			&ld->ld_errno, &ld->ld_error );
-#else /* ! LDAP_NULL_IS_NULL */
-		tag = ber_scanf( ber, "{ia}",
-			&ld->ld_errno, &ld->ld_error );
-#endif /* ! LDAP_NULL_IS_NULL */
 
 	} else {
 		ber_len_t len;
 
-#ifdef LDAP_NULL_IS_NULL
 		tag = ber_scanf( ber, "{iAA" /*}*/,
 			&ld->ld_errno, &ld->ld_matched, &ld->ld_error );
-#else /* ! LDAP_NULL_IS_NULL */
-		tag = ber_scanf( ber, "{iaa" /*}*/,
-			&ld->ld_errno, &ld->ld_matched, &ld->ld_error );
-#endif /* ! LDAP_NULL_IS_NULL */
 
 		if( tag != LBER_ERROR ) {
 			/* peek for referrals */
@@ -402,17 +391,13 @@
 	}
 	if ( errcode == LDAP_SUCCESS ) {
 		if( matcheddnp != NULL ) {
-#ifdef LDAP_NULL_IS_NULL
 			if ( ld->ld_matched )
-#endif /* LDAP_NULL_IS_NULL */
 			{
 				*matcheddnp = LDAP_STRDUP( ld->ld_matched );
 			}
 		}
 		if( errmsgp != NULL ) {
-#ifdef LDAP_NULL_IS_NULL
 			if ( ld->ld_error )
-#endif /* LDAP_NULL_IS_NULL */
 			{
 				*errmsgp = LDAP_STRDUP( ld->ld_error );
 			}

Modified: openldap/trunk/libraries/libldap/extended.c
===================================================================
--- openldap/trunk/libraries/libldap/extended.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/extended.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/extended.c,v 1.32.2.6 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/extended.c,v 1.39.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -12,10 +12,19 @@
  * top-level directory of the distribution or, alternatively, at
  * <http://www.OpenLDAP.org/license.html>.
  */
-/* Portions Copyright (C) The Internet Society (1997).
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+#include "ldap_log.h"
+
 /*
  * LDAPv3 Extended Operation Request
  *	ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
@@ -30,20 +39,9 @@
  *		response         [11] OCTET STRING OPTIONAL
  *	}
  *
+ * (Source RFC 4511)
  */
 
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/stdlib.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#include "ldap-int.h"
-#include "ldap_log.h"
-
 int
 ldap_extended_operation(
 	LDAP			*ld,
@@ -140,7 +138,7 @@
         return( rc );
 	}
  
-    if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) {
+    if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res ) {
         return( ld->ld_errno );
 	}
 
@@ -210,13 +208,8 @@
 		return ld->ld_errno;
 	}
 
-#ifdef LDAP_NULL_IS_NULL
 	rc = ber_scanf( ber, "{eAA" /*}*/, &errcode,
 		&ld->ld_matched, &ld->ld_error );
-#else /* ! LDAP_NULL_IS_NULL */
-	rc = ber_scanf( ber, "{eaa" /*}*/, &errcode,
-		&ld->ld_matched, &ld->ld_error );
-#endif /* ! LDAP_NULL_IS_NULL */
 
 	if( rc == LBER_ERROR ) {
 		ld->ld_errno = LDAP_DECODING_ERROR;
@@ -248,9 +241,7 @@
 			return ld->ld_errno;
 		}
 
-#ifdef LDAP_NULL_IS_NULL
 		assert( resoid[ 0 ] != '\0' );
-#endif /* LDAP_NULL_IS_NULL */
 
 		tag = ber_peek_tag( ber, &len );
 	}
@@ -324,6 +315,7 @@
 
 	if( retoidp != NULL ) *retoidp = NULL;
 	if( retdatap != NULL ) *retdatap = NULL;
+	if( serverctrls != NULL ) *serverctrls = NULL;
 
 	ber = ber_dup( res->lm_ber );
 
@@ -359,9 +351,7 @@
 			return ld->ld_errno;
 		}
 
-#ifdef LDAP_NULL_IS_NULL
 		assert( resoid[ 0 ] != '\0' );
-#endif /* LDAP_NULL_IS_NULL */
 
 		tag = ber_peek_tag( ber, &len );
 	}

Modified: openldap/trunk/libraries/libldap/filter.c
===================================================================
--- openldap/trunk/libraries/libldap/filter.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/filter.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* search.c */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/filter.c,v 1.27.2.4 2007/01/10 09:22:18 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/filter.c,v 1.29.2.3 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -16,9 +16,6 @@
 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
  * All rights reserved.
  */
-/* Portions Copyright (C) The Internet Society (1997).
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
 #include "portable.h"
 
@@ -334,36 +331,36 @@
 	int	parens, balance, escape;
 
 	/*
-	 * A Filter looks like this:
-	 *      Filter ::= CHOICE {
-	 *              and             [0]     SET OF Filter,
-	 *              or              [1]     SET OF Filter,
-	 *              not             [2]     Filter,
-	 *              equalityMatch   [3]     AttributeValueAssertion,
-	 *              substrings      [4]     SubstringFilter,
-	 *              greaterOrEqual  [5]     AttributeValueAssertion,
-	 *              lessOrEqual     [6]     AttributeValueAssertion,
-	 *              present         [7]     AttributeType,
-	 *              approxMatch     [8]     AttributeValueAssertion,
-	 *		extensibleMatch [9]	MatchingRuleAssertion -- LDAPv3
-	 *      }
+	 * A Filter looks like this (RFC 4511 as extended by RFC 4526):
+	 *     Filter ::= CHOICE {
+	 *         and             [0]     SET SIZE (0..MAX) OF filter Filter,
+	 *         or              [1]     SET SIZE (0..MAX) OF filter Filter,
+	 *         not             [2]     Filter,
+	 *         equalityMatch   [3]     AttributeValueAssertion,
+	 *         substrings      [4]     SubstringFilter,
+	 *         greaterOrEqual  [5]     AttributeValueAssertion,
+	 *         lessOrEqual     [6]     AttributeValueAssertion,
+	 *         present         [7]     AttributeDescription,
+	 *         approxMatch     [8]     AttributeValueAssertion,
+	 *         extensibleMatch [9]     MatchingRuleAssertion,
+	 *         ... }
 	 *
-	 *      SubstringFilter ::= SEQUENCE {
-	 *              type               AttributeType,
-	 *              SEQUENCE OF CHOICE {
-	 *                      initial          [0] IA5String,
-	 *                      any              [1] IA5String,
-	 *                      final            [2] IA5String
-	 *              }
-	 *      }
+	 *     SubstringFilter ::= SEQUENCE {
+	 *         type         AttributeDescription,
+	 *         substrings   SEQUENCE SIZE (1..MAX) OF substring CHOICE {
+	 *             initial          [0] AssertionValue, -- only once
+	 *             any              [1] AssertionValue,
+	 *             final            [2] AssertionValue  -- only once
+	 *             }
+	 *         }
 	 *
-	 *	MatchingRuleAssertion ::= SEQUENCE {	-- LDAPv3
-	 *		matchingRule    [1] MatchingRuleId OPTIONAL,
-	 *		type            [2] AttributeDescription OPTIONAL,
-	 *		matchValue      [3] AssertionValue,
-	 *		dnAttributes    [4] BOOLEAN DEFAULT FALSE }
+	 *	   MatchingRuleAssertion ::= SEQUENCE {
+	 *         matchingRule    [1] MatchingRuleId OPTIONAL,
+	 *         type            [2] AttributeDescription OPTIONAL,
+	 *         matchValue      [3] AssertionValue,
+	 *         dnAttributes    [4] BOOLEAN DEFAULT FALSE }
 	 *
-	 * Note: tags in a choice are always explicit
+	 * Note: tags in a CHOICE are always explicit
 	 */
 
 	Debug( LDAP_DEBUG_TRACE, "put_filter: \"%s\"\n", str_in, 0, 0 );
@@ -592,7 +589,7 @@
 		break;
 
 	case ':':
-		/* RFC2254 extensible filters are off the form:
+		/* RFC 4515 extensible filters are off the form:
 		 *		type [:dn] [:rule] := value
 		 * or	[:dn]:rule := value		
 		 */
@@ -810,6 +807,8 @@
 	 *		matchingRule    [1] MatchingRuleId OPTIONAL,
 	 *		type            [2] AttributeDescription OPTIONAL,
 	 *		matchValue      [3] AssertionValue }
+	 *
+	 * (Source: RFC 3876)
 	 */
 
 	Debug( LDAP_DEBUG_TRACE, "put_vrFilter: \"%s\"\n", str_in, 0, 0 );

Modified: openldap/trunk/libraries/libldap/free.c
===================================================================
--- openldap/trunk/libraries/libldap/free.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/free.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* free.c */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/free.c,v 1.20.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/free.c,v 1.22.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/ftest.c
===================================================================
--- openldap/trunk/libraries/libldap/ftest.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/ftest.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ftest.c -- OpenLDAP Filter API Test */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/ftest.c,v 1.13.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/ftest.c,v 1.15.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -38,7 +38,7 @@
 {
 	fprintf( stderr, "usage:\n"
 		"  ftest [-d n] filter\n"
-		"    filter - RFC 2254 string representation of an "
+		"    filter - RFC 4515 string representation of an "
 			"LDAP search filter\n" );
 	return EXIT_FAILURE;
 }

Modified: openldap/trunk/libraries/libldap/getattr.c
===================================================================
--- openldap/trunk/libraries/libldap/getattr.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/getattr.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/getattr.c,v 1.33.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/getattr.c,v 1.35.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/getdn.c
===================================================================
--- openldap/trunk/libraries/libldap/getdn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/getdn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/getdn.c,v 1.124.2.6 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/getdn.c,v 1.130.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -337,16 +337,15 @@
  * from ( fin & LDAP_DN_FORMAT_MASK ) to ( fout & LDAP_DN_FORMAT_MASK )
  * 
  * fin can be one of:
- * 	LDAP_DN_FORMAT_LDAP		(rfc 2253 and ldapbis liberal, 
- * 					plus some rfc 1779)
- * 	LDAP_DN_FORMAT_LDAPV3		(rfc 2253 and ldapbis)
- * 	LDAP_DN_FORMAT_LDAPV2		(rfc 1779)
+ * 	LDAP_DN_FORMAT_LDAP		(RFC 4514 liberal, plus some RFC 1779)
+ * 	LDAP_DN_FORMAT_LDAPV3	(RFC 4514)
+ * 	LDAP_DN_FORMAT_LDAPV2	(RFC 1779)
  * 	LDAP_DN_FORMAT_DCE		(?)
  *
  * fout can be any of the above except
  * 	LDAP_DN_FORMAT_LDAP
  * plus:
- * 	LDAP_DN_FORMAT_UFN		(rfc 1781, partial and with extensions)
+ * 	LDAP_DN_FORMAT_UFN		(RFC 1781, partial and with extensions)
  * 	LDAP_DN_FORMAT_AD_CANONICAL	(?)
  */
 int
@@ -433,14 +432,14 @@
 #define LDAP_DN_VALUE_END(c) \
 	( LDAP_DN_RDN_SEP(c) || LDAP_DN_AVA_SEP(c) )
 
-/* NOTE: according to draft-ietf-ldapbis-dn, '=' can be escaped
- * and treated as special, i.e. escaped both as "\<hexpair>" and
- * as "\=", but it is treated as a regular char, i.e. it can also 
- * appear as '='.
+/* NOTE: according to RFC 4514, '=' can be escaped and treated as special,
+ * i.e. escaped both as "\<hexpair>" and * as "\=", but it is treated as
+ * a regular char, i.e. it can also appear as '='.
  *
- * As such, in 2.2 we used to allow reading unescaped '=',
- * but we always produced escaped '\3D'; this changes 
- * since 2.3, if compatibility issues do not arise */
+ * As such, in 2.2 we used to allow reading unescaped '=', but we always
+ * produced escaped '\3D'; this changes since 2.3, if compatibility issues
+ * do not arise
+ */
 #define LDAP_DN_NE(c) \
 	( LDAP_DN_RDN_SEP_V2(c) || LDAP_DN_AVA_SEP(c) \
 	  || LDAP_DN_QUOTES(c) \
@@ -1003,15 +1002,8 @@
 		 * an AttributeType can be encoded as:
 		 * - its string representation; in detail, implementations
 		 *   MUST recognize AttributeType string type names listed 
-		 *   in section 2.3 of draft-ietf-ldapbis-dn-XX.txt, and
-		 *   MAY recognize other names.
-		 * - its numeric OID (a dotted decimal string); in detail
-		 *   RFC 2253 asserts that ``Implementations MUST allow 
-		 *   an oid in the attribute type to be prefixed by one 
-		 *   of the character strings "oid." or "OID."''.  As soon
-		 *   as draft-ietf-ldapbis-dn-XX.txt obsoletes RFC 2253 
-		 *   I'm not sure whether this is required or not any 
-		 *   longer; to be liberal, we still implement it.
+		 *   in Section 3 of RFC 4514, and MAY recognize other names.
+		 * - its numeric OID (a dotted decimal string)
 		 */
 		case B4AVA:
 			if ( LDAP_DN_ASCII_SPACE( p[ 0 ] ) ) {
@@ -1111,9 +1103,8 @@
 				if ( LDAP_DN_LANG_SEP( p[ 0 ] ) ) {
 					
 					/*
-					 * RFC 2253 does not explicitly
-					 * allow lang extensions to attribute 
-					 * types in DNs ... 
+					 * RFC 4514 explicitly does not allow attribute
+					 * description options, such as language tags.
 					 */
 					if ( flags & LDAP_DN_PEDANTIC ) {
 						goto parsing_error;
@@ -1233,7 +1224,7 @@
 			}
 
 			/*
-			 * here STRING means RFC 2253 string
+			 * here STRING means RFC 4514 string
 			 * FIXME: what about DCE strings? 
 			 */
 			if ( !p[ 0 ] ) {
@@ -2377,12 +2368,12 @@
 
 /*
  * Length of the (supposedly) AD canonical string representation, 
- * accounting for escaped hex of UTF-8 chars
+ * accounting for chars that need to be escaped 
  */
 static int
 strval2ADstrlen( struct berval *val, unsigned flags, ber_len_t *len )
 {
-	ber_len_t	l;
+	ber_len_t	l, cl;
 	char		*p;
 
 	assert( val != NULL );
@@ -2393,37 +2384,31 @@
 		return( 0 );
 	}
 
-	if ( flags & LDAP_AVA_NONPRINTABLE ) {
-		/* 
-		 * FIXME: Turn the value into a binary encoded BER?
-		 */
-		return( -1 );
-		
-	} else {
-		for ( l = 0, p = val->bv_val; p[ 0 ]; p++ ) {
-			if ( LDAP_DN_NEEDESCAPE_AD( p[ 0 ] ) ) {
-				l += 2;
-
-			} else {
-				l++;
-			}
+	for ( l = 0, p = val->bv_val; p[ 0 ]; p += cl ) {
+		cl = LDAP_UTF8_CHARLEN2( p, cl );
+		if ( cl == 0 ) {
+			/* illegal utf-8 char */
+			return -1;
+		} else if ( (cl == 1) && LDAP_DN_NEEDESCAPE_AD( p[ 0 ] ) ) {
+			l += 2;
+		} else {
+			l += cl;
 		}
 	}
 
 	*len = l;
-	
+
 	return( 0 );
 }
 
 /*
- * convert to (supposedly) AD string representation, 
- * escaping with hex the UTF-8 stuff;
+ * convert to (supposedly) AD string representation,
  * assume the destination has enough room for escaping
  */
 static int
 strval2ADstr( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 {
-	ber_len_t	s, d;
+	ber_len_t	s, d, cl;
 
 	assert( val != NULL );
 	assert( str != NULL );
@@ -2434,24 +2419,20 @@
 		return( 0 );
 	}
 
-	if ( flags & LDAP_AVA_NONPRINTABLE ) {
-		/*
-		 * FIXME: Turn the value into a binary encoded BER?
-		 */
-		*len = 0;
-		return( -1 );
-		
-	} else {
+	/* 
+	 * we assume the string has enough room for the escaping
+	 * of the value
+	 */
 
-		/* 
-		 * we assume the string has enough room for the hex encoding
-		 * of the value
-		 */
-
-		for ( s = 0, d = 0; s < val->bv_len; ) {
-			if ( LDAP_DN_NEEDESCAPE_AD( val->bv_val[ s ] ) ) {
-				str[ d++ ] = '\\';
-			}
+	for ( s = 0, d = 0; s < val->bv_len; ) {
+		cl = LDAP_UTF8_CHARLEN2( val->bv_val+s, cl );
+		if ( cl == 0 ) {
+			/* illegal utf-8 char */
+			return -1;
+		} else if ( (cl == 1) && LDAP_DN_NEEDESCAPE_AD(val->bv_val[ s ]) ) {
+			str[ d++ ] = '\\';
+		}
+		for (; cl--;) {
 			str[ d++ ] = val->bv_val[ s++ ];
 		}
 	}
@@ -3318,202 +3299,3 @@
 	return( rc );
 }
 
-#ifdef HAVE_TLS
-#include <openssl/x509.h>
-#include <openssl/err.h>
-
-/* Convert a structured DN from an X.509 certificate into an LDAPV3 DN.
- * x509_name must be an (X509_NAME *). If func is non-NULL, the
- * constructed DN will use numeric OIDs to identify attributeTypes,
- * and the func() will be invoked to rewrite the DN with the given
- * flags.
- *
- * Otherwise the DN will use shortNames as defined in the OpenSSL
- * library.
- *
- * It's preferable to let slapd do the OID to attributeType mapping,
- * because the OpenSSL tables are known to have many typos in versions
- * up to (at least) 0.9.6c. However, the LDAP client has no schema tables,
- * so we're forced to use OpenSSL's mapping there.
- *  -- Howard Chu 2002-04-18
- */
-
-int
-ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func,
-	unsigned flags )
-{
-	LDAPDN	newDN;
-	LDAPRDN	newRDN;
-	LDAPAVA *newAVA, *baseAVA;
-	X509_NAME_ENTRY *ne;
-	ASN1_OBJECT *obj;
-	ASN1_STRING *str;
-	char oids[8192], *oidptr = oids, *oidbuf = NULL;
-	void *ptrs[2048];
-	int i, j, k = 0, navas, nrdns, rc = LDAP_SUCCESS;
-	int set = -1;
-	size_t dnsize, oidrem = sizeof(oids), oidsize = 0;
-	int csize;
-
-	struct berval	Val;
-
-	assert( bv != NULL );
-	bv->bv_len = 0;
-	bv->bv_val = NULL;
-
-	/* Get the number of AVAs. This is not necessarily the same as
-	 * the number of RDNs.
-	 */
-	navas = X509_NAME_entry_count( x509_name );
-
-	/* Get the last element, to see how many RDNs there are */
-	ne = X509_NAME_get_entry( x509_name, navas - 1 );
-	nrdns = ne->set + 1;
-
-	/* Allocate the DN/RDN/AVA stuff as a single block */    
-	dnsize = sizeof(LDAPRDN) * (nrdns+1);
-	dnsize += sizeof(LDAPAVA *) * (navas+nrdns);
-	dnsize += sizeof(LDAPAVA) * navas;
-	if (dnsize > sizeof(ptrs)) {
-		newDN = (LDAPDN)LDAP_MALLOC( dnsize );
-		if ( newDN == NULL )
-			return LDAP_NO_MEMORY;
-	} else {
-		newDN = (LDAPDN)ptrs;
-	}
-	
-	newDN[nrdns] = NULL;
-	newRDN = (LDAPRDN)(newDN + nrdns+1);
-	newAVA = (LDAPAVA *)(newRDN + navas + nrdns);
-	baseAVA = newAVA;
-
-	/* Retrieve RDNs in reverse order; LDAP is backwards from X.500. */
-	for ( i = nrdns - 1, j = 0; i >= 0; i-- ) {
-		ne = X509_NAME_get_entry( x509_name, i );
-		obj = X509_NAME_ENTRY_get_object( ne );
-		str = X509_NAME_ENTRY_get_data( ne );
-
-		/* If set changed, move to next RDN */
-		if ( set != ne->set ) {
-			/* If this is not the first time, end the
-			 * previous RDN and advance.
-			 */
-			if ( j > 0 ) {
-				newRDN[k] = NULL;
-				newRDN += k+1;
-			}
-			newDN[j++] = newRDN;
-
-			k = 0;
-			set = ne->set;
-		}
-		newAVA->la_private = NULL;
-		newAVA->la_flags = LDAP_AVA_STRING;
-
-		if ( !func ) {
-			int n = OBJ_obj2nid( obj );
-
-			if (n == NID_undef)
-				goto get_oid;
-			newAVA->la_attr.bv_val = (char *)OBJ_nid2sn( n );
-			newAVA->la_attr.bv_len = strlen( newAVA->la_attr.bv_val );
-#ifdef HAVE_EBCDIC
-			newAVA->la_attr.bv_val = LDAP_STRDUP( newAVA->la_attr.bv_val );
-			__etoa( newAVA->la_attr.bv_val );
-			newAVA->la_flags |= LDAP_AVA_FREE_ATTR;
-#endif
-		} else {
-get_oid:		newAVA->la_attr.bv_val = oidptr;
-			newAVA->la_attr.bv_len = OBJ_obj2txt( oidptr, oidrem, obj, 1 );
-#ifdef HAVE_EBCDIC
-			__etoa( newAVA->la_attr.bv_val );
-#endif
-			oidptr += newAVA->la_attr.bv_len + 1;
-			oidrem -= newAVA->la_attr.bv_len + 1;
-
-			/* Running out of OID buffer space? */
-			if (oidrem < 128) {
-				if ( oidsize == 0 ) {
-					oidsize = sizeof(oids) * 2;
-					oidrem = oidsize;
-					oidbuf = LDAP_MALLOC( oidsize );
-					if ( oidbuf == NULL ) goto nomem;
-					oidptr = oidbuf;
-				} else {
-					char *old = oidbuf;
-					oidbuf = LDAP_REALLOC( oidbuf, oidsize*2 );
-					if ( oidbuf == NULL ) goto nomem;
-					/* Buffer moved! Fix AVA pointers */
-					if ( old != oidbuf ) {
-						LDAPAVA *a;
-						long dif = oidbuf - old;
-
-						for (a=baseAVA; a<=newAVA; a++){
-							if (a->la_attr.bv_val >= old &&
-								a->la_attr.bv_val <= (old + oidsize))
-								a->la_attr.bv_val += dif;
-						}
-					}
-					oidptr = oidbuf + oidsize - oidrem;
-					oidrem += oidsize;
-					oidsize *= 2;
-				}
-			}
-		}
-		Val.bv_val = (char *) str->data;
-		Val.bv_len = str->length;
-		switch( str->type ) {
-		case V_ASN1_UNIVERSALSTRING:
-			/* This uses 32-bit ISO 10646-1 */
-			csize = 4; goto to_utf8;
-		case V_ASN1_BMPSTRING:
-			/* This uses 16-bit ISO 10646-1 */
-			csize = 2; goto to_utf8;
-		case V_ASN1_T61STRING:
-			/* This uses 8-bit, assume ISO 8859-1 */
-			csize = 1;
-to_utf8:		rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value );
-			newAVA->la_flags |= LDAP_AVA_FREE_VALUE;
-			if (rc != LDAP_SUCCESS) goto nomem;
-			newAVA->la_flags = LDAP_AVA_NONPRINTABLE;
-			break;
-		case V_ASN1_UTF8STRING:
-			newAVA->la_flags = LDAP_AVA_NONPRINTABLE;
-			/* This is already in UTF-8 encoding */
-		case V_ASN1_IA5STRING:
-		case V_ASN1_PRINTABLESTRING:
-			/* These are always 7-bit strings */
-			newAVA->la_value = Val;
-		default:
-			;
-		}
-		newRDN[k] = newAVA;
-		newAVA++;
-		k++;
-	}
-	newRDN[k] = NULL;
-
-	if ( func ) {
-		rc = func( newDN, flags, NULL );
-		if ( rc != LDAP_SUCCESS )
-			goto nomem;
-	}
-
-	rc = ldap_dn2bv_x( newDN, bv, LDAP_DN_FORMAT_LDAPV3, NULL );
-
-nomem:
-	for (;baseAVA < newAVA; baseAVA++) {
-		if (baseAVA->la_flags & LDAP_AVA_FREE_ATTR)
-			LDAP_FREE( baseAVA->la_attr.bv_val );
-		if (baseAVA->la_flags & LDAP_AVA_FREE_VALUE)
-			LDAP_FREE( baseAVA->la_value.bv_val );
-	}
-
-	if ( oidsize != 0 )
-		LDAP_FREE( oidbuf );
-	if ( newDN != (LDAPDN) ptrs )
-		LDAP_FREE( newDN );
-	return rc;
-}
-#endif /* HAVE_TLS */
-

Modified: openldap/trunk/libraries/libldap/getentry.c
===================================================================
--- openldap/trunk/libraries/libldap/getentry.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/getentry.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/getentry.c,v 1.26.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/getentry.c,v 1.28.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/getvalues.c
===================================================================
--- openldap/trunk/libraries/libldap/getvalues.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/getvalues.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/getvalues.c,v 1.24.2.3 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/getvalues.c,v 1.26.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Deleted: openldap/trunk/libraries/libldap/groupings.c
===================================================================
--- openldap/trunk/libraries/libldap/groupings.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/groupings.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,144 +0,0 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/groupings.c,v 1.4.2.4 2007/01/02 21:43:48 kurt Exp $ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2004-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This program was orignally developed by Kurt D. Zeilenga for inclusion in
- * OpenLDAP Software.
- */
-
-#include "portable.h"
-
-#include <ac/stdlib.h>
-
-#include <ac/time.h>
-#include <ac/string.h>
-
-#include "ldap-int.h"
-
-#ifdef LDAP_EXOP_GROUPING_CREATE
-
-int ldap_grouping_create(
-	LDAP *ld,
-	LDAP_CONST char *grpoid,
-	struct berval *grpdata,
-	LDAPControl **sctrls,
-	LDAPControl **cctrls,
-	int *msgidp )
-{
-	int rc;
-	BerElement *ber = NULL;
-	struct berval bv = BER_BVNULL;
-
-	Debug( LDAP_DEBUG_TRACE, "ldap_grouping_create\n", 0, 0, 0 );
-
-	assert( ld != NULL );
-	assert( LDAP_VALID( ld ) );
-	assert( grpoid != NULL || *grpoid == '\0' );
-	assert( msgidp != NULL );
-
-	/* build the create grouping exop */
-	ber = ber_alloc_t( LBER_USE_DER );
-	if( ber == NULL ) {
-		ld->ld_errno = LDAP_NO_MEMORY;
-		return( ld->ld_errno );
-	}
-
-	if ( grpdata != NULL ) {
-		ber_printf( ber, "{sON}", grpoid, grpdata );
-	} else {
-		ber_printf( ber, "{sN}", grpoid );
-	}
-
-	rc = ber_flatten2( ber, &bv, 0 );
-	if( rc < 0 ) {
-		ld->ld_errno = LDAP_ENCODING_ERROR;
-		return( ld->ld_errno );
-	}
-
-	rc = ldap_extended_operation( ld, LDAP_EXOP_GROUPING_CREATE,
-		&bv, sctrls, cctrls, msgidp );
-
-	ber_free( ber, 1 );
-	return rc;
-}
-
-int ldap_grouping_create_s(
-	LDAP *ld,
-	LDAP_CONST char *grpoid,
-	struct berval *grpdata,
-	LDAPControl **sctrls,
-	LDAPControl **cctrls,
-	struct berval **retgrpcookiep,
-	struct berval **retgrpdatap )
-{
-    int     rc;
-    int     msgid;
-    LDAPMessage *res;
-
-	Debug( LDAP_DEBUG_TRACE, "ldap_grouping_create_s\n", 0, 0, 0 );
-
-	assert( ld != NULL );
-	assert( LDAP_VALID( ld ) );
-	assert( grpoid != NULL || *grpoid == '\0' );
-
-    rc = ldap_grouping_create( ld, grpoid, grpdata,
-		sctrls, cctrls, &msgid );
-    if ( rc != LDAP_SUCCESS ) {
-        return rc;
-	}
- 
-    if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) {
-        return ld->ld_errno;
-	}
-
-	if ( retgrpcookiep != NULL ) *retgrpcookiep = NULL;
-	if ( retgrpdatap != NULL ) *retgrpdatap = NULL;
-
-#if 0
-	rc = ldap_parse_extended_result( ld, res, retoidp, retdatap, 0 );
-#else
-	rc = LDAP_NOT_SUPPORTED;
-#endif
-
-	if( rc != LDAP_SUCCESS ) {
-		ldap_msgfree( res );
-		return rc;
-	}
-
-    return( ldap_result2error( ld, res, 1 ) );
-}
-
-int ldap_grouping_end(
-	LDAP *ld,
-	LDAP_CONST char *grpoid,
-	struct berval *grpdata,
-	LDAPControl **sctrls,
-	LDAPControl **cctrls,
-	int *msgidp )
-{
-	return 0;
-}
-
-int ldap_grouping_end_s(
-	LDAP *ld,
-	LDAP_CONST char *grpoid,
-	struct berval *grpdata,
-	LDAPControl **sctrls,
-	LDAPControl **cctrls,
-	struct berval **retgrpdatap )
-{
-	return 0;
-}
-
-#endif

Modified: openldap/trunk/libraries/libldap/init.c
===================================================================
--- openldap/trunk/libraries/libldap/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/init.c,v 1.93.2.12 2007/01/02 21:43:48 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/init.c,v 1.102.2.4 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -29,6 +29,7 @@
 
 #include "ldap-int.h"
 #include "ldap_defaults.h"
+#include "lutil.h"
 
 struct ldapoptions ldap_int_global_options =
 	{ LDAP_UNINITIALIZED, LDAP_DEBUG_NONE };  
@@ -43,6 +44,9 @@
 #define ATTR_SASL	6
 #define ATTR_TLS	7
 
+#define ATTR_OPT_TV	8
+#define ATTR_OPT_INT	9
+
 struct ol_keyvalue {
 	const char *		key;
 	int			value;
@@ -63,6 +67,9 @@
 	const void *	data;
 	size_t		offset;
 } attrs[] = {
+	{0, ATTR_OPT_TV,	"TIMEOUT",		NULL,	LDAP_OPT_TIMEOUT},
+	{0, ATTR_OPT_TV,	"NETWORK_TIMEOUT",	NULL,	LDAP_OPT_NETWORK_TIMEOUT},
+	{0, ATTR_OPT_INT,	"VERSION",		NULL,	LDAP_OPT_PROTOCOL_VERSION},
 	{0, ATTR_KV,		"DEREF",	deref_kv, /* or &deref_kv[0] */
 		offsetof(struct ldapoptions, ldo_deref)},
 	{0, ATTR_INT,		"SIZELIMIT",	NULL,
@@ -78,12 +85,15 @@
 	{0, ATTR_OPTION,	"HOST",			NULL,	LDAP_OPT_HOST_NAME}, /* deprecated */
 	{0, ATTR_OPTION,	"URI",			NULL,	LDAP_OPT_URI}, /* replaces HOST/PORT */
 	{0, ATTR_BOOL,		"REFERRALS",	NULL,	LDAP_BOOL_REFERRALS},
+#if 0
+	/* This should only be allowed via ldap_set_option(3) */
 	{0, ATTR_BOOL,		"RESTART",		NULL,	LDAP_BOOL_RESTART},
+#endif
 
 #ifdef HAVE_CYRUS_SASL
-	{1, ATTR_STRING,	"SASL_MECH",		NULL,
+	{0, ATTR_STRING,	"SASL_MECH",		NULL,
 		offsetof(struct ldapoptions, ldo_def_sasl_mech)},
-	{1, ATTR_STRING,	"SASL_REALM",		NULL,
+	{0, ATTR_STRING,	"SASL_REALM",		NULL,
 		offsetof(struct ldapoptions, ldo_def_sasl_realm)},
 	{1, ATTR_STRING,	"SASL_AUTHCID",		NULL,
 		offsetof(struct ldapoptions, ldo_def_sasl_authcid)},
@@ -104,6 +114,9 @@
 #ifdef HAVE_OPENSSL_CRL
 	{0, ATTR_TLS,	"TLS_CRLCHECK",		NULL,	LDAP_OPT_X_TLS_CRLCHECK},
 #endif
+#ifdef HAVE_GNUTLS
+	{0, ATTR_TLS,	"TLS_CRL",			NULL,	LDAP_OPT_X_TLS_CRLFILE},
+#endif
         
 #endif
 
@@ -203,10 +216,15 @@
 
 				break;
 
-			case ATTR_INT:
+			case ATTR_INT: {
+				char *next;
+				long l;
 				p = &((char *) gopts)[attrs[i].offset];
-				* (int*) p = atoi(opt);
-				break;
+				l = strtol( opt, &next, 10 );
+				if ( next != opt && next[ 0 ] == '\0' ) {
+					* (int*) p = l;
+				}
+				} break;
 
 			case ATTR_KV: {
 					const struct ol_keyvalue *kv;
@@ -241,6 +259,24 @@
 			   	ldap_int_tls_config( NULL, attrs[i].offset, opt );
 #endif
 				break;
+			case ATTR_OPT_TV: {
+				struct timeval tv;
+				char *next;
+				tv.tv_usec = 0;
+				tv.tv_sec = strtol( opt, &next, 10 );
+				if ( next != opt && next[ 0 ] == '\0' && tv.tv_sec > 0 ) {
+					(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&tv );
+				}
+				} break;
+			case ATTR_OPT_INT: {
+				long l;
+				char *next;
+				l = strtol( opt, &next, 10 );
+				if ( next != opt && next[ 0 ] == '\0' && l > 0 && (long)((int)l) == l ) {
+					int v = (int)l;
+					(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&v );
+				}
+				} break;
 			}
 
 			break;
@@ -410,8 +446,7 @@
 	WSACleanup( );
 #endif
 
-#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
-	|| defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
+#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
 	if ( ldap_int_hostname ) {
 		LDAP_FREE( ldap_int_hostname );
 		ldap_int_hostname = NULL;
@@ -423,6 +458,9 @@
 		gopts->ldo_def_sasl_authcid = NULL;
 	}
 #endif
+#ifdef HAVE_TLS
+	ldap_int_tls_destroy( gopts );
+#endif
 }
 
 /* 
@@ -440,8 +478,8 @@
 	gopts->ldo_timelimit = LDAP_NO_LIMIT;
 	gopts->ldo_sizelimit = LDAP_NO_LIMIT;
 
-	gopts->ldo_tm_api = (struct timeval *)NULL;
-	gopts->ldo_tm_net = (struct timeval *)NULL;
+	gopts->ldo_tm_api.tv_sec = -1;
+	gopts->ldo_tm_net.tv_sec = -1;
 
 	/* ldo_defludp will be freed by the termination handler
 	 */
@@ -486,14 +524,14 @@
 #ifdef HAVE_TLS
 	gopts->ldo_tls_connect_cb = NULL;
 	gopts->ldo_tls_connect_arg = NULL;
+	gopts->ldo_tls_require_cert = LDAP_OPT_X_TLS_DEMAND;
 #endif
 
 	gopts->ldo_valid = LDAP_INITIALIZED;
    	return;
 }
 
-#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
-	|| defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
+#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
 char * ldap_int_hostname = NULL;
 #endif
 
@@ -541,8 +579,7 @@
 }
 #endif
 
-#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
-	|| defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
+#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
 	{
 		char	*name = ldap_int_hostname;
 

Deleted: openldap/trunk/libraries/libldap/kbind.c
===================================================================
--- openldap/trunk/libraries/libldap/kbind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/kbind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,294 +0,0 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/kbind.c,v 1.37.2.4 2007/01/02 21:43:49 kurt Exp $ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2007 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* Portions Copyright (c) 1993 Regents of the University of Michigan.
- * All rights reserved.
- */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
-
-/*
- *	BindRequest ::= SEQUENCE {
- *		version		INTEGER,
- *		name		DistinguishedName,	 -- who
- *		authentication	CHOICE {
- *			simple		[0] OCTET STRING -- passwd
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
- *			krbv42ldap	[1] OCTET STRING
- *			krbv42dsa	[2] OCTET STRING
-#endif
- *			sasl		[3] SaslCredentials	-- LDAPv3
- *		}
- *	}
- *
- *	BindResponse ::= SEQUENCE {
- *		COMPONENTS OF LDAPResult,
- *		serverSaslCreds		OCTET STRING OPTIONAL -- LDAPv3
- *	}
- *
- */
-
-#include "portable.h"
-
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-
-#include <stdio.h>
-#include <ac/stdlib.h>
-
-#include <ac/krb.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#include "ldap-int.h"
-
-/*
- * ldap_kerberos_bind1 - initiate a bind to the ldap server using
- * kerberos authentication.  The dn is supplied.  It is assumed the user
- * already has a valid ticket granting ticket.  The msgid of the
- * request is returned on success (suitable for passing to ldap_result()),
- * -1 is returned if there's trouble.
- *
- * Example:
- *	ldap_kerberos_bind1( ld, "cn=manager, o=university of michigan, c=us" )
- */
-int
-ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
-{
-	BerElement	*ber;
-	char		*cred;
-	int		rc;
-	ber_len_t credlen;
-	ber_int_t	id;
-
-	Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1\n", 0, 0, 0 );
-
-	if( ld->ld_version > LDAP_VERSION2 ) {
-		ld->ld_errno = LDAP_NOT_SUPPORTED;
-		return -1;
-	}
-
-	if ( dn == NULL )
-		dn = "";
-
-	if ( (cred = ldap_get_kerberosv4_credentials( ld, dn, "ldapserver",
-	    &credlen )) == NULL ) {
-		return( -1 );	/* ld_errno should already be set */
-	}
-
-	/* create a message to send */
-	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
-		LDAP_FREE( cred );
-		return( -1 );
-	}
-
-	LDAP_NEXT_MSGID( ld, id );
-	/* fill it in */
-	rc = ber_printf( ber, "{it{istoN}N}", id, LDAP_REQ_BIND,
-	    ld->ld_version, dn, LDAP_AUTH_KRBV41, cred, credlen );
-
-	if ( rc == -1 ) {
-		LDAP_FREE( cred );
-		ber_free( ber, 1 );
-		ld->ld_errno = LDAP_ENCODING_ERROR;
-		return( -1 );
-	}
-
-	LDAP_FREE( cred );
-
-
-	/* send the message */
-	return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id ));
-}
-
-int
-ldap_kerberos_bind1_s( LDAP *ld, LDAP_CONST char *dn )
-{
-	int		msgid;
-	LDAPMessage	*res;
-
-	Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1_s\n", 0, 0, 0 );
-
-	/* initiate the bind */
-	if ( (msgid = ldap_kerberos_bind1( ld, dn )) == -1 )
-		return( ld->ld_errno );
-
-	/* wait for a result */
-	if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &res )
-	    == -1 ) {
-		return( ld->ld_errno );	/* ldap_result sets ld_errno */
-	}
-
-	return( ldap_result2error( ld, res, 1 ) );
-}
-
-/*
- * ldap_kerberos_bind2 - initiate a bind to the X.500 server using
- * kerberos authentication.  The dn is supplied.  It is assumed the user
- * already has a valid ticket granting ticket.  The msgid of the
- * request is returned on success (suitable for passing to ldap_result()),
- * -1 is returned if there's trouble.
- *
- * Example:
- *	ldap_kerberos_bind2( ld, "cn=manager, o=university of michigan, c=us" )
- */
-int
-ldap_kerberos_bind2( LDAP *ld, LDAP_CONST char *dn )
-{
-	BerElement	*ber;
-	char		*cred;
-	int		rc;
-	ber_len_t credlen;
-	ber_int_t id;
-
-	Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind2\n", 0, 0, 0 );
-
-	if( ld->ld_version > LDAP_VERSION2 ) {
-		ld->ld_errno = LDAP_NOT_SUPPORTED;
-		return -1;
-	}
-
-	if ( dn == NULL )
-		dn = "";
-
-	if ( (cred = ldap_get_kerberosv4_credentials( ld, dn, "x500dsa", &credlen ))
-	    == NULL ) {
-		return( -1 );	/* ld_errno should already be set */
-	}
-
-	/* create a message to send */
-	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
-		LDAP_FREE( cred );
-		return( -1 );
-	}
-
-	LDAP_NEXT_MSGID( ld, id );
-	/* fill it in */
-	rc = ber_printf( ber, "{it{istoN}N}", id, LDAP_REQ_BIND,
-	    ld->ld_version, dn, LDAP_AUTH_KRBV42, cred, credlen );
-
-	LDAP_FREE( cred );
-
-	if ( rc == -1 ) {
-		ber_free( ber, 1 );
-		ld->ld_errno = LDAP_ENCODING_ERROR;
-		return( -1 );
-	}
-
-	/* send the message */
-	return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id ));
-}
-
-/* synchronous bind to DSA using kerberos */
-int
-ldap_kerberos_bind2_s( LDAP *ld, LDAP_CONST char *dn )
-{
-	int		msgid;
-	LDAPMessage	*res;
-
-	Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind2_s\n", 0, 0, 0 );
-
-	/* initiate the bind */
-	if ( (msgid = ldap_kerberos_bind2( ld, dn )) == -1 )
-		return( ld->ld_errno );
-
-	/* wait for a result */
-	if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &res )
-	    == -1 ) {
-		return( ld->ld_errno );	/* ldap_result sets ld_errno */
-	}
-
-	return( ldap_result2error( ld, res, 1 ) );
-}
-
-/* synchronous bind to ldap and DSA using kerberos */
-int
-ldap_kerberos_bind_s( LDAP *ld, LDAP_CONST char *dn )
-{
-	int	err;
-
-	Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind_s\n", 0, 0, 0 );
-
-	if ( (err = ldap_kerberos_bind1_s( ld, dn )) != LDAP_SUCCESS )
-		return( err );
-
-	return( ldap_kerberos_bind2_s( ld, dn ) );
-}
-
-
-#ifndef AUTHMAN
-/*
- * ldap_get_kerberosv4_credentials - obtain kerberos v4 credentials for ldap.
- * The dn of the entry to which to bind is supplied.  It's assumed the
- * user already has a tgt.
- */
-
-char *
-ldap_get_kerberosv4_credentials(
-	LDAP *ld,
-	LDAP_CONST char *who,
-	LDAP_CONST char *service,
-	ber_len_t *len )
-{
-	KTEXT_ST	ktxt;
-	int		err;
-	char		realm[REALM_SZ], *cred, *krbinstance;
-
-	Debug( LDAP_DEBUG_TRACE, "ldap_get_kerberosv4_credentials\n", 0, 0, 0 );
-
-	if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) {
-		Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
-			"krb_get_tf_realm failed: %s\n", krb_err_txt[err], 0, 0 );
-		ld->ld_errno = LDAP_AUTH_UNKNOWN;
-		return( NULL );
-	}
-
-	err = 0;
-#ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
-#endif
-	if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
-		/* not connected yet */
-		err = ldap_open_defconn( ld );
-	}
-#ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
-#endif
-	if ( err < 0 ) return NULL;
-
-	krbinstance = ld->ld_defconn->lconn_krbinstance;
-
-	if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
-	    != KSUCCESS )
-	{
-		Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
-			"krb_mk_req failed (%s)\n", krb_err_txt[err], 0, 0 );
-		ld->ld_errno = LDAP_AUTH_UNKNOWN;
-		return( NULL );
-	}
-
-	if ( ( cred = LDAP_MALLOC( ktxt.length )) == NULL ) {
-		ld->ld_errno = LDAP_NO_MEMORY;
-		return( NULL );
-	}
-
-	*len = ktxt.length;
-	AC_MEMCPY( cred, ktxt.dat, ktxt.length );
-
-	return( cred );
-}
-
-#endif /* !AUTHMAN */
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */

Modified: openldap/trunk/libraries/libldap/ldap-int.h
===================================================================
--- openldap/trunk/libraries/libldap/ldap-int.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/ldap-int.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /*  ldap-int.h - defines & prototypes internal to the LDAP library */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/ldap-int.h,v 1.160.2.10 2007/04/23 12:28:20 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/ldap-int.h,v 1.168.2.6 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -42,6 +42,9 @@
 #define SASL_MIN_BUFF_SIZE	4096
 #endif
 
+/* for struct timeval */
+#include <ac/time.h>
+
 #undef TV2MILLISEC
 #define TV2MILLISEC(tv) (((tv)->tv_sec * 1000) + ((tv)->tv_usec/1000))
 
@@ -95,20 +98,20 @@
 LDAP_BEGIN_DECL
 
 #define LDAP_URL_PREFIX         "ldap://"
-#define LDAP_URL_PREFIX_LEN     (sizeof(LDAP_URL_PREFIX)-1)
-#define LDAPS_URL_PREFIX		"ldaps://"
-#define LDAPS_URL_PREFIX_LEN	(sizeof(LDAPS_URL_PREFIX)-1)
+#define LDAP_URL_PREFIX_LEN     STRLENOF(LDAP_URL_PREFIX)
+#define LDAPS_URL_PREFIX	"ldaps://"
+#define LDAPS_URL_PREFIX_LEN	STRLENOF(LDAPS_URL_PREFIX)
 #define LDAPI_URL_PREFIX	"ldapi://"
-#define LDAPI_URL_PREFIX_LEN	(sizeof(LDAPI_URL_PREFIX)-1)
+#define LDAPI_URL_PREFIX_LEN	STRLENOF(LDAPI_URL_PREFIX)
 #ifdef LDAP_CONNECTIONLESS
 #define LDAPC_URL_PREFIX	"cldap://"
-#define LDAPC_URL_PREFIX_LEN	(sizeof(LDAPC_URL_PREFIX)-1)
+#define LDAPC_URL_PREFIX_LEN	STRLENOF(LDAPC_URL_PREFIX)
 #endif
-#define LDAP_URL_URLCOLON		"URL:"
-#define LDAP_URL_URLCOLON_LEN	(sizeof(LDAP_URL_URLCOLON)-1)
+#define LDAP_URL_URLCOLON	"URL:"
+#define LDAP_URL_URLCOLON_LEN	STRLENOF(LDAP_URL_URLCOLON)
 
 #define LDAP_REF_STR		"Referral:\n"
-#define LDAP_REF_STR_LEN	(sizeof(LDAP_REF_STR)-1)
+#define LDAP_REF_STR_LEN	STRLENOF(LDAP_REF_STR)
 #define LDAP_LDAP_REF_STR	LDAP_URL_PREFIX
 #define LDAP_LDAP_REF_STR_LEN	LDAP_URL_PREFIX_LEN
 
@@ -117,6 +120,7 @@
 #define LDAP_BOOL_REFERRALS		0
 #define LDAP_BOOL_RESTART		1
 #define LDAP_BOOL_TLS			3
+#define	LDAP_BOOL_CONNECT_ASYNC		4
 
 #define LDAP_BOOLEANS	unsigned long
 #define LDAP_BOOL(n)	((LDAP_BOOLEANS)1 << (n))
@@ -142,6 +146,20 @@
 	time_t	lm_time;	/* used to maintain cache */
 };
 
+#ifdef HAVE_TLS
+struct ldaptls {
+	char		*lt_certfile;
+	char		*lt_keyfile;
+	char		*lt_dhfile;
+	char		*lt_cacertfile;
+	char		*lt_cacertdir;
+	char		*lt_ciphersuite;
+#ifdef HAVE_GNUTLS
+	char		*lt_crlfile;
+#endif
+};
+#endif
+
 /*
  * structure representing get/set'able options
  * which have global defaults.
@@ -161,8 +179,8 @@
 #endif
 
 	/* per API call timeout */
-	struct timeval		*ldo_tm_api;
-	struct timeval		*ldo_tm_net;
+	struct timeval		ldo_tm_api;
+	struct timeval		ldo_tm_net;
 
 	ber_int_t		ldo_version;
 	ber_int_t		ldo_deref;
@@ -172,10 +190,22 @@
 #ifdef HAVE_TLS
    	/* tls context */
    	void		*ldo_tls_ctx;
-   	int			ldo_tls_mode;
 	LDAP_TLS_CONNECT_CB	*ldo_tls_connect_cb;
 	void*			ldo_tls_connect_arg;
+	struct ldaptls ldo_tls_info;
+#define ldo_tls_certfile	ldo_tls_info.lt_certfile
+#define ldo_tls_keyfile	ldo_tls_info.lt_keyfile
+#define ldo_tls_dhfile	ldo_tls_info.lt_dhfile
+#define ldo_tls_cacertfile	ldo_tls_info.lt_cacertfile
+#define ldo_tls_cacertdir	ldo_tls_info.lt_cacertdir
+#define ldo_tls_ciphersuite	ldo_tls_info.lt_ciphersuite
+#define ldo_tls_crlfile	ldo_tls_info.lt_crlfile
+   	int			ldo_tls_mode;
+   	int			ldo_tls_require_cert;
+#ifdef HAVE_OPENSSL_CRL
+   	int			ldo_tls_crlcheck;
 #endif
+#endif
 
 	LDAPURLDesc *ldo_defludp;
 	int		ldo_defport;
@@ -203,6 +233,8 @@
 	void *ldo_rebind_params;
 	LDAP_NEXTREF_PROC *ldo_nextref_proc;
 	void *ldo_nextref_params;
+	LDAP_URLLIST_PROC *ldo_urllist_proc;
+	void *ldo_urllist_params;
 
 	LDAP_BOOLEANS ldo_booleans;	/* boolean options */
 };
@@ -218,6 +250,7 @@
 	void		*lconn_sasl_sockctx;	/* for security layer */
 #endif
 	int			lconn_refcnt;
+	time_t		lconn_created;	/* time */
 	time_t		lconn_lastused;	/* time */
 	int			lconn_rebind_inprogress;	/* set if rebind in progress */
 	char		***lconn_rebind_queue;		/* used if rebind in progress */
@@ -226,9 +259,6 @@
 #define LDAP_CONNST_CONNECTING		2
 #define LDAP_CONNST_CONNECTED		3
 	LDAPURLDesc		*lconn_server;
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-	char			*lconn_krbinstance;
-#endif
 	BerElement		*lconn_ber;	/* ber receiving on this conn. */
 
 	struct ldap_conn *lconn_next;
@@ -239,23 +269,25 @@
  * structure used to track outstanding requests
  */
 typedef struct ldapreq {
-	ber_int_t		lr_msgid;	/* the message id */
+	ber_int_t	lr_msgid;	/* the message id */
 	int		lr_status;	/* status of request */
 #define LDAP_REQST_COMPLETED	0
 #define LDAP_REQST_INPROGRESS	1
 #define LDAP_REQST_CHASINGREFS	2
 #define LDAP_REQST_NOTCONNECTED	3
 #define LDAP_REQST_WRITING	4
+	int		lr_refcnt;	/* count of references */
 	int		lr_outrefcnt;	/* count of outstanding referrals */
-	ber_int_t		lr_origid;	/* original request's message id */
+	int		lr_abandoned;	/* the request has been abandoned */
+	ber_int_t	lr_origid;	/* original request's message id */
 	int		lr_parentcnt;	/* count of parent requests */
-	ber_tag_t		lr_res_msgtype;	/* result message type */
-	ber_int_t		lr_res_errno;	/* result LDAP errno */
+	ber_tag_t	lr_res_msgtype;	/* result message type */
+	ber_int_t	lr_res_errno;	/* result LDAP errno */
 	char		*lr_res_error;	/* result error string */
 	char		*lr_res_matched;/* result matched DN string */
 	BerElement	*lr_ber;	/* ber encoded request contents */
 	LDAPConn	*lr_conn;	/* connection used to send request */
-	struct berval	lr_dn;	/* DN of request, in lr_ber */
+	struct berval	lr_dn;		/* DN of request, in lr_ber */
 	struct ldapreq	*lr_parent;	/* request that spawned this referral */
 	struct ldapreq	*lr_child;	/* first child request */
 	struct ldapreq	*lr_refnext;	/* next referral spawned */
@@ -317,6 +349,8 @@
 #define ld_rebind_params	ld_options.ldo_rebind_params
 #define ld_nextref_proc		ld_options.ldo_nextref_proc
 #define ld_nextref_params	ld_options.ldo_nextref_params
+#define ld_urllist_proc		ld_options.ldo_urllist_proc
+#define ld_urllist_params	ld_options.ldo_urllist_params
 
 #define ld_version		ld_options.ldo_version
 
@@ -338,7 +372,8 @@
 	ldap_pvt_thread_mutex_t	ld_res_mutex;
 #endif
 
-	ber_int_t		*ld_abandoned;	/* array of abandoned requests */
+	ber_len_t	ld_nabandoned;
+	ber_int_t	*ld_abandoned;	/* array of abandoned requests */
 
 	LDAPCache	*ld_cache;	/* non-null if cache is initialized */
 
@@ -370,6 +405,17 @@
 #endif
 
 /*
+ * in abandon.c
+ */
+
+LDAP_F (int)
+ldap_int_bisect_find( ber_int_t *v, ber_len_t n, ber_int_t id, int *idxp );
+LDAP_F (int)
+ldap_int_bisect_insert( ber_int_t **vp, ber_len_t *np, int id, int idx );
+LDAP_F (int)
+ldap_int_bisect_delete( ber_int_t **vp, ber_len_t *np, int id, int idx );
+
+/*
  * in init.c
  */
 
@@ -438,19 +484,7 @@
  */
 LDAP_F (int) ldap_int_next_line_tokens LDAP_P(( char **bufp, ber_len_t *blenp, char ***toksp ));
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-/*
- * in kerberos.c
- */
-LDAP_F (char *) ldap_get_kerberosv4_credentials LDAP_P((
-	LDAP *ld,
-	LDAP_CONST char *who,
-	LDAP_CONST char *service,
-	ber_len_t *len ));
 
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
-
-
 /*
  * in open.c
  */
@@ -470,9 +504,10 @@
 	const struct timeval *tm );
 LDAP_F (int) ldap_connect_to_host( LDAP *ld, Sockbuf *sb,
 	int proto, const char *host, int port, int async );
+LDAP_F (int) ldap_int_poll( LDAP *ld, ber_socket_t s,
+	struct timeval *tvp );
 
-#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) || \
-	defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
+#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
 LDAP_V (char *) ldap_int_hostname;
 LDAP_F (char *) ldap_host_connected_to( Sockbuf *sb,
 	const char *host );
@@ -503,9 +538,10 @@
 LDAP_F (BerElement *) ldap_alloc_ber_with_options( LDAP *ld );
 LDAP_F (void) ldap_set_ber_options( LDAP *ld, BerElement *ber );
 
-LDAP_F (int) ldap_send_server_request( LDAP *ld, BerElement *ber, ber_int_t msgid, LDAPRequest *parentreq, LDAPURLDesc *srvlist, LDAPConn *lc, LDAPreqinfo *bind );
-LDAP_F (LDAPConn *) ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, int connect, LDAPreqinfo *bind );
+LDAP_F (int) ldap_send_server_request( LDAP *ld, BerElement *ber, ber_int_t msgid, LDAPRequest *parentreq, LDAPURLDesc **srvlist, LDAPConn *lc, LDAPreqinfo *bind );
+LDAP_F (LDAPConn *) ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb, int connect, LDAPreqinfo *bind );
 LDAP_F (LDAPRequest *) ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid );
+LDAP_F (void) ldap_return_request( LDAP *ld, LDAPRequest *lr, int freeit );
 LDAP_F (void) ldap_free_request( LDAP *ld, LDAPRequest *lr );
 LDAP_F (void) ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind );
 LDAP_F (void) ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all );
@@ -520,7 +556,7 @@
 /*
  * in result.c:
  */
-LDAP_F (char *) ldap_int_msgtype2str( ber_tag_t tag );
+LDAP_F (const char *) ldap_int_msgtype2str( ber_tag_t tag );
 
 /*
  * in search.c
@@ -563,15 +599,6 @@
 LDAP_F (LDAPURLDesc *) ldap_url_duplist LDAP_P((
 	LDAPURLDesc *ludlist ));
 
-LDAP_F (int) ldap_url_parselist LDAP_P((
-	LDAPURLDesc **ludlist,
-	const char *url ));
-
-LDAP_F (int) ldap_url_parselist_ext LDAP_P((
-	LDAPURLDesc **ludlist,
-	const char *url,
-	const char *sep	));
-
 LDAP_F (int) ldap_url_parsehosts LDAP_P((
 	LDAPURLDesc **ludlist,
 	const char *hosts,
@@ -580,12 +607,6 @@
 LDAP_F (char *) ldap_url_list2hosts LDAP_P((
 	LDAPURLDesc *ludlist ));
 
-LDAP_F (char *) ldap_url_list2urls LDAP_P((
-	LDAPURLDesc *ludlist ));
-
-LDAP_F (void) ldap_free_urllist LDAP_P((
-	LDAPURLDesc *ludlist ));
-
 /*
  * in cyrus.c
  */
@@ -634,6 +655,8 @@
 LDAP_F (int) ldap_int_tls_start LDAP_P(( LDAP *ld,
 	LDAPConn *conn, LDAPURLDesc *srv ));
 
+LDAP_F (void) ldap_int_tls_destroy LDAP_P(( struct ldapoptions *lo ));
+
 /*
  *	in getvalues.c
  */

Modified: openldap/trunk/libraries/libldap/ldap.conf
===================================================================
--- openldap/trunk/libraries/libldap/ldap.conf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/ldap.conf	2007-12-15 10:25:31 UTC (rev 892)
@@ -5,7 +5,7 @@
 # See ldap.conf(5) for details
 # This file should be world readable but not world writable.
 
-#BASE	dc=example, dc=com
+#BASE	dc=example,dc=com
 #URI	ldap://ldap.example.com ldap://ldap-master.example.com:666
 
 #SIZELIMIT	12

Copied: openldap/trunk/libraries/libldap/ldap_sync.c (from rev 891, openldap/vendor/openldap-2.4.7/libraries/libldap/ldap_sync.c)
===================================================================
--- openldap/trunk/libraries/libldap/ldap_sync.c	                        (rev 0)
+++ openldap/trunk/libraries/libldap/ldap_sync.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,902 @@
+/* $OpenLDAP: pkg/ldap/libraries/libldap/ldap_sync.c,v 1.2.2.2 2007/08/31 23:13:55 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2006-2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This program was originally developed by Pierangelo Masarati
+ * for inclusion in OpenLDAP Software.
+ */
+
+/*
+ * Proof-of-concept API that implement the client-side
+ * of the "LDAP Content Sync Operation" (RFC 4533)
+ */
+
+#include "portable.h"
+
+#include <ac/time.h>
+
+#include "ldap-int.h"
+
+#ifdef LDAP_SYNC_TRACE
+static const char *
+ldap_sync_state2str( int state )
+{
+	switch ( state ) {
+	case LDAP_SYNC_PRESENT:
+		return "LDAP_SYNC_PRESENT";
+
+	case LDAP_SYNC_ADD:
+		return "LDAP_SYNC_ADD";
+
+	case LDAP_SYNC_MODIFY:
+		return "LDAP_SYNC_MODIFY";
+
+	case LDAP_SYNC_DELETE:
+		return "LDAP_SYNC_DELETE";
+
+	default:
+		return "(unknown)";
+	}
+}
+#endif
+
+/*
+ * initialize the persistent search structure
+ */
+ldap_sync_t *
+ldap_sync_initialize( ldap_sync_t *ls_in )
+{
+	ldap_sync_t	*ls = ls_in;
+
+	if ( ls == NULL ) {
+		ls = ldap_memalloc( sizeof( ldap_sync_t ) );
+		if ( ls == NULL ) {
+			return NULL;
+		}
+
+	} else {
+		memset( ls, 0, sizeof( ldap_sync_t ) );
+	}
+
+	ls->ls_scope = LDAP_SCOPE_SUBTREE;
+	ls->ls_timeout = -1;
+
+	return ls;
+}
+
+/*
+ * destroy the persistent search structure
+ */
+void
+ldap_sync_destroy( ldap_sync_t *ls, int freeit )
+{
+	assert( ls != NULL );
+
+	if ( ls->ls_base != NULL ) {
+		ldap_memfree( ls->ls_base );
+		ls->ls_base = NULL;
+	}
+
+	if ( ls->ls_filter != NULL ) {
+		ldap_memfree( ls->ls_filter );
+		ls->ls_filter = NULL;
+	}
+
+	if ( ls->ls_attrs != NULL ) {
+		int	i;
+
+		for ( i = 0; ls->ls_attrs[ i ] != NULL; i++ ) {
+			ldap_memfree( ls->ls_attrs[ i ] );
+		}
+		ldap_memfree( ls->ls_attrs );
+		ls->ls_attrs = NULL;
+	}
+
+	if ( ls->ls_ld != NULL ) {
+		(void)ldap_unbind_ext( ls->ls_ld, NULL, NULL );
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr, "ldap_unbind_ext()\n" );
+#endif /* LDAP_SYNC_TRACE */
+		ls->ls_ld = NULL;
+	}
+
+	if ( ls->ls_cookie.bv_val != NULL ) {
+		ldap_memfree( ls->ls_cookie.bv_val );
+		ls->ls_cookie.bv_val = NULL;
+	}
+
+	if ( freeit ) {
+		ldap_memfree( ls );
+	}
+}
+
+/*
+ * handle the LDAP_RES_SEARCH_ENTRY response
+ */
+static int
+ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res )
+{
+	LDAPControl		**ctrls = NULL;
+	int			rc = LDAP_SUCCESS,
+				i;
+	BerElement		*ber = NULL;
+	struct berval		entryUUID = { 0 },
+				cookie = { 0 };
+	int			state = -1;
+	ber_len_t		len;
+	ldap_sync_refresh_t	phase = ls->ls_refreshPhase;
+
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr, "\tgot LDAP_RES_SEARCH_ENTRY\n" );
+#endif /* LDAP_SYNC_TRACE */
+
+	assert( ls != NULL );
+	assert( res != NULL );
+
+	/* OK */
+
+	/* extract:
+	 * - data
+	 * - entryUUID
+	 *
+	 * check that:
+	 * - Sync State Control is "add"
+	 */
+
+	/* the control MUST be present */
+
+	/* extract controls */
+	ldap_get_entry_controls( ls->ls_ld, res, &ctrls );
+	if ( ctrls == NULL ) {
+		rc = LDAP_OTHER;
+		goto done;
+	}
+
+	/* lookup the sync state control */
+	for ( i = 0; ctrls[ i ] != NULL; i++ ) {
+		if ( strcmp( ctrls[ i ]->ldctl_oid, LDAP_CONTROL_SYNC_STATE ) == 0 ) {
+			break;
+		}
+	}
+
+	/* control must be present; there might be other... */
+	if ( ctrls[ i ] == NULL ) {
+		rc = LDAP_OTHER;
+		goto done;
+	}
+
+	/* extract data */
+	ber = ber_init( &ctrls[ i ]->ldctl_value );
+	/* scan entryUUID in-place ("m") */
+	ber_scanf( ber, "{em" /*"}"*/, &state, &entryUUID );
+	if ( entryUUID.bv_len == 0 ) {
+		rc = LDAP_OTHER;
+		goto done;
+	}
+
+	if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
+		/* scan cookie in-place ("m") */
+		ber_scanf( ber, /*"{"*/ "m}", &cookie );
+		if ( cookie.bv_val != NULL ) {
+			ber_bvreplace( &ls->ls_cookie, &cookie );
+		}
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr, "\t\tgot cookie=%s\n",
+			cookie.bv_val ? cookie.bv_val : "(null)" );
+#endif /* LDAP_SYNC_TRACE */
+	}
+
+	switch ( state ) {
+	case LDAP_SYNC_PRESENT:
+	case LDAP_SYNC_DELETE:
+	case LDAP_SYNC_ADD:
+	case LDAP_SYNC_MODIFY:
+		/* NOTE: ldap_sync_refresh_t is defined
+		 * as the corresponding LDAP_SYNC_*
+		 * for the 4 above cases */
+		phase = state;
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr, "\t\tgot syncState=%s\n", ldap_sync_state2str( state ) );
+#endif /* LDAP_SYNC_TRACE */
+		break;
+
+	default:
+		rc = LDAP_OTHER;
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr, "\t\tgot unknown syncState=%d\n", state );
+#endif /* LDAP_SYNC_TRACE */
+		goto done;
+	}
+
+	if ( ls->ls_search_entry ) {
+		rc = ls->ls_search_entry( ls, res, &entryUUID, phase );
+	}
+
+done:;
+	if ( ber != NULL ) {
+		ber_free( ber, 1 );
+	}
+
+	if ( ctrls != NULL ) {
+		ldap_controls_free( ctrls );
+	}
+
+	return rc;
+}
+
+/*
+ * handle the LDAP_RES_SEARCH_REFERENCE response
+ * (to be implemented yet)
+ */
+static int
+ldap_sync_search_reference( ldap_sync_t *ls, LDAPMessage *res )
+{
+	int		rc = 0;
+
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr, "\tgot LDAP_RES_SEARCH_REFERENCE\n" );
+#endif /* LDAP_SYNC_TRACE */
+
+	assert( ls != NULL );
+	assert( res != NULL );
+
+	if ( ls->ls_search_reference ) {
+		rc = ls->ls_search_reference( ls, res );
+	}
+
+	return rc;
+}
+
+/*
+ * handle the LDAP_RES_SEARCH_RESULT response
+ */
+static int
+ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res )
+{
+	int		err;
+	char		*matched = NULL,
+			*msg = NULL;
+	LDAPControl	**ctrls = NULL;
+	int		rc;
+	int		refreshDeletes = -1;
+
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr, "\tgot LDAP_RES_SEARCH_RESULT\n" );
+#endif /* LDAP_SYNC_TRACE */
+
+	assert( ls != NULL );
+	assert( res != NULL );
+
+	/* should not happen in refreshAndPersist... */
+	rc = ldap_parse_result( ls->ls_ld,
+		res, &err, &matched, &msg, NULL, &ctrls, 0 );
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr,
+		"\tldap_parse_result(%d, \"%s\", \"%s\") == %d\n",
+		err,
+		matched ? matched : "",
+		msg ? msg : "",
+		rc );
+#endif /* LDAP_SYNC_TRACE */
+	if ( rc == LDAP_SUCCESS ) {
+		rc = err;
+	}
+
+	ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE;
+
+	switch ( rc ) {
+	case LDAP_SUCCESS: {
+		int		i;
+		BerElement	*ber = NULL;
+		ber_len_t	len;
+		struct berval	cookie = { 0 };
+
+		/* deal with control; then fallthru to handler */
+		if ( ctrls == NULL ) {
+			rc = LDAP_OTHER;
+			goto done;
+		}
+
+		/* lookup the sync state control */
+		for ( i = 0; ctrls[ i ] != NULL; i++ ) {
+			if ( strcmp( ctrls[ i ]->ldctl_oid,
+				LDAP_CONTROL_SYNC_DONE ) == 0 )
+			{
+				break;
+			}
+		}
+
+		/* control must be present; there might be other... */
+		if ( ctrls[ i ] == NULL ) {
+			rc = LDAP_OTHER;
+			goto done;
+		}
+
+		/* extract data */
+		ber = ber_init( &ctrls[ i ]->ldctl_value );
+
+		ber_scanf( ber, "{" /*"}"*/);
+		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
+			ber_scanf( ber, "m", &cookie );
+			if ( cookie.bv_val != NULL ) {
+				ber_bvreplace( &ls->ls_cookie, &cookie );
+			}
+#ifdef LDAP_SYNC_TRACE
+			fprintf( stderr, "\t\tgot cookie=%s\n",
+				cookie.bv_val ? cookie.bv_val : "(null)" );
+#endif /* LDAP_SYNC_TRACE */
+		}
+
+		refreshDeletes = 0;
+		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) {
+			ber_scanf( ber, "b", &refreshDeletes );
+			if ( refreshDeletes ) {
+				refreshDeletes = 1;
+			}
+		}
+
+		ber_scanf( ber, /*"{"*/ "}" );
+
+		/* NOTE: if any goto/return between ber_init() and here
+		 * is introduced, don't forget to ber_free() */
+		ber_free( ber, 1 );
+
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr, "\t\tgot refreshDeletes=%s\n",
+			refreshDeletes ? "TRUE" : "FALSE" );
+#endif /* LDAP_SYNC_TRACE */
+
+		/* FIXME: what should we do with the refreshDelete? */
+		switch ( refreshDeletes ) {
+		case 0:
+			ls->ls_refreshPhase = LDAP_SYNC_CAPI_PRESENTS;
+			break;
+
+		default:
+			ls->ls_refreshPhase = LDAP_SYNC_CAPI_DELETES;
+			break;
+		}
+
+		} /* fallthru */
+
+	case LDAP_SYNC_REFRESH_REQUIRED:
+		/* TODO: check for Sync Done Control */
+		/* FIXME: perhaps the handler should be called
+		 * also in case of failure; we'll deal with this 
+		 * later when implementing refreshOnly */
+		if ( ls->ls_search_result ) {
+			err = ls->ls_search_result( ls, res, refreshDeletes );
+		}
+		break;
+
+	default:
+		break;
+	}
+
+done:;
+	if ( matched != NULL ) {
+		ldap_memfree( matched );
+	}
+
+	if ( msg != NULL ) {
+		ldap_memfree( msg );
+	}
+
+	if ( ctrls != NULL ) {
+		ldap_controls_free( ctrls );
+	}
+
+	ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE;
+
+	return rc;
+}
+
+/*
+ * handle the LDAP_RES_INTERMEDIATE response
+ */
+static int
+ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDone )
+{
+	int			rc;
+	char			*retoid = NULL;
+        struct berval		*retdata = NULL;
+	BerElement		*ber = NULL;
+	ber_len_t		len;
+	ber_tag_t		tag,
+				syncinfo_tag;
+	struct berval		cookie;
+	int			refreshDeletes = 0;
+	BerVarray		syncUUIDs = NULL;
+	ldap_sync_refresh_t	phase;
+
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr, "\tgot LDAP_RES_INTERMEDIATE\n" );
+#endif /* LDAP_SYNC_TRACE */
+
+	assert( ls != NULL );
+	assert( res != NULL );
+	assert( refreshDone != NULL );
+
+	*refreshDone = 0;
+
+	rc = ldap_parse_intermediate( ls->ls_ld, res,
+		&retoid, &retdata, NULL, 0 );
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr, "\t%sldap_parse_intermediate(%s) == %d\n",
+		rc != LDAP_SUCCESS ? "!!! " : "",
+		retoid == NULL ? "\"\"" : retoid,
+		rc );
+#endif /* LDAP_SYNC_TRACE */
+	/* parsing must be successful, and yield the OID
+	 * of the sync info intermediate response */
+	if ( rc != LDAP_SUCCESS ) {
+		goto done;
+	}
+
+	if ( retoid == NULL || strcmp( retoid, LDAP_SYNC_INFO ) != 0 ) {
+		rc = LDAP_OTHER;
+		goto done;
+	}
+
+	/* init ber using the value in the response */
+	ber = ber_init( retdata );
+	if ( ber == NULL ) {
+		goto done;
+	}
+
+	syncinfo_tag = ber_peek_tag( ber, &len );
+	switch ( syncinfo_tag ) {
+	case LDAP_TAG_SYNC_NEW_COOKIE:
+		ber_scanf( ber, "tm", &tag, &cookie );
+		if ( cookie.bv_val != NULL ) {
+			ber_bvreplace( &ls->ls_cookie, &cookie );
+		}
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr, "\t\tgot cookie=%s\n",
+			cookie.bv_val ? cookie.bv_val : "(null)" );
+#endif /* LDAP_SYNC_TRACE */
+		break;
+
+	case LDAP_TAG_SYNC_REFRESH_DELETE:
+	case LDAP_TAG_SYNC_REFRESH_PRESENT:
+		if ( syncinfo_tag == LDAP_TAG_SYNC_REFRESH_DELETE ) {
+#ifdef LDAP_SYNC_TRACE
+			fprintf( stderr, "\t\tgot refreshDelete\n" );
+#endif /* LDAP_SYNC_TRACE */
+			switch ( ls->ls_refreshPhase ) {
+			case LDAP_SYNC_CAPI_NONE:
+			case LDAP_SYNC_CAPI_PRESENTS:
+				ls->ls_refreshPhase = LDAP_SYNC_CAPI_DELETES;
+				break;
+
+			default:
+				/* TODO: impossible; handle */
+				rc = LDAP_OTHER;
+				goto done;
+			}
+
+		} else {
+#ifdef LDAP_SYNC_TRACE
+			fprintf( stderr, "\t\tgot refreshPresent\n" );
+#endif /* LDAP_SYNC_TRACE */
+			switch ( ls->ls_refreshPhase ) {
+			case LDAP_SYNC_CAPI_NONE:
+				ls->ls_refreshPhase = LDAP_SYNC_CAPI_PRESENTS;
+				break;
+
+			default:
+				/* TODO: impossible; handle */
+				rc = LDAP_OTHER;
+				goto done;
+			}
+		}
+
+		ber_scanf( ber, "t{" /*"}"*/, &tag );
+		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
+			ber_scanf( ber, "m", &cookie );
+			if ( cookie.bv_val != NULL ) {
+				ber_bvreplace( &ls->ls_cookie, &cookie );
+			}
+#ifdef LDAP_SYNC_TRACE
+			fprintf( stderr, "\t\tgot cookie=%s\n",
+				cookie.bv_val ? cookie.bv_val : "(null)" );
+#endif /* LDAP_SYNC_TRACE */
+		}
+
+		*refreshDone = 1;
+		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDONE ) {
+			ber_scanf( ber, "b", refreshDone );
+		}
+
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr, "\t\tgot refreshDone=%s\n",
+			*refreshDone ? "TRUE" : "FALSE" );
+#endif /* LDAP_SYNC_TRACE */
+
+		ber_scanf( ber, /*"{"*/ "}" );
+
+		if ( *refreshDone ) {
+			ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE;
+		}
+
+		if ( ls->ls_intermediate ) {
+			ls->ls_intermediate( ls, res, NULL, ls->ls_refreshPhase );
+		}
+
+		break;
+
+	case LDAP_TAG_SYNC_ID_SET:
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr, "\t\tgot syncIdSet\n" );
+#endif /* LDAP_SYNC_TRACE */
+		ber_scanf( ber, "t{" /*"}"*/, &tag );
+		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
+			ber_scanf( ber, "m", &cookie );
+			if ( cookie.bv_val != NULL ) {
+				ber_bvreplace( &ls->ls_cookie, &cookie );
+			}
+#ifdef LDAP_SYNC_TRACE
+			fprintf( stderr, "\t\tgot cookie=%s\n",
+				cookie.bv_val ? cookie.bv_val : "(null)" );
+#endif /* LDAP_SYNC_TRACE */
+		}
+
+		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) {
+			ber_scanf( ber, "b", &refreshDeletes );
+		}
+
+		ber_scanf( ber, "[W]", &syncUUIDs );
+		ber_scanf( ber, /*"{"*/ "}" );
+		if ( syncUUIDs == NULL ) {
+			rc = LDAP_OTHER;
+			goto done;
+		}
+
+#ifdef LDAP_SYNC_TRACE
+		{
+			int	i;
+
+			fprintf( stderr, "\t\tgot refreshDeletes=%s\n",
+				refreshDeletes ? "TRUE" : "FALSE" );
+			for ( i = 0; syncUUIDs[ i ].bv_val != NULL; i++ ) {
+				char	buf[ BUFSIZ ];
+				fprintf( stderr, "\t\t%s\n", 
+					lutil_uuidstr_from_normalized(
+						syncUUIDs[ i ].bv_val, syncUUIDs[ i ].bv_len,
+						buf, sizeof( buf ) ) );
+			}
+		}
+#endif /* LDAP_SYNC_TRACE */
+
+		if ( refreshDeletes ) {
+			phase = LDAP_SYNC_CAPI_DELETES_IDSET;
+
+		} else {
+			phase = LDAP_SYNC_CAPI_PRESENTS_IDSET;
+		}
+
+		/* FIXME: should touch ls->ls_refreshPhase? */
+		if ( ls->ls_intermediate ) {
+			ls->ls_intermediate( ls, res, syncUUIDs, phase );
+		}
+
+		ber_bvarray_free( syncUUIDs );
+		break;
+
+	default:
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr, "\t\tunknown tag!\n" );
+#endif /* LDAP_SYNC_TRACE */
+		goto done;
+	}
+
+done:;
+	if ( ber != NULL ) {
+		ber_free( ber, 1 );
+	}
+
+	if ( retoid != NULL ) {
+		ldap_memfree( retoid );
+	}
+
+	if ( retdata != NULL ) {
+		ber_bvfree( retdata );
+	}
+
+	return rc;
+}
+
+/*
+ * initialize the sync
+ */
+int
+ldap_sync_init( ldap_sync_t *ls, int mode )
+{
+	LDAPControl	ctrl = { 0 },
+			*ctrls[ 2 ];
+	BerElement	*ber = NULL;
+	int		rc;
+	struct timeval	tv = { 0 },
+			*tvp = NULL;
+	LDAPMessage	*res = NULL;
+
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr, "ldap_sync_init(%s)...\n",
+		mode == LDAP_SYNC_REFRESH_AND_PERSIST ?
+			"LDAP_SYNC_REFRESH_AND_PERSIST" :
+			( mode == LDAP_SYNC_REFRESH_ONLY ? 
+				"LDAP_SYNC_REFRESH_ONLY" : "unknown" ) );
+#endif /* LDAP_SYNC_TRACE */
+
+	assert( ls != NULL );
+	assert( ls->ls_ld != NULL );
+
+	/* support both refreshOnly and refreshAndPersist */
+	switch ( mode ) {
+	case LDAP_SYNC_REFRESH_AND_PERSIST:
+	case LDAP_SYNC_REFRESH_ONLY:
+		break;
+
+	default:
+		fprintf( stderr, "ldap_sync_init: unknown mode=%d\n", mode );
+		return LDAP_PARAM_ERROR;
+	}
+
+	/* check consistency of cookie and reloadHint at initial refresh */
+	if ( ls->ls_cookie.bv_val == NULL && ls->ls_reloadHint != 0 ) {
+		fprintf( stderr, "ldap_sync_init: inconsistent cookie/rhint\n" );
+		return LDAP_PARAM_ERROR;
+	}
+
+	ctrls[ 0 ] = &ctrl;
+	ctrls[ 1 ] = NULL;
+
+	/* prepare the Sync Request control */
+	ber = ber_alloc_t( LBER_USE_DER );
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr, "%sber_alloc_t() %s= NULL\n",
+		ber == NULL ? "!!! " : "",
+		ber == NULL ? "=" : "!" );
+#endif /* LDAP_SYNC_TRACE */
+	if ( ber == NULL ) {
+		rc = LDAP_NO_MEMORY;
+		goto done;
+	}
+
+	ls->ls_refreshPhase = LDAP_SYNC_CAPI_NONE;
+
+	if ( ls->ls_cookie.bv_val != NULL ) {
+		ber_printf( ber, "{eOb}", mode,
+			&ls->ls_cookie, ls->ls_reloadHint );
+
+	} else {
+		ber_printf( ber, "{eb}", mode, ls->ls_reloadHint );
+	}
+
+	rc = ber_flatten2( ber, &ctrl.ldctl_value, 0 );
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr,
+		"%sber_flatten2() == %d\n",
+		rc ? "!!! " : "",
+		rc );
+#endif /* LDAP_SYNC_TRACE */
+	if ( rc == LBER_ERROR ) {
+		rc = LDAP_OTHER;
+                goto done;
+        }
+
+	/* make the control critical, as we cannot proceed without */
+	ctrl.ldctl_oid = LDAP_CONTROL_SYNC;
+	ctrl.ldctl_iscritical = 1;
+
+	/* timelimit? */
+	if ( ls->ls_timelimit ) {
+		tv.tv_sec = ls->ls_timelimit;
+		tvp = &tv;
+	}
+
+	/* actually run the search */
+	rc = ldap_search_ext( ls->ls_ld,
+		ls->ls_base, ls->ls_scope, ls->ls_filter,
+		ls->ls_attrs, 0, ctrls, NULL,
+		tvp, ls->ls_sizelimit, &ls->ls_msgid );
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr,
+		"%sldap_search_ext(\"%s\", %d, \"%s\") == %d\n",
+		rc ? "!!! " : "",
+		ls->ls_base, ls->ls_scope, ls->ls_filter, rc );
+#endif /* LDAP_SYNC_TRACE */
+	if ( rc != LDAP_SUCCESS ) {
+		goto done;
+	}
+
+	/* initial content/content update phase */
+	for ( ; ; ) {
+		LDAPMessage	*msg = NULL;
+
+		/* NOTE: this very short timeout is just to let
+		 * ldap_result() yield long enough to get something */
+		tv.tv_sec = 0;
+		tv.tv_usec = 100000;
+
+		rc = ldap_result( ls->ls_ld, ls->ls_msgid,
+			LDAP_MSG_RECEIVED, &tv, &res );
+#ifdef LDAP_SYNC_TRACE
+		fprintf( stderr,
+			"\t%sldap_result(%d) == %d\n",
+			rc == -1 ? "!!! " : "",
+			ls->ls_msgid, rc );
+#endif /* LDAP_SYNC_TRACE */
+		switch ( rc ) {
+		case 0:
+			/*
+			 * timeout
+			 *
+			 * TODO: can do something else in the meanwhile)
+			 */
+			break;
+
+		case -1:
+			/* smtg bad! */
+			goto done;
+
+		default:
+			for ( msg = ldap_first_message( ls->ls_ld, res );
+				msg != NULL;
+				msg = ldap_next_message( ls->ls_ld, msg ) )
+			{
+				int	refreshDone;
+
+				switch ( ldap_msgtype( msg ) ) {
+				case LDAP_RES_SEARCH_ENTRY:
+					rc = ldap_sync_search_entry( ls, res );
+					break;
+
+				case LDAP_RES_SEARCH_REFERENCE:
+					rc = ldap_sync_search_reference( ls, res );
+					break;
+
+				case LDAP_RES_SEARCH_RESULT:
+					rc = ldap_sync_search_result( ls, res );
+					goto done_search;
+
+				case LDAP_RES_INTERMEDIATE:
+					rc = ldap_sync_search_intermediate( ls, res, &refreshDone );
+					if ( rc != LDAP_SUCCESS || refreshDone ) {
+						goto done_search;
+					}
+					break;
+
+				default:
+#ifdef LDAP_SYNC_TRACE
+					fprintf( stderr, "\tgot something unexpected...\n" );
+#endif /* LDAP_SYNC_TRACE */
+
+					ldap_msgfree( res );
+
+					rc = LDAP_OTHER;
+					goto done;
+				}
+			}
+			ldap_msgfree( res );
+			res = NULL;
+			break;
+		}
+	}
+
+done_search:;
+	ldap_msgfree( res );
+
+done:;
+	if ( ber != NULL ) {
+		ber_free( ber, 1 );
+	}
+
+	return rc;
+}
+
+/*
+ * initialize the refreshOnly sync
+ */
+int
+ldap_sync_init_refresh_only( ldap_sync_t *ls )
+{
+	return ldap_sync_init( ls, LDAP_SYNC_REFRESH_ONLY );
+}
+
+/*
+ * initialize the refreshAndPersist sync
+ */
+int
+ldap_sync_init_refresh_and_persist( ldap_sync_t *ls )
+{
+	return ldap_sync_init( ls, LDAP_SYNC_REFRESH_AND_PERSIST );
+}
+
+/*
+ * poll for new responses
+ */
+int
+ldap_sync_poll( ldap_sync_t *ls )
+{
+	struct	timeval		tv,
+				*tvp = NULL;
+	LDAPMessage		*res = NULL,
+				*msg;
+	int			rc = 0;
+
+#ifdef LDAP_SYNC_TRACE
+	fprintf( stderr, "ldap_sync_poll...\n" );
+#endif /* LDAP_SYNC_TRACE */
+
+	assert( ls != NULL );
+	assert( ls->ls_ld != NULL );
+
+	if ( ls->ls_timeout != -1 ) {
+		tv.tv_sec = ls->ls_timeout;
+		tv.tv_usec = 0;
+		tvp = &tv;
+	}
+
+	rc = ldap_result( ls->ls_ld, ls->ls_msgid,
+		LDAP_MSG_RECEIVED, tvp, &res );
+	if ( rc <= 0 ) {
+		return rc;
+	}
+
+	for ( msg = ldap_first_message( ls->ls_ld, res );
+		msg;
+		msg = ldap_next_message( ls->ls_ld, msg ) )
+	{
+		int	refreshDone;
+
+		switch ( ldap_msgtype( msg ) ) {
+		case LDAP_RES_SEARCH_ENTRY:
+			rc = ldap_sync_search_entry( ls, res );
+			break;
+
+		case LDAP_RES_SEARCH_REFERENCE:
+			rc = ldap_sync_search_reference( ls, res );
+			break;
+
+		case LDAP_RES_SEARCH_RESULT:
+			rc = ldap_sync_search_result( ls, res );
+			goto done_search;
+
+		case LDAP_RES_INTERMEDIATE:
+			rc = ldap_sync_search_intermediate( ls, res, &refreshDone );
+			if ( rc != LDAP_SUCCESS || refreshDone ) {
+				goto done_search;
+			}
+			break;
+
+		default:
+#ifdef LDAP_SYNC_TRACE
+			fprintf( stderr, "\tgot something unexpected...\n" );
+#endif /* LDAP_SYNC_TRACE */
+
+			ldap_msgfree( res );
+
+			rc = LDAP_OTHER;
+			goto done;
+		}
+	}
+
+done_search:;
+	ldap_msgfree( res );
+
+done:;
+	return rc;
+}
+

Modified: openldap/trunk/libraries/libldap/messages.c
===================================================================
--- openldap/trunk/libraries/libldap/messages.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/messages.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* messages.c */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/messages.c,v 1.15.2.3 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/messages.c,v 1.17.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/modify.c
===================================================================
--- openldap/trunk/libraries/libldap/modify.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/modify.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/modify.c,v 1.21.2.4 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/modify.c,v 1.25.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -15,9 +15,6 @@
 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
  * All rights reserved.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
 #include "portable.h"
 
@@ -29,6 +26,32 @@
 
 #include "ldap-int.h"
 
+/* A modify request/response looks like this:
+ *        ModifyRequest ::= [APPLICATION 6] SEQUENCE {              
+ *             object          LDAPDN,
+ *             changes         SEQUENCE OF change SEQUENCE {
+ *                  operation       ENUMERATED {      
+ *                       add     (0),                
+ *                       delete  (1),                 
+ *                       replace (2),
+ *                       ...  },
+ *                  modification    PartialAttribute } }                  
+ *
+ *        PartialAttribute ::= SEQUENCE {
+ *             type       AttributeDescription,
+ *             vals       SET OF value AttributeValue }
+ *
+ *        AttributeDescription ::= LDAPString           
+ *              -- Constrained to <attributedescription> [RFC4512]
+ *                                      
+ *        AttributeValue ::= OCTET STRING
+ *		
+ *        ModifyResponse ::= [APPLICATION 7] LDAPResult
+ *
+ * (Source: RFC 4511)
+ */
+
+
 /*
  * ldap_modify_ext - initiate an ldap extended modify operation.
  *
@@ -65,25 +88,6 @@
 	int		i, rc;
 	ber_int_t	id;
 
-	/*
-	 * A modify request looks like this:
-	 *	ModifyRequet ::= SEQUENCE {
-	 *		object		DistinguishedName,
-	 *		modifications	SEQUENCE OF SEQUENCE {
-	 *			operation	ENUMERATED {
-	 *				add	(0),
-	 *				delete (1),
-	 *				replace	(2),
-	 *				increment (3) -- extension
-	 *			},
-	 *			modification	SEQUENCE {
-	 *				type	AttributeType,
-	 *				values	SET OF AttributeValue
-	 *			}
-	 *		}
-	 *	}
-	 */
-
 	Debug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
 
 	/* check client controls */
@@ -197,7 +201,7 @@
 	if ( rc != LDAP_SUCCESS )
 		return( rc );
 
-	if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
+	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
 		return( ld->ld_errno );
 
 	return( ldap_result2error( ld, res, 1 ) );

Modified: openldap/trunk/libraries/libldap/modrdn.c
===================================================================
--- openldap/trunk/libraries/libldap/modrdn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/modrdn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/modrdn.c,v 1.27.2.3 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/modrdn.c,v 1.30.2.2 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -23,14 +23,21 @@
  * without restriction or fee of any kind as long as this notice
  * is preserved.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC 2251 for full legal notices.
- */
 
 /* ACKNOWLEDGEMENTS:
  * 	Juan C. Gomez
  */
 
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+
 /*
  * A modify rdn request looks like this:
  *	ModifyRDNRequest ::= SEQUENCE {
@@ -41,16 +48,7 @@
  *	}
  */
 
-#include "portable.h"
 
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#include "ldap-int.h"
-
 /*
  * ldap_rename - initiate an ldap extended modifyDN operation.
  *
@@ -219,9 +217,9 @@
 		return rc;
 	}
 
-	rc = ldap_result( ld, msgid, 1, NULL, &res );
+	rc = ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &res );
 
-	if( rc == -1 ) {
+	if( rc == -1 || !res ) {
 		return ld->ld_errno;
 	}
 

Modified: openldap/trunk/libraries/libldap/open.c
===================================================================
--- openldap/trunk/libraries/libldap/open.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/open.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/open.c,v 1.105.2.7 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/open.c,v 1.110.2.5 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -39,7 +39,7 @@
 int ldap_open_defconn( LDAP *ld )
 {
 	ld->ld_defconn = ldap_new_connection( ld,
-		ld->ld_options.ldo_defludp, 1, 1, NULL );
+		&ld->ld_options.ldo_defludp, 1, 1, NULL );
 
 	if( ld->ld_defconn == NULL ) {
 		ld->ld_errno = LDAP_SERVER_DOWN;
@@ -122,8 +122,6 @@
 	/* but not pointers to malloc'ed items */
 	ld->ld_options.ldo_sctrls = NULL;
 	ld->ld_options.ldo_cctrls = NULL;
-	ld->ld_options.ldo_tm_api = NULL;
-	ld->ld_options.ldo_tm_net = NULL;
 	ld->ld_options.ldo_defludp = NULL;
 
 #ifdef HAVE_CYRUS_SASL
@@ -137,14 +135,15 @@
 		? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL;
 #endif
 
-	if ( gopts->ldo_tm_api &&
-		ldap_int_timeval_dup( &ld->ld_options.ldo_tm_api, gopts->ldo_tm_api ))
-		goto nomem;
+#ifdef HAVE_TLS
+	/* We explicitly inherit the SSL_CTX, don't need the names/paths. Leave
+	 * them empty to allow new SSL_CTX's to be created from scratch.
+	 */
+	memset( &ld->ld_options.ldo_tls_info, 0,
+		sizeof( ld->ld_options.ldo_tls_info ));
+	ld->ld_options.ldo_tls_ctx = NULL;
+#endif
 
-	if ( gopts->ldo_tm_net &&
-		ldap_int_timeval_dup( &ld->ld_options.ldo_tm_net, gopts->ldo_tm_net ))
-		goto nomem;
-
 	if ( gopts->ldo_defludp ) {
 		ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp);
 
@@ -169,8 +168,6 @@
 nomem:
 	ldap_free_select_info( ld->ld_selectinfo );
 	ldap_free_urllist( ld->ld_options.ldo_defludp );
-	LDAP_FREE( ld->ld_options.ldo_tm_net );
-	LDAP_FREE( ld->ld_options.ldo_tm_api );
 #ifdef HAVE_CYRUS_SASL
 	LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid );
 	LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid );
@@ -243,6 +240,95 @@
 }
 
 int
+ldap_init_fd(
+	ber_socket_t fd,
+	int proto,
+	LDAP_CONST char *url,
+	LDAP **ldp
+)
+{
+	int rc;
+	LDAP *ld;
+	LDAPConn *conn;
+
+	*ldp = NULL;
+	rc = ldap_create( &ld );
+	if( rc != LDAP_SUCCESS )
+		return( rc );
+
+	if (url != NULL) {
+		rc = ldap_set_option(ld, LDAP_OPT_URI, url);
+		if ( rc != LDAP_SUCCESS ) {
+			ldap_ld_free(ld, 1, NULL, NULL);
+			return rc;
+		}
+	}
+
+	/* Attach the passed socket as the LDAP's connection */
+	conn = ldap_new_connection( ld, NULL, 1, 0, NULL);
+	if( conn == NULL ) {
+		ldap_unbind_ext( ld, NULL, NULL );
+		return( LDAP_NO_MEMORY );
+	}
+	ber_sockbuf_ctrl( conn->lconn_sb, LBER_SB_OPT_SET_FD, &fd );
+	ld->ld_defconn = conn;
+	++ld->ld_defconn->lconn_refcnt;	/* so it never gets closed/freed */
+
+	switch( proto ) {
+	case LDAP_PROTO_TCP:
+#ifdef LDAP_DEBUG
+		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
+			LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" );
+#endif
+		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp,
+			LBER_SBIOD_LEVEL_PROVIDER, NULL );
+		break;
+
+#ifdef LDAP_CONNECTIONLESS
+	case LDAP_PROTO_UDP:
+#ifdef LDAP_DEBUG
+		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
+			LBER_SBIOD_LEVEL_PROVIDER, (void *)"udp_" );
+#endif
+		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp,
+			LBER_SBIOD_LEVEL_PROVIDER, NULL );
+		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead,
+			LBER_SBIOD_LEVEL_PROVIDER, NULL );
+		break;
+#endif /* LDAP_CONNECTIONLESS */
+
+	case LDAP_PROTO_IPC:
+#ifdef LDAP_DEBUG
+		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
+			LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" );
+#endif
+		ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd,
+			LBER_SBIOD_LEVEL_PROVIDER, NULL );
+		break;
+
+	case LDAP_PROTO_EXT:
+		/* caller must supply sockbuf handlers */
+		break;
+
+	default:
+		ldap_unbind_ext( ld, NULL, NULL );
+		return LDAP_PARAM_ERROR;
+	}
+
+#ifdef LDAP_DEBUG
+	ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
+		INT_MAX, (void *)"ldap_" );
+#endif
+
+	/* Add the connection to the *LDAP's select pool */
+	ldap_mark_select_read( ld, conn->lconn_sb );
+	ldap_mark_select_write( ld, conn->lconn_sb );
+	
+	*ldp = ld;
+	return LDAP_SUCCESS;
+}
+
+int
 ldap_int_open_connection(
 	LDAP *ld,
 	LDAPConn *conn,
@@ -336,6 +422,8 @@
 			break;
 	}
 
+	conn->lconn_created = time( NULL );
+
 #ifdef LDAP_DEBUG
 	ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
 		INT_MAX, (void *)"ldap_" );
@@ -361,24 +449,12 @@
 	}
 #endif
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-	if ( conn->lconn_krbinstance == NULL ) {
-		char *c;
-		conn->lconn_krbinstance = ldap_host_connected_to(
-			conn->lconn_sb, host );
-
-		if( conn->lconn_krbinstance != NULL && 
-		    ( c = strchr( conn->lconn_krbinstance, '.' )) != NULL ) {
-			*c = '\0';
-		}
-	}
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
-
 	return( 0 );
 }
 
 
-int ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
+int
+ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
 {
 	int rc;
 	LDAPConn *c;
@@ -393,7 +469,7 @@
 	/* Make it appear that a search request, msgid 0, was sent */
 	lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ));
 	if( lr == NULL ) {
-		ldap_unbind( *ldp );
+		ldap_unbind_ext( *ldp, NULL, NULL );
 		*ldp = NULL;
 		return( LDAP_NO_MEMORY );
 	}
@@ -407,7 +483,7 @@
 	/* Attach the passed socket as the *LDAP's connection */
 	c = ldap_new_connection( *ldp, NULL, 1, 0, NULL);
 	if( c == NULL ) {
-		ldap_unbind( *ldp );
+		ldap_unbind_ext( *ldp, NULL, NULL );
 		*ldp = NULL;
 		return( LDAP_NO_MEMORY );
 	}

Modified: openldap/trunk/libraries/libldap/options.c
===================================================================
--- openldap/trunk/libraries/libldap/options.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/options.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/options.c,v 1.67.2.8 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/options.c,v 1.75.2.5 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -31,6 +31,9 @@
 #define LDAP_OPT_NEXTREF_PROC 0x4e815d
 #define LDAP_OPT_NEXTREF_PARAMS 0x4e815e
 
+#define LDAP_OPT_URLLIST_PROC 0x4e816d
+#define LDAP_OPT_URLLIST_PARAMS 0x4e816e
+
 static const LDAPAPIFeatureInfo features[] = {
 #ifdef LDAP_API_FEATURE_X_OPENLDAP
 	{	/* OpenLDAP Extensions API Feature */
@@ -174,14 +177,18 @@
 
 	case LDAP_OPT_TIMEOUT:
 		/* the caller has to free outvalue ! */
-		if ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_api) != 0 ) {
+		if ( lo->ldo_tm_api.tv_sec < 0 ) {
+			*(void **)outvalue = NULL;
+		} else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_api ) != 0 ) {
 			return LDAP_OPT_ERROR;
 		}
 		return LDAP_OPT_SUCCESS;
 		
 	case LDAP_OPT_NETWORK_TIMEOUT:
 		/* the caller has to free outvalue ! */
-		if ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_net ) != 0 ) {
+		if ( lo->ldo_tm_net.tv_sec < 0 ) {
+			*(void **)outvalue = NULL;
+		} else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_net ) != 0 ) {
 			return LDAP_OPT_ERROR;
 		}
 		return LDAP_OPT_SUCCESS;
@@ -230,7 +237,20 @@
 		* (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp);
 		return LDAP_OPT_SUCCESS;
 
-	case LDAP_OPT_ERROR_NUMBER:
+	case LDAP_OPT_DEFBASE:
+		if( lo->ldo_defbase == NULL ) {
+			* (char **) outvalue = NULL;
+		} else {
+			* (char **) outvalue = LDAP_STRDUP(lo->ldo_defbase);
+		}
+
+		return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_CONNECT_ASYNC:
+		* (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_CONNECT_ASYNC);
+		return LDAP_OPT_SUCCESS;
+		
+	case LDAP_OPT_RESULT_CODE:
 		if(ld == NULL) {
 			/* bad param */
 			break;
@@ -238,7 +258,7 @@
 		* (int *) outvalue = ld->ld_errno;
 		return LDAP_OPT_SUCCESS;
 
-	case LDAP_OPT_ERROR_STRING:
+	case LDAP_OPT_DIAGNOSTIC_MESSAGE:
 		if(ld == NULL) {
 			/* bad param */
 			break;
@@ -380,6 +400,14 @@
 			LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART);
 		}
 		return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_CONNECT_ASYNC:
+		if(invalue == LDAP_OPT_OFF) {
+			LDAP_BOOL_CLR(lo, LDAP_BOOL_CONNECT_ASYNC);
+		} else {
+			LDAP_BOOL_SET(lo, LDAP_BOOL_CONNECT_ASYNC);
+		}
+		return LDAP_OPT_SUCCESS;
 	}
 
 	/* options which can withstand invalue == NULL */
@@ -424,34 +452,7 @@
 			}
 		} return LDAP_OPT_SUCCESS;
 
-	case LDAP_OPT_TIMEOUT: {
-			const struct timeval *tv = 
-				(const struct timeval *) invalue;
 
-			if ( lo->ldo_tm_api != NULL ) {
-				LDAP_FREE( lo->ldo_tm_api );
-				lo->ldo_tm_api = NULL;
-			}
-
-			if ( ldap_int_timeval_dup( &lo->ldo_tm_api, tv ) != 0 ) {
-				return LDAP_OPT_ERROR;
-			}
-		} return LDAP_OPT_SUCCESS;
-
-	case LDAP_OPT_NETWORK_TIMEOUT: {
-			const struct timeval *tv = 
-				(const struct timeval *) invalue;
-
-			if ( lo->ldo_tm_net != NULL ) {
-				LDAP_FREE( lo->ldo_tm_net );
-				lo->ldo_tm_net = NULL;
-			}
-
-			if ( ldap_int_timeval_dup( &lo->ldo_tm_net, tv ) != 0 ) {
-				return LDAP_OPT_ERROR;
-			}
-		} return LDAP_OPT_SUCCESS;
-
 	case LDAP_OPT_HOST_NAME: {
 			const char *host = (const char *) invalue;
 			LDAPURLDesc *ludlist = NULL;
@@ -466,7 +467,9 @@
 				 * must want global default returned
 				 * to initial condition.
 				 */
-				rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
+				rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL,
+					LDAP_PVT_URL_PARSE_NOEMPTY_HOST
+					| LDAP_PVT_URL_PARSE_DEF_PORT );
 
 			} else {
 				/*
@@ -493,13 +496,17 @@
 			int rc = LDAP_OPT_SUCCESS;
 
 			if(urls != NULL) {
-				rc = ldap_url_parselist(&ludlist, urls);
+				rc = ldap_url_parselist_ext(&ludlist, urls, NULL,
+					LDAP_PVT_URL_PARSE_NOEMPTY_HOST
+					| LDAP_PVT_URL_PARSE_DEF_PORT );
 			} else if(ld == NULL) {
 				/*
 				 * must want global default returned
 				 * to initial condition.
 				 */
-				rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
+				rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL,
+					LDAP_PVT_URL_PARSE_NOEMPTY_HOST
+					| LDAP_PVT_URL_PARSE_DEF_PORT );
 
 			} else {
 				/*
@@ -509,7 +516,7 @@
 				ludlist = ldap_url_duplist(
 					ldap_int_global_options.ldo_defludp);
 				if (ludlist == NULL)
-					rc = LDAP_NO_MEMORY;
+					rc = LDAP_URL_ERR_MEM;
 			}
 
 			switch (rc) {
@@ -534,7 +541,7 @@
 				break;
 			}
 
-			if (rc == LDAP_OPT_SUCCESS) {
+			if (rc == LDAP_SUCCESS) {
 				if (lo->ldo_defludp != NULL)
 					ldap_free_urllist(lo->ldo_defludp);
 				lo->ldo_defludp = ludlist;
@@ -542,74 +549,30 @@
 			return rc;
 		}
 
-	/* Only accessed from inside this function by ldap_set_rebind_proc() */
-	case LDAP_OPT_REBIND_PROC: {
-			lo->ldo_rebind_proc = (LDAP_REBIND_PROC *)invalue;		
-		} return LDAP_OPT_SUCCESS;
-	case LDAP_OPT_REBIND_PARAMS: {
-			lo->ldo_rebind_params = (void *)invalue;		
-		} return LDAP_OPT_SUCCESS;
+	case LDAP_OPT_DEFBASE: {
+			const char *newbase = (const char *) invalue;
+			char *defbase = NULL;
 
-	/* Only accessed from inside this function by ldap_set_nextref_proc() */
-	case LDAP_OPT_NEXTREF_PROC: {
-			lo->ldo_nextref_proc = (LDAP_NEXTREF_PROC *)invalue;		
-		} return LDAP_OPT_SUCCESS;
-	case LDAP_OPT_NEXTREF_PARAMS: {
-			lo->ldo_nextref_params = (void *)invalue;		
-		} return LDAP_OPT_SUCCESS;
-	}
+			if ( newbase != NULL ) {
+				defbase = LDAP_STRDUP( newbase );
+				if ( defbase == NULL ) return LDAP_NO_MEMORY;
 
-	if(invalue == NULL) {
-		/* no place to set from */
-		return LDAP_OPT_ERROR;
-	}
-
-	/* options which cannot withstand invalue == NULL */
-
-	switch(option) {
-	case LDAP_OPT_API_INFO:
-	case LDAP_OPT_DESC:
-		/* READ ONLY */
-		break;
-
-	case LDAP_OPT_DEREF:
-		lo->ldo_deref = * (const int *) invalue;
-		return LDAP_OPT_SUCCESS;
-
-	case LDAP_OPT_SIZELIMIT:
-		lo->ldo_sizelimit = * (const int *) invalue;
-		return LDAP_OPT_SUCCESS;
-
-	case LDAP_OPT_TIMELIMIT:
-		lo->ldo_timelimit = * (const int *) invalue;
-		return LDAP_OPT_SUCCESS;
-
-	case LDAP_OPT_PROTOCOL_VERSION: {
-			int vers = * (const int *) invalue;
-			if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
-				/* not supported */
-				break;
+			} else if ( ld != NULL ) {
+				defbase = LDAP_STRDUP( ldap_int_global_options.ldo_defbase );
+				if ( defbase == NULL ) return LDAP_NO_MEMORY;
 			}
-			lo->ldo_version = vers;
+			
+			if ( lo->ldo_defbase != NULL )
+				LDAP_FREE( lo->ldo_defbase );
+			lo->ldo_defbase = defbase;
 		} return LDAP_OPT_SUCCESS;
 
-	case LDAP_OPT_ERROR_NUMBER: {
-			int err = * (const int *) invalue;
-
-			if(ld == NULL) {
-				/* need a struct ldap */
-				break;
-			}
-
-			ld->ld_errno = err;
-		} return LDAP_OPT_SUCCESS;
-
-	case LDAP_OPT_ERROR_STRING: {
+	case LDAP_OPT_DIAGNOSTIC_MESSAGE: {
 			const char *err = (const char *) invalue;
 
 			if(ld == NULL) {
 				/* need a struct ldap */
-				break;
+				return LDAP_OPT_ERROR;
 			}
 
 			if( ld->ld_error ) {
@@ -627,7 +590,7 @@
 
 			if (ld == NULL) {
 				/* need a struct ldap */
-				break;
+				return LDAP_OPT_ERROR;
 			}
 
 			if( ld->ld_matched ) {
@@ -645,23 +608,63 @@
 			
 			if(ld == NULL) {
 				/* need a struct ldap */
-				break;
+				return LDAP_OPT_ERROR;
 			}
 
 			if( ld->ld_referrals ) {
 				LDAP_VFREE(ld->ld_referrals);
 			}
 
-			ld->ld_referrals = ldap_value_dup(referrals);
+			if ( referrals ) {
+				ld->ld_referrals = ldap_value_dup(referrals);
+			}
 		} return LDAP_OPT_SUCCESS;
 
+	/* Only accessed from inside this function by ldap_set_rebind_proc() */
+	case LDAP_OPT_REBIND_PROC: {
+			lo->ldo_rebind_proc = (LDAP_REBIND_PROC *)invalue;		
+		} return LDAP_OPT_SUCCESS;
+	case LDAP_OPT_REBIND_PARAMS: {
+			lo->ldo_rebind_params = (void *)invalue;		
+		} return LDAP_OPT_SUCCESS;
+
+	/* Only accessed from inside this function by ldap_set_nextref_proc() */
+	case LDAP_OPT_NEXTREF_PROC: {
+			lo->ldo_nextref_proc = (LDAP_NEXTREF_PROC *)invalue;		
+		} return LDAP_OPT_SUCCESS;
+	case LDAP_OPT_NEXTREF_PARAMS: {
+			lo->ldo_nextref_params = (void *)invalue;		
+		} return LDAP_OPT_SUCCESS;
+
+	/* Only accessed from inside this function by ldap_set_urllist_proc() */
+	case LDAP_OPT_URLLIST_PROC: {
+			lo->ldo_urllist_proc = (LDAP_URLLIST_PROC *)invalue;		
+		} return LDAP_OPT_SUCCESS;
+	case LDAP_OPT_URLLIST_PARAMS: {
+			lo->ldo_urllist_params = (void *)invalue;		
+		} return LDAP_OPT_SUCCESS;
+
+	/* read-only options */
+	case LDAP_OPT_API_INFO:
+	case LDAP_OPT_DESC:
+	case LDAP_OPT_SOCKBUF:
 	case LDAP_OPT_API_FEATURE_INFO:
-		/* read-only */
-		break;
+		return LDAP_OPT_ERROR;
 
+	/* options which cannot withstand invalue == NULL */
+	case LDAP_OPT_DEREF:
+	case LDAP_OPT_SIZELIMIT:
+	case LDAP_OPT_TIMELIMIT:
+	case LDAP_OPT_PROTOCOL_VERSION:
+	case LDAP_OPT_RESULT_CODE:
 	case LDAP_OPT_DEBUG_LEVEL:
-		lo->ldo_debug = * (const int *) invalue;
-		return LDAP_OPT_SUCCESS;
+	case LDAP_OPT_TIMEOUT:
+	case LDAP_OPT_NETWORK_TIMEOUT:
+		if(invalue == NULL) {
+			/* no place to set from */
+			return LDAP_OPT_ERROR;
+		}
+		break;
 
 	default:
 #ifdef HAVE_TLS
@@ -673,8 +676,65 @@
 			return LDAP_OPT_SUCCESS;
 #endif
 		/* bad param */
-		break;
+		return LDAP_OPT_ERROR;
 	}
+
+	/* options which cannot withstand invalue == NULL */
+
+	switch(option) {
+	case LDAP_OPT_DEREF:
+		/* FIXME: check value for protocol compliance? */
+		lo->ldo_deref = * (const int *) invalue;
+		return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_SIZELIMIT:
+		/* FIXME: check value for protocol compliance? */
+		lo->ldo_sizelimit = * (const int *) invalue;
+		return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_TIMELIMIT:
+		/* FIXME: check value for protocol compliance? */
+		lo->ldo_timelimit = * (const int *) invalue;
+		return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_TIMEOUT: {
+			const struct timeval *tv = 
+				(const struct timeval *) invalue;
+
+			lo->ldo_tm_api = *tv;
+		} return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_NETWORK_TIMEOUT: {
+			const struct timeval *tv = 
+				(const struct timeval *) invalue;
+
+			lo->ldo_tm_net = *tv;
+		} return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_PROTOCOL_VERSION: {
+			int vers = * (const int *) invalue;
+			if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
+				/* not supported */
+				break;
+			}
+			lo->ldo_version = vers;
+		} return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_RESULT_CODE: {
+			int err = * (const int *) invalue;
+
+			if(ld == NULL) {
+				/* need a struct ldap */
+				break;
+			}
+
+			ld->ld_errno = err;
+		} return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_DEBUG_LEVEL:
+		lo->ldo_debug = * (const int *) invalue;
+		return LDAP_OPT_SUCCESS;
+	}
 	return LDAP_OPT_ERROR;
 }
 
@@ -699,3 +759,14 @@
 	rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PARAMS, (void *)params );
 	return rc;
 }
+
+int
+ldap_set_urllist_proc( LDAP *ld, LDAP_URLLIST_PROC *proc, void *params )
+{
+	int rc;
+	rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PROC, (void *)proc );
+	if( rc != LDAP_OPT_SUCCESS ) return rc;
+
+	rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PARAMS, (void *)params );
+	return rc;
+}

Modified: openldap/trunk/libraries/libldap/os-ip.c
===================================================================
--- openldap/trunk/libraries/libldap/os-ip.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/os-ip.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* os-ip.c -- platform-specific TCP & UDP related code */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/os-ip.c,v 1.108.2.14 2007/06/10 18:39:53 hallvard Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/os-ip.c,v 1.118.2.3 2007/08/31 23:13:55 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -214,83 +214,63 @@
 
 #endif /* HAVE_WINSOCK */
 
-static int
-ldap_pvt_connect(LDAP *ld, ber_socket_t s,
-	struct sockaddr *sin, ber_socklen_t addrlen,
-	int async)
+/* NOTE: this is identical to analogous code in os-local.c */
+int
+ldap_int_poll(
+	LDAP *ld,
+	ber_socket_t s,
+	struct timeval *tvp )
 {
-	int rc, err;
-	struct timeval	tv = { 0 },
-			*opt_tv = NULL;
+	int		rc;
+		
 
-#ifdef LDAP_CONNECTIONLESS
-	/* We could do a connect() but that would interfere with
-	 * attempts to poll a broadcast address
-	 */
-	if (LDAP_IS_UDP(ld)) {
-		if (ld->ld_options.ldo_peer)
-			ldap_memfree(ld->ld_options.ldo_peer);
-		ld->ld_options.ldo_peer=ldap_memalloc(sizeof(struct sockaddr));
-		AC_MEMCPY(ld->ld_options.ldo_peer,sin,sizeof(struct sockaddr));
-		return ( 0 );
-	}
-#endif
-	opt_tv = ld->ld_options.ldo_tm_net;
-	if ( opt_tv != NULL ) {
-		tv = *opt_tv;
-	}
+	osip_debug(ld, "ldap_int_poll: fd: %d tm: %ld\n",
+		s, tvp ? tvp->tv_sec : -1L, 0);
 
-	osip_debug(ld, "ldap_connect_timeout: fd: %d tm: %ld async: %d\n",
-			s, opt_tv ? tv.tv_sec : -1L, async);
-
-	if ( opt_tv && ldap_pvt_ndelay_on(ld, s) == -1 )
-		return ( -1 );
-
-	if ( connect(s, sin, addrlen) != AC_SOCKET_ERROR ) {
-		if ( opt_tv && ldap_pvt_ndelay_off(ld, s) == -1 )
-			return ( -1 );
-		return ( 0 );
-	}
-
-	err = sock_errno();
-	if ( err != EINPROGRESS && err != EWOULDBLOCK ) {
-		return ( -1 );
-	}
-	
-#ifdef notyet
-	if ( async ) return ( -2 );
-#endif
-
 #ifdef HAVE_POLL
 	{
 		struct pollfd fd;
 		int timeout = INFTIM;
 
-		if( opt_tv != NULL ) timeout = TV2MILLISEC( &tv );
-
 		fd.fd = s;
 		fd.events = POLL_WRITE;
 
+		if ( tvp != NULL ) {
+			timeout = TV2MILLISEC( tvp );
+		}
 		do {
 			fd.revents = 0;
 			rc = poll( &fd, 1, timeout );
-		} while( rc == AC_SOCKET_ERROR && errno == EINTR &&
-			LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART ));
+		
+		} while ( rc == AC_SOCKET_ERROR && errno == EINTR &&
+			LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_RESTART ) );
 
-		if( rc == AC_SOCKET_ERROR ) return rc;
+		if ( rc == AC_SOCKET_ERROR ) {
+			return rc;
+		}
 
-		if( fd.revents & POLL_WRITE ) {
-			if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1;
-			if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
-			return ( 0 );
+		if ( timeout == 0 && rc == 0 ) {
+			return -2;
 		}
+
+		if ( fd.revents & POLL_WRITE ) {
+			if ( ldap_pvt_is_socket_ready( ld, s ) == -1 ) {
+				return -1;
+			}
+
+			if ( ldap_pvt_ndelay_off( ld, s ) == -1 ) {
+				return -1;
+			}
+			return 0;
+		}
 	}
 #else
 	{
-		fd_set		wfds, *z=NULL;
+		fd_set		wfds, *z = NULL;
 #ifdef HAVE_WINSOCK
 		fd_set		efds;
 #endif
+		struct timeval	tv = { 0 };
 
 #if defined( FD_SETSIZE ) && !defined( HAVE_WINSOCK )
 		if ( s >= FD_SETSIZE ) {
@@ -301,6 +281,10 @@
 		}
 #endif
 
+		if ( tvp != NULL ) {
+			tv = *tvp;
+		}
+
 		do {
 			FD_ZERO(&wfds);
 			FD_SET(s, &wfds );
@@ -310,50 +294,114 @@
 			FD_SET(s, &efds );
 #endif
 
-			rc = select(ldap_int_tblsize, z, &wfds,
+			rc = select( ldap_int_tblsize, z, &wfds,
 #ifdef HAVE_WINSOCK
 				&efds,
 #else
 				z,
 #endif
-				opt_tv ? &tv : NULL);
-		} while( rc == AC_SOCKET_ERROR && errno == EINTR &&
-			LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART ));
+				tvp ? &tv : NULL );
+		} while ( rc == AC_SOCKET_ERROR && errno == EINTR &&
+			LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_RESTART ) );
 
-		if( rc == AC_SOCKET_ERROR ) return rc;
+		if ( rc == AC_SOCKET_ERROR ) {
+			return rc;
+		}
 
+		if ( rc == 0 && tvp && tvp->tv_sec == 0 && tvp->tv_usec == 0 ) {
+			return -2;
+		}
+
 #ifdef HAVE_WINSOCK
 		/* This means the connection failed */
 		if ( FD_ISSET(s, &efds) ) {
-		    int so_errno;
-		    ber_socklen_t dummy = sizeof(so_errno);
-		    if ( getsockopt( s, SOL_SOCKET, SO_ERROR,
+			int so_errno;
+			ber_socklen_t dummy = sizeof(so_errno);
+			if ( getsockopt( s, SOL_SOCKET, SO_ERROR,
 				(char *) &so_errno, &dummy ) == AC_SOCKET_ERROR || !so_errno )
-		    {
-		    	/* impossible */
-		    	so_errno = WSAGetLastError();
-		    }
-		    ldap_pvt_set_errno(so_errno);
-		    osip_debug(ld, "ldap_pvt_connect: error on socket %d: "
-			       "errno: %d (%s)\n", s, errno, sock_errstr(errno));
-		    return -1;
+			{
+				/* impossible */
+				so_errno = WSAGetLastError();
+			}
+			ldap_pvt_set_errno( so_errno );
+			osip_debug(ld, "ldap_int_poll: error on socket %d: "
+			       "errno: %d (%s)\n", s, errno, sock_errstr( errno ));
+			return -1;
 		}
 #endif
 		if ( FD_ISSET(s, &wfds) ) {
 #ifndef HAVE_WINSOCK
-			if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1;
+			if ( ldap_pvt_is_socket_ready( ld, s ) == -1 ) {
+				return -1;
+			}
 #endif
-			if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
+			if ( ldap_pvt_ndelay_off(ld, s) == -1 ) {
+				return -1;
+			}
 			return 0;
 		}
 	}
 #endif
 
-	osip_debug(ld, "ldap_connect_timeout: timed out\n",0,0,0);
+	osip_debug(ld, "ldap_int_poll: timed out\n",0,0,0);
 	ldap_pvt_set_errno( ETIMEDOUT );
 	return -1;
 }
 
+static int
+ldap_pvt_connect(LDAP *ld, ber_socket_t s,
+	struct sockaddr *sin, ber_socklen_t addrlen,
+	int async)
+{
+	int rc, err;
+	struct timeval	tv, *opt_tv = NULL;
+
+#ifdef LDAP_CONNECTIONLESS
+	/* We could do a connect() but that would interfere with
+	 * attempts to poll a broadcast address
+	 */
+	if (LDAP_IS_UDP(ld)) {
+		if (ld->ld_options.ldo_peer)
+			ldap_memfree(ld->ld_options.ldo_peer);
+		ld->ld_options.ldo_peer=ldap_memalloc(sizeof(struct sockaddr));
+		AC_MEMCPY(ld->ld_options.ldo_peer,sin,sizeof(struct sockaddr));
+		return ( 0 );
+	}
+#endif
+	if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
+		tv = ld->ld_options.ldo_tm_net;
+		opt_tv = &tv;
+	}
+
+	osip_debug(ld, "ldap_pvt_connect: fd: %d tm: %ld async: %d\n",
+			s, opt_tv ? tv.tv_sec : -1L, async);
+
+	if ( opt_tv && ldap_pvt_ndelay_on(ld, s) == -1 )
+		return ( -1 );
+
+	if ( connect(s, sin, addrlen) != AC_SOCKET_ERROR ) {
+		if ( opt_tv && ldap_pvt_ndelay_off(ld, s) == -1 )
+			return ( -1 );
+		return ( 0 );
+	}
+
+	err = sock_errno();
+	if ( err != EINPROGRESS && err != EWOULDBLOCK ) {
+		return ( -1 );
+	}
+	
+	if ( async ) {
+		/* caller will call ldap_int_poll() as appropriate? */
+		return ( -2 );
+	}
+
+	rc = ldap_int_poll( ld, s, opt_tv );
+
+	osip_debug(ld, "ldap_pvt_connect: %d\n", rc, 0, 0);
+
+	return rc;
+}
+
 #ifndef HAVE_INET_ATON
 int
 ldap_pvt_inet_aton( const char *host, struct in_addr *in)
@@ -482,7 +530,7 @@
 
 		rc = ldap_pvt_connect( ld, s,
 			sai->ai_addr, sai->ai_addrlen, async );
-		if ( (rc == 0) || (rc == -2) ) {
+		if ( rc == 0 || rc == -2 ) {
 			ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
 			break;
 		}
@@ -569,8 +617,7 @@
 	return rc;
 }
 
-#if defined( LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND ) || \
-	defined( HAVE_CYRUS_SASL )
+#if defined( HAVE_CYRUS_SASL )
 char *
 ldap_host_connected_to( Sockbuf *sb, const char *host )
 {

Modified: openldap/trunk/libraries/libldap/os-local.c
===================================================================
--- openldap/trunk/libraries/libldap/os-local.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/os-local.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* os-local.c -- platform-specific domain socket code */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/os-local.c,v 1.37.2.9 2007/06/10 18:39:53 hallvard Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/os-local.c,v 1.44.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -154,11 +154,7 @@
 }
 #undef TRACE
 
-#if !defined(HAVE_GETPEEREID) && \
-	!defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && \
-	defined(HAVE_SENDMSG) && (defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTSLEN) || \
-		defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL))
-#define DO_SENDMSG
+#ifdef LDAP_PF_LOCAL_SENDMSG
 static const char abandonPDU[] = {LDAP_TAG_MESSAGE, 6,
 	LDAP_TAG_MSGID, 1, 0, LDAP_REQ_ABANDON, 1, 0};
 #endif
@@ -167,12 +163,11 @@
 ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async)
 {
 	int rc;
-	struct timeval	tv = { 0 },
-			*opt_tv = NULL;
+	struct timeval	tv, *opt_tv = NULL;
 
-	opt_tv = ld->ld_options.ldo_tm_net;
-	if ( opt_tv != NULL ) {
-		tv = *opt_tv;
+	if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
+		tv = ld->ld_options.ldo_tm_net;
+		opt_tv = &tv;
 	}
 
 	oslocal_debug(ld, "ldap_connect_timeout: fd: %d tm: %ld async: %d\n",
@@ -185,14 +180,16 @@
 	{
 		if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
 
-#ifdef DO_SENDMSG
+#ifdef LDAP_PF_LOCAL_SENDMSG
 	/* Send a dummy message with access rights. Remote side will
-	 * obtain our uid/gid by fstat'ing this descriptor.
+	 * obtain our uid/gid by fstat'ing this descriptor. The
+	 * descriptor permissions must match exactly, and we also
+	 * send the socket name, which must also match.
 	 */
 sendcred:
 		{
-#if 0	/* ITS#4893 disable all of this for now */
 			int fds[2];
+			ber_socklen_t salen = sizeof(*sa);
 			if (pipe(fds) == 0) {
 				/* Abandon, noop, has no reply */
 				struct iovec iov;
@@ -231,13 +228,13 @@
 				msg.msg_accrights = (char *)fds;
 				msg.msg_accrightslen = sizeof(int);
 # endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
+				getpeername( s, sa, &salen );
+				fchmod( fds[0], S_ISUID|S_IRWXU );
+				write( fds[1], sa, salen );
 				sendmsg( s, &msg, 0 );
 				close(fds[0]);
 				close(fds[1]);
 			}
-# else
-			write( s, abandonPDU, sizeof( abandonPDU ));
-#endif /* ITS#4893 */
 		}
 #endif
 		return 0;
@@ -270,7 +267,7 @@
 		if( fd.revents & POLL_WRITE ) {
 			if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1;
 			if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
-#ifdef DO_SENDMSG
+#ifdef LDAP_PF_LOCAL_SENDMSG
 			goto sendcred;
 #else
 			return ( 0 );
@@ -301,7 +298,7 @@
 		if ( FD_ISSET(s, &wfds) ) {
 			if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1;
 			if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
-#ifdef DO_SENDMSG
+#ifdef LDAP_PF_LOCAL_SENDMSG
 			goto sendcred;
 #else
 			return ( 0 );

Copied: openldap/trunk/libraries/libldap/pagectrl.c (from rev 891, openldap/vendor/openldap-2.4.7/libraries/libldap/pagectrl.c)
===================================================================
--- openldap/trunk/libraries/libldap/pagectrl.c	                        (rev 0)
+++ openldap/trunk/libraries/libldap/pagectrl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,269 @@
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2007 The OpenLDAP Foundation.
+ * Copyright 2006 Hans Leidekker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+
+/* ---------------------------------------------------------------------------
+    ldap_create_page_control_value
+
+    Create and encode the value of the paged results control (RFC 2696).
+
+    ld          (IN) An LDAP session handle
+    pagesize    (IN) Page size requested
+    cookie      (IN) Opaque structure used by the server to track its
+                     location in the search results.  NULL on the
+                     first call.
+    value      (OUT) Control value, SHOULD be freed by calling
+					 ldap_memfree() when done.
+ 
+    pagedResultsControl ::= SEQUENCE {
+            controlType     1.2.840.113556.1.4.319,
+            criticality     BOOLEAN DEFAULT FALSE,
+            controlValue    searchControlValue }
+
+    searchControlValue ::= SEQUENCE {
+            size            INTEGER (0..maxInt),
+                                    -- requested page size from client
+                                    -- result set size estimate from server
+            cookie          OCTET STRING }
+
+   ---------------------------------------------------------------------------*/
+
+int
+ldap_create_page_control_value(
+	LDAP *ld,
+	ber_int_t pagesize,
+	struct berval	*cookie,
+	struct berval	*value )
+{
+	BerElement	*ber = NULL;
+	ber_tag_t	tag;
+	struct berval	null_cookie = { 0, NULL };
+
+	if ( ld == NULL || value == NULL ||
+		pagesize < 1 || pagesize > LDAP_MAXINT )
+	{
+		if ( ld )
+			ld->ld_errno = LDAP_PARAM_ERROR;
+		return LDAP_PARAM_ERROR;
+	}
+
+	assert( LDAP_VALID( ld ) );
+
+	value->bv_val = NULL;
+	value->bv_len = 0;
+
+	if ( cookie == NULL ) {
+		cookie = &null_cookie;
+	}
+
+	ber = ldap_alloc_ber_with_options( ld );
+	if ( ber == NULL ) {
+		ld->ld_errno = LDAP_NO_MEMORY;
+		return ld->ld_errno;
+	}
+
+	tag = ber_printf( ber, "{iO}", pagesize, cookie );
+	if ( tag == LBER_ERROR ) {
+		ld->ld_errno = LDAP_ENCODING_ERROR;
+		goto done;
+	}
+
+	if ( ber_flatten2( ber, value, 1 ) == -1 ) {
+		ld->ld_errno = LDAP_NO_MEMORY;
+	}
+
+done:;
+	if ( ber != NULL ) {
+		ber_free( ber, 1 );
+	}
+
+	return ld->ld_errno;
+}
+
+
+/* ---------------------------------------------------------------------------
+    ldap_create_page_control
+
+    Create and encode a page control.
+
+    ld          (IN) An LDAP session handle
+    pagesize    (IN) Page size requested
+    cookie      (IN) Opaque structure used by the server to track its
+                     location in the search results.  NULL on the
+                     first call.
+    value      (OUT) Control value, SHOULD be freed by calling
+					 ldap_memfree() when done.
+    iscritical  (IN) Criticality
+    ctrlp      (OUT) LDAP control, SHOULD be freed by calling
+					 ldap_control_free() when done.
+ 
+    pagedResultsControl ::= SEQUENCE {
+            controlType     1.2.840.113556.1.4.319,
+            criticality     BOOLEAN DEFAULT FALSE,
+            controlValue    searchControlValue }
+
+    searchControlValue ::= SEQUENCE {
+            size            INTEGER (0..maxInt),
+                                    -- requested page size from client
+                                    -- result set size estimate from server
+            cookie          OCTET STRING }
+
+   ---------------------------------------------------------------------------*/
+
+int
+ldap_create_page_control(
+	LDAP		*ld,
+	ber_int_t	pagesize,
+	struct berval	*cookie,
+	int		iscritical,
+	LDAPControl	**ctrlp )
+{
+	struct berval	value;
+
+	if ( ctrlp == NULL ) {
+		ld->ld_errno = LDAP_PARAM_ERROR;
+		return ld->ld_errno;
+	}
+
+	ld->ld_errno = ldap_create_page_control_value( ld,
+		pagesize, cookie, &value );
+	if ( ld->ld_errno == LDAP_SUCCESS ) {
+		ld->ld_errno = ldap_control_create( LDAP_CONTROL_PAGEDRESULTS,
+			iscritical, &value, 0, ctrlp );
+		if ( ld->ld_errno != LDAP_SUCCESS ) {
+			LDAP_FREE( value.bv_val );
+		}
+	}
+
+	return ld->ld_errno;
+}
+
+
+/* ---------------------------------------------------------------------------
+    ldap_parse_pageresponse_control
+
+    Decode a page control.
+
+    ld          (IN) An LDAP session handle
+    ctrl        (IN) The page response control
+    count      (OUT) The number of entries in the page.
+    cookie     (OUT) Opaque cookie.  Use ldap_memfree() to
+                     free the bv_val member of this structure.
+
+   ---------------------------------------------------------------------------*/
+
+int
+ldap_parse_pageresponse_control(
+	LDAP *ld,
+	LDAPControl *ctrl,
+	ber_int_t *countp,
+	struct berval *cookie )
+{
+	BerElement *ber;
+	ber_tag_t tag;
+	ber_int_t count;
+
+	if ( ld == NULL || ctrl == NULL || cookie == NULL ) {
+		if ( ld )
+			ld->ld_errno = LDAP_PARAM_ERROR;
+		return LDAP_PARAM_ERROR;
+	}
+
+	/* Create a BerElement from the berval returned in the control. */
+	ber = ber_init( &ctrl->ldctl_value );
+
+	if ( ber == NULL ) {
+		ld->ld_errno = LDAP_NO_MEMORY;
+		return ld->ld_errno;
+	}
+
+	/* Extract the count and cookie from the control. */
+	tag = ber_scanf( ber, "{io}", &count, cookie );
+        ber_free( ber, 1 );
+
+	if ( tag == LBER_ERROR ) {
+		ld->ld_errno = LDAP_DECODING_ERROR;
+	} else {
+		ld->ld_errno = LDAP_SUCCESS;
+
+		if ( countp != NULL ) {
+			*countp = (unsigned long)count;
+		}
+	}
+
+	return ld->ld_errno;
+}
+
+/* ---------------------------------------------------------------------------
+    ldap_parse_page_control
+
+    Decode a page control.
+
+    ld          (IN) An LDAP session handle
+    ctrls       (IN) Response controls
+    count      (OUT) The number of entries in the page.
+    cookie     (OUT) Opaque cookie.  Use ldap_memfree() to
+                     free the bv_val member of this structure.
+
+   ---------------------------------------------------------------------------*/
+
+int
+ldap_parse_page_control(
+	LDAP		*ld,
+	LDAPControl	**ctrls,
+	ber_int_t *countp,
+	struct berval	**cookiep )
+{
+	LDAPControl *c;
+	struct berval	cookie;
+
+	if ( cookiep == NULL ) {
+		ld->ld_errno = LDAP_PARAM_ERROR;
+		return ld->ld_errno;
+	}
+
+	if ( ctrls == NULL ) {
+		ld->ld_errno =  LDAP_CONTROL_NOT_FOUND;
+		return ld->ld_errno;
+	}
+
+	c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
+	if ( c == NULL ) {
+		/* No page control was found. */
+		ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
+		return ld->ld_errno;
+	}
+
+	ld->ld_errno = ldap_parse_pageresponse_control( ld, c, countp, &cookie );
+	if ( ld->ld_errno == LDAP_SUCCESS ) {
+		*cookiep = LDAP_MALLOC( sizeof( struct berval * ) );
+		if ( *cookiep == NULL ) {
+			ld->ld_errno = LDAP_NO_MEMORY;
+		} else {
+			**cookiep = cookie;
+		}
+	}
+
+	return ld->ld_errno;
+}
+

Modified: openldap/trunk/libraries/libldap/passwd.c
===================================================================
--- openldap/trunk/libraries/libldap/passwd.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/passwd.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/passwd.c,v 1.14.2.3 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/passwd.c,v 1.18.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -27,7 +27,7 @@
 #include "ldap-int.h"
 
 /*
- * LDAP Password Modify (Extended) Operation <RFC 3062>
+ * LDAP Password Modify (Extended) Operation (RFC 3062)
  */
 
 int ldap_parse_passwd(
@@ -36,8 +36,7 @@
 	struct berval *newpasswd )
 {
 	int rc;
-	char *retoid = NULL;
-	struct berval *retdata;
+	struct berval *retdata = NULL;
 
 	assert( ld != NULL );
 	assert( LDAP_VALID( ld ) );
@@ -47,31 +46,32 @@
 	newpasswd->bv_val = NULL;
 	newpasswd->bv_len = 0;
 
-	rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 0 );
-
-	if( rc != LDAP_SUCCESS ) {
+	rc = ldap_parse_extended_result( ld, res, NULL, &retdata, 0 );
+	if ( rc != LDAP_SUCCESS ) {
 		return rc;
 	}
 
-	if( retdata != NULL ) {
+	if ( retdata != NULL ) {
 		ber_tag_t tag;
 		BerElement *ber = ber_init( retdata );
 
-		if( ber == NULL ) {
-			ld->ld_errno = LDAP_NO_MEMORY;
-			return ld->ld_errno;
+		if ( ber == NULL ) {
+			rc = ld->ld_errno = LDAP_NO_MEMORY;
+			goto done;
 		}
 
 		/* we should check the tag */
 		tag = ber_scanf( ber, "{o}", newpasswd );
 		ber_free( ber, 1 );
 
-		if( tag == LBER_ERROR ) {
+		if ( tag == LBER_ERROR ) {
 			rc = ld->ld_errno = LDAP_DECODING_ERROR;
 		}
 	}
 
-	ber_memfree( retoid );
+done:;
+	ber_bvfree( retdata );
+
 	return rc;
 }
 
@@ -156,7 +156,7 @@
 		return rc;
 	}
 
-	if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) {
+	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res ) {
 		return ld->ld_errno;
 	}
 

Modified: openldap/trunk/libraries/libldap/ppolicy.c
===================================================================
--- openldap/trunk/libraries/libldap/ppolicy.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/ppolicy.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/ppolicy.c,v 1.3.2.6 2007/08/22 20:44:41 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/ppolicy.c,v 1.11.2.3 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2004-2007 The OpenLDAP Foundation.
@@ -33,7 +33,7 @@
 
 /* IMPLICIT TAGS, all context-specific */
 #define PPOLICY_WARNING 0xa0L	/* constructed + 0 */
-#define PPOLICY_ERROR 0x81L	/* primitive + 1 */
+#define PPOLICY_ERROR 0x81L		/* primitive + 1 */
 
 #define PPOLICY_EXPIRE 0x80L	/* primitive + 0 */
 #define PPOLICY_GRACE  0x81L	/* primitive + 1 */
@@ -65,10 +65,10 @@
 	assert( LDAP_VALID( ld ) );
 	assert( ctrlp != NULL );
 
-	ld->ld_errno = ldap_create_control( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
-		NULL, 0, ctrlp);
+	ld->ld_errno = ldap_control_create( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
+		0, NULL, 0, ctrlp );
 
-	return(ld->ld_errno);
+	return ld->ld_errno;
 }
 
 
@@ -79,9 +79,10 @@
 
    ld           (IN)   An LDAP session handle.
    
-   ctrls        (IN)   The address of an
-					   LDAPControl structure, typically obtained 
-					   by a call to ldap_find_control().
+   ctrl         (IN)   The address of an
+					   LDAPControl structure, either obtained 
+					   by running thorugh the list of response controls or
+					   by a call to ldap_control_find().
 
    exptimep     (OUT)  This result parameter is filled in with the number of seconds before
                                            the password will expire, if expiration is imminent
@@ -118,9 +119,9 @@
 ldap_parse_passwordpolicy_control(
 	LDAP           *ld,
 	LDAPControl    *ctrl,
-        int            *expirep,
-        int            *gracep,
-        LDAPPasswordPolicyError *errorp )
+	ber_int_t      *expirep,
+	ber_int_t      *gracep,
+	LDAPPasswordPolicyError *errorp )
 {
 	BerElement  *ber;
 	int exp = -1, grace = -1;
@@ -141,68 +142,67 @@
 		return(ld->ld_errno);
 	}
 
-        tag = ber_peek_tag( ber, &berLen );
-        if (tag != LBER_SEQUENCE) goto exit;
+	tag = ber_peek_tag( ber, &berLen );
+	if (tag != LBER_SEQUENCE) goto exit;
 
-        for( tag = ber_first_element( ber, &berLen, &last );
-             tag != LBER_DEFAULT;
-             tag = ber_next_element( ber, &berLen, last ) ) {
-            switch (tag) {
-                case PPOLICY_WARNING:
-                    ber_skip_tag(ber, &berLen );
-                    tag = ber_peek_tag( ber, &berLen );
-                    switch( tag ) {
-                        case PPOLICY_EXPIRE:
-                            if (ber_get_int( ber, &exp ) == LBER_DEFAULT) goto exit;
-                            break;
-                        case PPOLICY_GRACE:
-                            if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit;
-                            break;
-                        default:
-                            goto exit;
+	for( tag = ber_first_element( ber, &berLen, &last );
+		tag != LBER_DEFAULT;
+		tag = ber_next_element( ber, &berLen, last ) )
+	{
+		switch (tag) {
+		case PPOLICY_WARNING:
+			ber_skip_tag(ber, &berLen );
+			tag = ber_peek_tag( ber, &berLen );
+			switch( tag ) {
+			case PPOLICY_EXPIRE:
+				if (ber_get_int( ber, &exp ) == LBER_DEFAULT) goto exit;
+				break;
+			case PPOLICY_GRACE:
+				if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit;
+				break;
+			default:
+				goto exit;
+			}
+			break;
+		case PPOLICY_ERROR:
+			if (ber_get_enum( ber, &err ) == LBER_DEFAULT) goto exit;
+			break;
+		default:
+			goto exit;
+		}
+	}
 
-                    }
-                    
-                    break;
-                case PPOLICY_ERROR:
-                    if (ber_get_enum( ber, &err ) == LBER_DEFAULT) goto exit;
-                    break;
-                default:
-                    goto exit;
-            }
-        }
-        
 	ber_free(ber, 1);
 
 	/* Return data to the caller for items that were requested. */
-        if (expirep) *expirep = exp;
-        if (gracep) *gracep = grace;
-        if (errorp) *errorp = err;
+	if (expirep) *expirep = exp;
+	if (gracep) *gracep = grace;
+	if (errorp) *errorp = err;
         
 	ld->ld_errno = LDAP_SUCCESS;
 	return(ld->ld_errno);
 
   exit:
-        ber_free(ber, 1);
-        ld->ld_errno = LDAP_DECODING_ERROR;
-        return(ld->ld_errno);
+	ber_free(ber, 1);
+	ld->ld_errno = LDAP_DECODING_ERROR;
+	return(ld->ld_errno);
 }
 
 const char *
 ldap_passwordpolicy_err2txt( LDAPPasswordPolicyError err )
 {
 	switch(err) {
-		case PP_passwordExpired: return "Password expired";
-		case PP_accountLocked: return "Account locked";
-		case PP_changeAfterReset: return "Password must be changed";
-		case PP_passwordModNotAllowed: return "Policy prevents password modification";
-		case PP_mustSupplyOldPassword: return "Policy requires old password in order to change password";
-		case PP_insufficientPasswordQuality: return "Password fails quality checks";
-		case PP_passwordTooShort: return "Password is too short for policy";
-		case PP_passwordTooYoung: return "Password has been changed too recently";
-		case PP_passwordInHistory: return "New password is in list of old passwords";
-		case PP_noError: return "No error";
-		default: return "Unknown error code";
+	case PP_passwordExpired: return "Password expired";
+	case PP_accountLocked: return "Account locked";
+	case PP_changeAfterReset: return "Password must be changed";
+	case PP_passwordModNotAllowed: return "Policy prevents password modification";
+	case PP_mustSupplyOldPassword: return "Policy requires old password in order to change password";
+	case PP_insufficientPasswordQuality: return "Password fails quality checks";
+	case PP_passwordTooShort: return "Password is too short for policy";
+	case PP_passwordTooYoung: return "Password has been changed too recently";
+	case PP_passwordInHistory: return "New password is in list of old passwords";
+	case PP_noError: return "No error";
+	default: return "Unknown error code";
 	}
 }
 

Modified: openldap/trunk/libraries/libldap/print.c
===================================================================
--- openldap/trunk/libraries/libldap/print.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/print.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/print.c,v 1.14.2.3 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/print.c,v 1.16.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/references.c
===================================================================
--- openldap/trunk/libraries/libldap/references.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/references.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* references.c */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/references.c,v 1.22.2.3 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/references.c,v 1.24.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/request.c
===================================================================
--- openldap/trunk/libraries/libldap/request.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/request.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/request.c,v 1.103.2.19 2007/07/01 12:17:28 hallvard Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/request.c,v 1.125.2.6 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -70,7 +70,8 @@
 {
 	BerElement	*ber;
 
-    if (( ber = ber_alloc_t( ld->ld_lberoptions )) == NULL ) {
+	ber = ber_alloc_t( ld->ld_lberoptions );
+	if ( ber == NULL ) {
 		ld->ld_errno = LDAP_NO_MEMORY;
 	}
 
@@ -148,7 +149,7 @@
 {
 	LDAPConn *lc = lr->lr_conn;
 
-	if ( ber_flush( lc->lconn_sb, lr->lr_ber, 0 ) != 0 ) {
+	if ( ber_flush2( lc->lconn_sb, lr->lr_ber, LBER_FLUSH_FREE_NEVER ) != 0 ) {
 		if ( sock_errno() == EAGAIN ) {
 			/* need to continue write later */
 			lr->lr_status = LDAP_REQST_WRITING;
@@ -180,12 +181,12 @@
 	BerElement *ber,
 	ber_int_t msgid,
 	LDAPRequest *parentreq,
-	LDAPURLDesc *srvlist,
+	LDAPURLDesc **srvlist,
 	LDAPConn *lc,
 	LDAPreqinfo *bind )
 {
 	LDAPRequest	*lr;
-	int incparent, rc;
+	int		incparent, rc;
 
 	Debug( LDAP_DEBUG_TRACE, "ldap_send_server_request\n", 0, 0, 0 );
 
@@ -196,7 +197,7 @@
 		if ( srvlist == NULL ) {
 			lc = ld->ld_defconn;
 		} else {
-			lc = find_connection( ld, srvlist, 1 );
+			lc = find_connection( ld, *srvlist, 1 );
 			if ( lc == NULL ) {
 				if ( (bind != NULL) && (parentreq != NULL) ) {
 					/* Remember the bind in the parent */
@@ -208,11 +209,43 @@
 		}
 	}
 
+	/* async connect... */
+	if ( lc != NULL && lc->lconn_status == LDAP_CONNST_CONNECTING ) {
+		ber_socket_t	sd = AC_SOCKET_ERROR;
+		struct timeval	tv = { 0 };
+
+		ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_GET_FD, &sd );
+
+		/* poll ... */
+		switch ( ldap_int_poll( ld, sd, &tv ) ) {
+		case 0:
+			/* go on! */
+			lc->lconn_status = LDAP_CONNST_CONNECTED;
+			break;
+
+		case -2:
+			/* async only occurs if a network timeout is set */
+
+			/* honor network timeout */
+			if ( time( NULL ) - lc->lconn_created <= ld->ld_options.ldo_tm_net.tv_sec )
+			{
+				/* caller will have to call again */
+				ld->ld_errno = LDAP_X_CONNECTING;
+			}
+			/* fallthru */
+
+		default:
+			/* error */
+			break;
+		}
+	}
+
 	if ( lc == NULL || lc->lconn_status != LDAP_CONNST_CONNECTED ) {
-		ber_free( ber, 1 );
 		if ( ld->ld_errno == LDAP_SUCCESS ) {
 			ld->ld_errno = LDAP_SERVER_DOWN;
 		}
+
+		ber_free( ber, 1 );
 		if ( incparent ) {
 			/* Forget about the bind */
 			--parentreq->lr_outrefcnt; 
@@ -249,7 +282,7 @@
 	}
 	if ( rc ) return rc;
 
-	lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ));
+	lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ) );
 	if ( lr == NULL ) {
 		ld->ld_errno = LDAP_NO_MEMORY;
 		ldap_free_connection( ld, lc, 0, 0 );
@@ -305,7 +338,8 @@
 	}
 
 	lr->lr_prev = NULL;
-	if (( lr->lr_next = ld->ld_requests ) != NULL ) {
+	lr->lr_next = ld->ld_requests;
+	if ( lr->lr_next != NULL ) {
 		lr->lr_next->lr_prev = lr;
 	}
 	ld->ld_requests = lr;
@@ -319,11 +353,11 @@
 }
 
 LDAPConn *
-ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
+ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb,
 	int connect, LDAPreqinfo *bind )
 {
 	LDAPConn	*lc;
-	LDAPURLDesc	*srv;
+	int		async = 0;
 
 	Debug( LDAP_DEBUG_TRACE, "ldap_new_connection %d %d %d\n",
 		use_ldsb, connect, (bind != NULL) );
@@ -351,9 +385,21 @@
 	}
 
 	if ( connect ) {
-		for ( srv = srvlist; srv != NULL; srv = srv->lud_next ) {
-			if ( ldap_int_open_connection( ld, lc, srv, 0 ) != -1 )
-			{
+		LDAPURLDesc	**srvp, *srv = NULL;
+
+		async = LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_CONNECT_ASYNC );
+
+		for ( srvp = srvlist; *srvp != NULL; srvp = &(*srvp)->lud_next ) {
+			int		rc;
+
+			rc = ldap_int_open_connection( ld, lc, *srvp, async );
+			if ( rc != -1 ) {
+				srv = *srvp;
+
+				if ( ld->ld_urllist_proc && ( !async || rc != -2 ) ) {
+					ld->ld_urllist_proc( ld, srvlist, srvp, ld->ld_urllist_params );
+				}
+
 				break;
 			}
 		}
@@ -370,7 +416,7 @@
 		lc->lconn_server = ldap_url_dup( srv );
 	}
 
-	lc->lconn_status = LDAP_CONNST_CONNECTED;
+	lc->lconn_status = async ? LDAP_CONNST_CONNECTING : LDAP_CONNST_CONNECTED;
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex );
 #endif
@@ -380,11 +426,7 @@
 	ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
 #endif
 
-	/*
-	 * XXX for now, we always do a synchronous bind.  This will have
-	 * to change in the long run...
-	 */
-	if ( bind != NULL) {
+	if ( bind != NULL ) {
 		int		err = 0;
 		LDAPConn	*savedefconn;
 
@@ -397,7 +439,7 @@
 		if ( ld->ld_rebind_proc != NULL) {
 			LDAPURLDesc	*srvfunc;
 
-			srvfunc = ldap_url_dup( srvlist );
+			srvfunc = ldap_url_dup( *srvlist );
 			if ( srvfunc == NULL ) {
 				ld->ld_errno = LDAP_NO_MEMORY;
 				err = -1;
@@ -429,6 +471,7 @@
 				}
 				ldap_free_urldesc( srvfunc );
 			}
+
 		} else {
 			int		msgid, rc;
 			struct berval	passwd = BER_BVNULL;
@@ -482,7 +525,7 @@
 							"ldap_new_connection %p: "
 							"unexpected response %d "
 							"from BIND request id=%d\n",
-							(void *)ld, ldap_msgtype( res ), msgid );
+							(void *) ld, ldap_msgtype( res ), msgid );
 						err = -1;
 						break;
 					}
@@ -535,7 +578,7 @@
 			if ( lsu_port == lcu_port
 				&& strcmp( lcu->lud_scheme, lsu->lud_scheme ) == 0
 				&& lcu->lud_host != NULL && *lcu->lud_host != '\0'
-			    && lsu->lud_host != NULL && *lsu->lud_host != '\0'
+				&& lsu->lud_host != NULL && *lsu->lud_host != '\0'
 				&& strcasecmp( lsu->lud_host, lcu->lud_host ) == 0 )
 			{
 				found = 1;
@@ -573,25 +616,12 @@
 		force, unbind, 0 );
 
 	if ( force || --lc->lconn_refcnt <= 0 ) {
-		if ( lc->lconn_status == LDAP_CONNST_CONNECTED ) {
-			ldap_mark_select_clear( ld, lc->lconn_sb );
-			if ( unbind ) {
-				ldap_send_unbind( ld, lc->lconn_sb,
-						NULL, NULL );
-			}
-		}
-
-		if ( lc->lconn_ber != NULL ) {
-			ber_free( lc->lconn_ber, 1 );
-		}
-
-		ldap_int_sasl_close( ld, lc );
-
-		prevlc = NULL;
+		/* remove from connections list first */
 #ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex );
+		ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex );
 #endif
-		for ( tmplc = ld->ld_conns;
+
+		for ( prevlc = NULL, tmplc = ld->ld_conns;
 			tmplc != NULL;
 			tmplc = tmplc->lconn_next )
 		{
@@ -606,16 +636,29 @@
 			prevlc = tmplc;
 		}
 #ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
+		ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
 #endif
-		ldap_free_urllist( lc->lconn_server );
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-		if ( lc->lconn_krbinstance != NULL ) {
-			LDAP_FREE( lc->lconn_krbinstance );
+
+		if ( lc->lconn_status == LDAP_CONNST_CONNECTED ) {
+			ldap_mark_select_clear( ld, lc->lconn_sb );
+			if ( unbind ) {
+				ldap_send_unbind( ld, lc->lconn_sb,
+						NULL, NULL );
+			}
 		}
-#endif
 
-		/* FIXME: is this at all possible? */
+		if ( lc->lconn_ber != NULL ) {
+			ber_free( lc->lconn_ber, 1 );
+		}
+
+		ldap_int_sasl_close( ld, lc );
+
+		ldap_free_urllist( lc->lconn_server );
+
+		/* FIXME: is this at all possible?
+		 * ldap_ld_free() in unbind.c calls ldap_free_connection()
+		 * with force == 1 __after__ explicitly calling
+		 * ldap_free_request() on all requests */
 		if ( force ) {
 			LDAPRequest	*lr;
 
@@ -629,9 +672,11 @@
 				lr = lr_next;
 			}
 		}
+
 		if ( lc->lconn_sb != ld->ld_sb ) {
 			ber_sockbuf_free( lc->lconn_sb );
 		}
+
 		if ( lc->lconn_rebind_queue != NULL) {
 			int i;
 			for( i = 0; lc->lconn_rebind_queue[i] != NULL; i++ ) {
@@ -639,10 +684,13 @@
 			}
 			LDAP_FREE( lc->lconn_rebind_queue );
 		}
+
 		LDAP_FREE( lc );
+
 		Debug( LDAP_DEBUG_TRACE,
 			"ldap_free_connection: actually freed\n",
 			0, 0, 0 );
+
 	} else {
 		lc->lconn_lastused = time( NULL );
 		Debug( LDAP_DEBUG_TRACE, "ldap_free_connection: refcnt %d\n",
@@ -658,37 +706,39 @@
 	LDAPConn	*lc;
    	char		timebuf[32];
 
-	fprintf( stderr, "** ld %p Connection%s:\n", (void *)ld, all ? "s" : "" );
+	Debug( LDAP_DEBUG_TRACE, "** ld %p Connection%s:\n", (void *)ld, all ? "s" : "", 0 );
 	for ( lc = lconns; lc != NULL; lc = lc->lconn_next ) {
 		if ( lc->lconn_server != NULL ) {
-			fprintf( stderr, "* host: %s  port: %d%s\n",
-			    ( lc->lconn_server->lud_host == NULL ) ? "(null)"
-			    : lc->lconn_server->lud_host,
-			    lc->lconn_server->lud_port, ( lc->lconn_sb ==
-			    ld->ld_sb ) ? "  (default)" : "" );
+			Debug( LDAP_DEBUG_TRACE, "* host: %s  port: %d%s\n",
+				( lc->lconn_server->lud_host == NULL ) ? "(null)"
+				: lc->lconn_server->lud_host,
+				lc->lconn_server->lud_port, ( lc->lconn_sb ==
+				ld->ld_sb ) ? "  (default)" : "" );
 		}
-		fprintf( stderr, "  refcnt: %d  status: %s\n", lc->lconn_refcnt,
-		    ( lc->lconn_status == LDAP_CONNST_NEEDSOCKET ) ?
-		    "NeedSocket" : ( lc->lconn_status ==
-		    LDAP_CONNST_CONNECTING ) ? "Connecting" : "Connected" );
-		fprintf( stderr, "  last used: %s",
-		    ldap_pvt_ctime( &lc->lconn_lastused, timebuf ));
-		if( lc->lconn_rebind_inprogress ) {
-			fprintf( stderr, "  rebind in progress\n");
-			if( lc->lconn_rebind_queue != NULL) {
-				int i = 0;
-				for( ;lc->lconn_rebind_queue[i] != NULL; i++) {
-					int j = 0;
-					for( ;lc->lconn_rebind_queue[i][j] != 0; j++) {
-						fprintf( stderr, "    queue %d entry %d - %s\n",
-							i, j, lc->lconn_rebind_queue[i][j]);
+		Debug( LDAP_DEBUG_TRACE, "  refcnt: %d  status: %s\n", lc->lconn_refcnt,
+			( lc->lconn_status == LDAP_CONNST_NEEDSOCKET )
+				? "NeedSocket" :
+				( lc->lconn_status == LDAP_CONNST_CONNECTING )
+					? "Connecting" : "Connected", 0 );
+		Debug( LDAP_DEBUG_TRACE, "  last used: %s%s\n",
+			ldap_pvt_ctime( &lc->lconn_lastused, timebuf ),
+			lc->lconn_rebind_inprogress ? "  rebind in progress" : "", 0 );
+		if ( lc->lconn_rebind_inprogress ) {
+			if ( lc->lconn_rebind_queue != NULL) {
+				int	i;
+
+				for ( i = 0; lc->lconn_rebind_queue[i] != NULL; i++ ) {
+					int	j;
+					for( j = 0; lc->lconn_rebind_queue[i][j] != 0; j++ ) {
+						Debug( LDAP_DEBUG_TRACE, "    queue %d entry %d - %s\n",
+							i, j, lc->lconn_rebind_queue[i][j] );
 					}
 				}
 			} else {
-				fprintf( stderr, "    queue is empty\n");
+				Debug( LDAP_DEBUG_TRACE, "    queue is empty\n", 0, 0, 0 );
 			}
 		}
-		fprintf(stderr, "\n");
+		Debug( LDAP_DEBUG_TRACE, "\n", 0, 0, 0 );
 		if ( !all ) {
 			break;
 		}
@@ -701,57 +751,67 @@
 {
 	LDAPRequest	*lr;
 	LDAPMessage	*lm, *l;
+	int		i;
 
-#ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
-#endif
-	fprintf( stderr, "** ld %p Outstanding Requests:\n", (void *)ld );
-	if (( lr = ld->ld_requests ) == NULL ) {
-		fprintf( stderr, "   Empty\n" );
+	Debug( LDAP_DEBUG_TRACE, "** ld %p Outstanding Requests:\n",
+		(void *)ld, 0, 0 );
+	lr = ld->ld_requests;
+	if ( lr == NULL ) {
+		Debug( LDAP_DEBUG_TRACE, "   Empty\n", 0, 0, 0 );
 	}
-	for ( ; lr != NULL; lr = lr->lr_next ) {
-	    fprintf( stderr, " * msgid %d,  origid %d, status %s\n",
-		lr->lr_msgid, lr->lr_origid,
-		( lr->lr_status == LDAP_REQST_INPROGRESS ) ? "InProgress" :
-		( lr->lr_status == LDAP_REQST_CHASINGREFS ) ? "ChasingRefs" :
-		( lr->lr_status == LDAP_REQST_NOTCONNECTED ) ? "NotConnected" :
-		( lr->lr_status == LDAP_REQST_WRITING) ? "Writing" :
-		( lr->lr_status == LDAP_REQST_COMPLETED ? "RequestCompleted"
-			: "InvalidStatus"));
-	    fprintf( stderr, "   outstanding referrals %d, parent count %d\n",
-		    lr->lr_outrefcnt, lr->lr_parentcnt );
+	for ( i = 0; lr != NULL; lr = lr->lr_next, i++ ) {
+		Debug( LDAP_DEBUG_TRACE, " * msgid %d,  origid %d, status %s\n",
+			lr->lr_msgid, lr->lr_origid,
+			( lr->lr_status == LDAP_REQST_INPROGRESS ) ? "InProgress" :
+			( lr->lr_status == LDAP_REQST_CHASINGREFS ) ? "ChasingRefs" :
+			( lr->lr_status == LDAP_REQST_NOTCONNECTED ) ? "NotConnected" :
+			( lr->lr_status == LDAP_REQST_WRITING ) ? "Writing" :
+			( lr->lr_status == LDAP_REQST_COMPLETED ) ? "RequestCompleted"
+				: "InvalidStatus" );
+		Debug( LDAP_DEBUG_TRACE, "   outstanding referrals %d, parent count %d\n",
+			lr->lr_outrefcnt, lr->lr_parentcnt, 0 );
 	}
-#ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
-#endif
-	fprintf( stderr, "** ld %p Response Queue:\n", (void *)ld );
-	if (( lm = ld->ld_responses ) == NULL ) {
-		fprintf( stderr, "   Empty\n" );
+	Debug( LDAP_DEBUG_TRACE, "  ld %p request count %d (abandoned %lu)\n",
+		(void *)ld, i, ld->ld_nabandoned );
+	Debug( LDAP_DEBUG_TRACE, "** ld %p Response Queue:\n", (void *)ld, 0, 0 );
+	if ( ( lm = ld->ld_responses ) == NULL ) {
+		Debug( LDAP_DEBUG_TRACE, "   Empty\n", 0, 0, 0 );
 	}
-	for ( ; lm != NULL; lm = lm->lm_next ) {
-		fprintf( stderr, " * msgid %d,  type %lu\n",
-		    lm->lm_msgid, (unsigned long) lm->lm_msgtype );
-		if (( l = lm->lm_chain ) != NULL ) {
-			fprintf( stderr, "   chained responses:\n" );
-			for ( ; l != NULL; l = l->lm_chain ) {
-				fprintf( stderr,
-				    "  * msgid %d,  type %lu\n",
-				    l->lm_msgid,
-				    (unsigned long) l->lm_msgtype );
+	for ( i = 0; lm != NULL; lm = lm->lm_next, i++ ) {
+		Debug( LDAP_DEBUG_TRACE, " * msgid %d,  type %lu\n",
+		    lm->lm_msgid, (unsigned long)lm->lm_msgtype, 0 );
+		if ( lm->lm_chain != NULL ) {
+			Debug( LDAP_DEBUG_TRACE, "   chained responses:\n", 0, 0, 0 );
+			for ( l = lm->lm_chain; l != NULL; l = l->lm_chain ) {
+				Debug( LDAP_DEBUG_TRACE,
+					"  * msgid %d,  type %lu\n",
+					l->lm_msgid,
+					(unsigned long)l->lm_msgtype, 0 );
 			}
 		}
 	}
+	Debug( LDAP_DEBUG_TRACE, "  ld %p response count %d\n", (void *)ld, i, 0 );
 }
 #endif /* LDAP_DEBUG */
 
 static void
 ldap_free_request_int( LDAP *ld, LDAPRequest *lr )
 {
+	/* if lr_refcnt > 0, the request has been looked up 
+	 * by ldap_find_request_by_msgid(); if in the meanwhile
+	 * the request is free()'d by someone else, just decrease
+	 * the reference count and extract it from the request
+	 * list; later on, it will be freed. */
 	if ( lr->lr_prev == NULL ) {
-		/* free'ing the first request? */
-		assert( ld->ld_requests == lr );
-		ld->ld_requests = lr->lr_next;
+		if ( lr->lr_refcnt == 0 ) {
+			/* free'ing the first request? */
+			assert( ld->ld_requests == lr );
+		}
 
+		if ( ld->ld_requests == lr ) {
+			ld->ld_requests = lr->lr_next;
+		}
+
 	} else {
 		lr->lr_prev->lr_next = lr->lr_next;
 	}
@@ -760,16 +820,28 @@
 		lr->lr_next->lr_prev = lr->lr_prev;
 	}
 
+	if ( lr->lr_refcnt > 0 ) {
+		lr->lr_refcnt = -lr->lr_refcnt;
+
+		lr->lr_prev = NULL;
+		lr->lr_next = NULL;
+
+		return;
+	}
+
 	if ( lr->lr_ber != NULL ) {
 		ber_free( lr->lr_ber, 1 );
+		lr->lr_ber = NULL;
 	}
 
 	if ( lr->lr_res_error != NULL ) {
 		LDAP_FREE( lr->lr_res_error );
+		lr->lr_res_error = NULL;
 	}
 
 	if ( lr->lr_res_matched != NULL ) {
 		LDAP_FREE( lr->lr_res_matched );
+		lr->lr_res_matched = NULL;
 	}
 
 	LDAP_FREE( lr );
@@ -778,20 +850,29 @@
 void
 ldap_free_request( LDAP *ld, LDAPRequest *lr )
 {
-	LDAPRequest     **ttmplr;
+#ifdef LDAP_R_COMPILE
+	LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_req_mutex );
+#endif
 
 	Debug( LDAP_DEBUG_TRACE, "ldap_free_request (origid %d, msgid %d)\n",
 		lr->lr_origid, lr->lr_msgid, 0 );
 
 	/* free all referrals (child requests) */
-	while ( lr->lr_child )
+	while ( lr->lr_child ) {
 		ldap_free_request( ld, lr->lr_child );
+	}
 
 	if ( lr->lr_parent != NULL ) {
+		LDAPRequest     **lrp;
+
 		--lr->lr_parent->lr_outrefcnt;
-		for ( ttmplr = &lr->lr_parent->lr_child; *ttmplr && *ttmplr != lr; ttmplr = &(*ttmplr)->lr_refnext ); 
-		if ( *ttmplr == lr )  
-			*ttmplr = lr->lr_refnext;
+		for ( lrp = &lr->lr_parent->lr_child;
+			*lrp && *lrp != lr;
+			lrp = &(*lrp)->lr_refnext );
+
+		if ( *lrp == lr ) {
+			*lrp = lr->lr_refnext;
+		}
 	}
 	ldap_free_request_int( ld, lr );
 }
@@ -873,7 +954,7 @@
 		Debug( LDAP_DEBUG_ANY,
 		    "more than %d referral hops (dropping)\n", ld->ld_refhoplimit, 0, 0 );
 		ld->ld_errno = LDAP_REFERRAL_LIMIT_EXCEEDED;
-	    rc = -1;
+		rc = -1;
 		goto done;
 	}
 
@@ -900,8 +981,11 @@
 	{
 
 		/* Parse the referral URL */
-		if (( rc = ldap_url_parse_ext( refarray[i], &srv)) != LDAP_SUCCESS) {
-			ld->ld_errno = rc;
+		rc = ldap_url_parse_ext( refarray[i], &srv, LDAP_PVT_URL_PARSE_NOEMPTY_DN );
+		if ( rc != LDAP_URL_SUCCESS ) {
+			/* ldap_url_parse_ext() returns LDAP_URL_* errors
+			 * which do not map on API errors */
+			ld->ld_errno = LDAP_PARAM_ERROR;
 			rc = -1;
 			goto done;
 		}
@@ -913,12 +997,6 @@
 			goto done;
 		}
 
-		/* treat ldap://hostpart and ldap://hostpart/ the same */
-		if ( srv->lud_dn && srv->lud_dn[0] == '\0' ) {
-			LDAP_FREE( srv->lud_dn );
-			srv->lud_dn = NULL;
-		}
-
 		/* check connection for re-bind in progress */
 		if (( lc = find_connection( ld, srv, 1 )) != NULL ) {
 			/* See if we've already requested this DN with this conn */
@@ -926,14 +1004,13 @@
 			int looped = 0;
 			int len = srv->lud_dn ? strlen( srv->lud_dn ) : 0;
 			for ( lp = origreq; lp; ) {
-				if ( lp->lr_conn == lc ) {
-					if ( len == lp->lr_dn.bv_len
-						&& len
-						&& strncmp( srv->lud_dn, lp->lr_dn.bv_val, len ) == 0 )
-					{
-						looped = 1;
-						break;
-					}
+				if ( lp->lr_conn == lc
+					&& len == lp->lr_dn.bv_len
+					&& len
+					&& strncmp( srv->lud_dn, lp->lr_dn.bv_val, len ) == 0 )
+				{
+					looped = 1;
+					break;
 				}
 				if ( lp == origreq ) {
 					lp = lp->lr_child;
@@ -1033,7 +1110,7 @@
 		ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
 #endif
 		rc = ldap_send_server_request( ld, ber, id,
-			origreq, srv, NULL, &rinfo );
+			origreq, &srv, NULL, &rinfo );
 #ifdef LDAP_R_COMPILE
 		ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
 #endif
@@ -1165,21 +1242,16 @@
 			*p++ = '\0';
 		}
 
-		rc = ldap_url_parse_ext( ref, &srv );
-
+		rc = ldap_url_parse_ext( ref, &srv, LDAP_PVT_URL_PARSE_NOEMPTY_DN );
 		if ( rc != LDAP_URL_SUCCESS ) {
 			Debug( LDAP_DEBUG_TRACE,
-			    "ignoring unknown referral <%s>\n", ref, 0, 0 );
+				"ignoring %s referral <%s>\n",
+				ref, rc == LDAP_URL_ERR_BADSCHEME ? "unknown" : "incorrect", 0 );
 			rc = ldap_append_referral( ld, &unfollowed, ref );
 			*hadrefp = 1;
 			continue;
 		}
 
-		if ( srv->lud_dn != NULL && srv->lud_dn == '\0' ) {
-			LDAP_FREE( srv->lud_dn );
-			srv->lud_dn = NULL;
-		}
-
 		Debug( LDAP_DEBUG_TRACE,
 		    "chasing LDAP referral: <%s>\n", ref, 0, 0 );
 
@@ -1190,19 +1262,18 @@
 			LDAPRequest *lp;
 			int looped = 0;
 			int len = srv->lud_dn ? strlen( srv->lud_dn ) : 0;
-			for (lp = lr; lp; lp = lp->lr_parent ) {
-				if ( lp->lr_conn == lc ) {
-					if ( len == lp->lr_dn.bv_len ) {
-						if ( len && strncmp( srv->lud_dn, lp->lr_dn.bv_val,
-							len ))
+			for ( lp = lr; lp; lp = lp->lr_parent ) {
+				if ( lp->lr_conn == lc
+					&& len == lp->lr_dn.bv_len )
+				{
+					if ( len && strncmp( srv->lud_dn, lp->lr_dn.bv_val, len ) )
 							continue;
-						looped = 1;
-						break;
-					}
+					looped = 1;
+					break;
 				}
 			}
 			if ( looped ) {
-				ldap_free_urllist(srv);
+				ldap_free_urllist( srv );
 				ld->ld_errno = LDAP_CLIENT_LOOP;
 				rc = -1;
 				continue;
@@ -1226,7 +1297,7 @@
 		ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
 #endif
 		rc = ldap_send_server_request( ld, ber, id,
-			lr, srv, NULL, &rinfo );
+			lr, &srv, NULL, &rinfo );
 #ifdef LDAP_R_COMPILE
 		ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
 #endif
@@ -1355,9 +1426,7 @@
 				scope = LDAP_SCOPE_BASE;
 				break;
 			case LDAP_SCOPE_SUBTREE:
-#ifdef LDAP_SCOPE_SUBORDINATE
 			case LDAP_SCOPE_SUBORDINATE:
-#endif
 				scope = LDAP_SCOPE_SUBTREE;
 				break;
 			}
@@ -1431,10 +1500,11 @@
 	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
 #endif
 	for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
-		if( lr->lr_status == LDAP_REQST_COMPLETED ) {
+		if ( lr->lr_status == LDAP_REQST_COMPLETED ) {
 			continue;	/* Skip completed requests */
 		}
 		if ( msgid == lr->lr_msgid ) {
+			lr->lr_refcnt++;
 			break;
 		}
 	}
@@ -1445,4 +1515,35 @@
 	return( lr );
 }
 
+void
+ldap_return_request( LDAP *ld, LDAPRequest *lrx, int freeit )
+{
+	LDAPRequest	*lr;
 
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
+	for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
+		if ( lr == lrx ) {
+			if ( lr->lr_refcnt > 0 ) {
+				lr->lr_refcnt--;
+
+			} else if ( lr->lr_refcnt < 0 ) {
+				lr->lr_refcnt++;
+				if ( lr->lr_refcnt == 0 ) {
+					lr = NULL;
+				}
+			}
+			break;
+		}
+	}
+	if ( lr == NULL ) {
+		ldap_free_request_int( ld, lrx );
+
+	} else if ( freeit ) {
+		ldap_free_request( ld, lrx );
+	}
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
+}

Modified: openldap/trunk/libraries/libldap/result.c
===================================================================
--- openldap/trunk/libraries/libldap/result.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/result.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* result.c - wait for an ldap result */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.99.2.23 2007/03/13 08:53:15 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.124.2.8 2007/10/17 20:14:11 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -37,20 +37,17 @@
  * can be found in the file "build/LICENSE-2.0.1" in this distribution
  * of OpenLDAP Software.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
 /*
- * LDAPv3 (RFC2251)
+ * LDAPv3 (RFC 4511)
  *	LDAPResult ::= SEQUENCE {
- *		resultCode		ENUMERATED { ... },
- *		matchedDN		LDAPDN,
- *		errorMessage	LDAPString,
- *		referral		Referral OPTIONAL
+ *		resultCode			ENUMERATED { ... },
+ *		matchedDN			LDAPDN,
+ *		diagnosticMessage		LDAPString,
+ *		referral			[3] Referral OPTIONAL
  *	}
  *	Referral ::= SEQUENCE OF LDAPURL	(one or more)
- *	LDAPURL ::= LDAPString				(limited to URL chars)
+ *	LDAPURL ::= LDAPString			(limited to URL chars)
  */
 
 #include "portable.h"
@@ -67,9 +64,10 @@
 
 #include "ldap-int.h"
 #include "ldap_log.h"
+#include "lutil.h"
 
-static int ldap_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid ));
-static int ldap_mark_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid ));
+static int ldap_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid, int *idx ));
+static int ldap_mark_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid, int idx ));
 static int wait4msg LDAP_P(( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout,
 	LDAPMessage **result ));
 static ber_tag_t try_read1msg LDAP_P(( LDAP *ld, ber_int_t msgid,
@@ -94,7 +92,8 @@
  * search references, followed by an ldap result).  An extension to
  * LDAPv3 allows partial extended responses to be returned in response
  * to any request.  The type of the first message received is returned.
- * When waiting, any messages that have been abandoned are discarded.
+ * When waiting, any messages that have been abandoned/discarded are 
+ * discarded.
  *
  * Example:
  *	ldap_result( s, msgid, all, timeout, result )
@@ -107,8 +106,8 @@
 	struct timeval *timeout,
 	LDAPMessage **result )
 {
-	LDAPMessage	*lm;
-	int	rc;
+	LDAPMessage	*lm = NULL;
+	int		rc;
 
 	assert( ld != NULL );
 	assert( result != NULL );
@@ -118,19 +117,26 @@
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
 #endif
-	lm = chkResponseList(ld, msgid, all);
 
+#if 0
+	/* this is already done inside wait4msg(), right?... */
+	lm = chkResponseList( ld, msgid, all );
+#endif
+
 	if ( lm == NULL ) {
 		rc = wait4msg( ld, msgid, all, timeout, result );
+
 	} else {
 		*result = lm;
 		ld->ld_errno = LDAP_SUCCESS;
 		rc = lm->lm_msgtype;
 	}
+
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
 #endif
-	return( rc );
+
+	return rc;
 }
 
 static LDAPMessage *
@@ -140,26 +146,49 @@
 	int all)
 {
 	LDAPMessage	*lm, **lastlm, *nextlm;
-    /*
+	int		cnt = 0;
+
+	/*
 	 * Look through the list of responses we have received on
 	 * this association and see if the response we're interested in
 	 * is there.  If it is, return it.  If not, call wait4msg() to
 	 * wait until it arrives or timeout occurs.
 	 */
 
+#ifdef LDAP_R_COMPILE
+	LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );
+#endif
+
 	Debug( LDAP_DEBUG_TRACE,
 		"ldap_chkResponseList ld %p msgid %d all %d\n",
 		(void *)ld, msgid, all );
+
 	lastlm = &ld->ld_responses;
 	for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) {
+		int	idx;
+
 		nextlm = lm->lm_next;
+		++cnt;
 
-		if ( ldap_abandoned( ld, lm->lm_msgid ) ) {
-			Debug( LDAP_DEBUG_TRACE,
-				"ldap_chkResponseList msg abandoned, msgid %d\n",
-			    msgid, 0, 0 );
-			ldap_mark_abandoned( ld, lm->lm_msgid );
+		if ( ldap_abandoned( ld, lm->lm_msgid, &idx ) ) {
+			Debug( LDAP_DEBUG_ANY,
+				"response list msg abandoned, "
+				"msgid %d message type %s\n",
+				lm->lm_msgid, ldap_int_msgtype2str( lm->lm_msgtype ), 0 );
 
+			switch ( lm->lm_msgtype ) {
+			case LDAP_RES_SEARCH_ENTRY:
+			case LDAP_RES_SEARCH_REFERENCE:
+			case LDAP_RES_INTERMEDIATE:
+				break;
+
+			default:
+				/* there's no need to keep the id
+				 * in the abandoned list any longer */
+				ldap_mark_abandoned( ld, lm->lm_msgid, idx );
+				break;
+			}
+
 			/* Remove this entry from list */
 			*lastlm = nextlm;
 
@@ -171,15 +200,18 @@
 		if ( msgid == LDAP_RES_ANY || lm->lm_msgid == msgid ) {
 			LDAPMessage	*tmp;
 
-			if ( all == LDAP_MSG_ONE || all == LDAP_MSG_RECEIVED ||
-				msgid == LDAP_RES_UNSOLICITED ) {
+			if ( all == LDAP_MSG_ONE ||
+				all == LDAP_MSG_RECEIVED ||
+				msgid == LDAP_RES_UNSOLICITED )
+			{
 				break;
 			}
 
 			tmp = lm->lm_chain_tail;
-			if ((tmp->lm_msgtype == LDAP_RES_SEARCH_ENTRY) ||
-				(tmp->lm_msgtype == LDAP_RES_SEARCH_REFERENCE) ||
-				(tmp->lm_msgtype == LDAP_RES_INTERMEDIATE)) {
+			if ( tmp->lm_msgtype == LDAP_RES_SEARCH_ENTRY ||
+				tmp->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ||
+				tmp->lm_msgtype == LDAP_RES_INTERMEDIATE )
+			{
 				tmp = NULL;
 			}
 
@@ -192,31 +224,32 @@
 		lastlm = &lm->lm_next;
 	}
 
-    if ( lm != NULL ) {
+	if ( lm != NULL ) {
 		/* Found an entry, remove it from the list */
-	    if ( all == LDAP_MSG_ONE && lm->lm_chain != NULL ) {
+		if ( all == LDAP_MSG_ONE && lm->lm_chain != NULL ) {
 			*lastlm = lm->lm_chain;
 			lm->lm_chain->lm_next = lm->lm_next;
 			lm->lm_chain->lm_chain_tail = ( lm->lm_chain_tail != lm ) ? lm->lm_chain_tail : lm->lm_chain;
 			lm->lm_chain = NULL;
 			lm->lm_chain_tail = NULL;
-	    } else {
+		} else {
 			*lastlm = lm->lm_next;
 		}
-	    lm->lm_next = NULL;
-    }
+		lm->lm_next = NULL;
+	}
 
 #ifdef LDAP_DEBUG
-	if( lm == NULL) {
+	if ( lm == NULL) {
 		Debug( LDAP_DEBUG_TRACE,
 			"ldap_chkResponseList returns ld %p NULL\n", (void *)ld, 0, 0);
 	} else {
 		Debug( LDAP_DEBUG_TRACE,
-			"ldap_chkResponseList returns ld %p msgid %d, type 0x%02lu\n",
-			(void *)ld, lm->lm_msgid, (unsigned long) lm->lm_msgtype);
+			"ldap_chkResponseList returns ld %p msgid %d, type 0x%02lx\n",
+			(void *)ld, lm->lm_msgid, (unsigned long)lm->lm_msgtype );
 	}
 #endif
-    return lm;
+
+	return lm;
 }
 
 static int
@@ -230,14 +263,22 @@
 	int		rc;
 	struct timeval	tv = { 0 },
 			tv0 = { 0 },
-			*tvp;
-	time_t		start_time = 0;
-	time_t		tmp_time;
+			start_time_tv = { 0 },
+			*tvp = NULL;
 	LDAPConn	*lc;
 
 	assert( ld != NULL );
 	assert( result != NULL );
 
+#ifdef LDAP_R_COMPILE
+	LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );
+#endif
+
+	if ( timeout == NULL && ld->ld_options.ldo_tm_api.tv_sec >= 0 ) {
+		tv = ld->ld_options.ldo_tm_api;
+		timeout = &tv;
+	}
+
 #ifdef LDAP_DEBUG
 	if ( timeout == NULL ) {
 		Debug( LDAP_DEBUG_TRACE, "wait4msg ld %p msgid %d (infinite timeout)\n",
@@ -248,13 +289,16 @@
 	}
 #endif /* LDAP_DEBUG */
 
-	if ( timeout == NULL ) {
-		tvp = NULL;
-	} else {
+	if ( timeout != NULL ) {
 		tv0 = *timeout;
 		tv = *timeout;
 		tvp = &tv;
-		start_time = time( NULL );
+#ifdef HAVE_GETTIMEOFDAY
+		gettimeofday( &start_time_tv, NULL );
+#else /* ! HAVE_GETTIMEOFDAY */
+		time( &start_time_tv.tv_sec );
+		start_time_tv.tv_usec = 0;
+#endif /* ! HAVE_GETTIMEOFDAY */
 	}
 		    
 	rc = LDAP_MSG_X_KEEP_LOOKING;
@@ -263,12 +307,22 @@
 		if ( ldap_debug & LDAP_DEBUG_TRACE ) {
 			Debug( LDAP_DEBUG_TRACE, "wait4msg continue ld %p msgid %d all %d\n",
 				(void *)ld, msgid, all );
+#ifdef LDAP_R_COMPILE
+			ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex );
+#endif
 			ldap_dump_connection( ld, ld->ld_conns, 1 );
+#ifdef LDAP_R_COMPILE
+			ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
+			ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
 			ldap_dump_requests_and_responses( ld );
+#ifdef LDAP_R_COMPILE
+			ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
 		}
 #endif /* LDAP_DEBUG */
 
-        	if ( (*result = chkResponseList(ld, msgid, all)) != NULL ) {
+        	if ( ( *result = chkResponseList( ld, msgid, all ) ) != NULL ) {
 			rc = (*result)->lm_msgtype;
 
 		} else {
@@ -279,7 +333,8 @@
 #endif
 			for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {
 				if ( ber_sockbuf_ctrl( lc->lconn_sb,
-						LBER_SB_OPT_DATA_READY, NULL ) ) {
+					LBER_SB_OPT_DATA_READY, NULL ) )
+				{
 #ifdef LDAP_R_COMPILE
 					ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
 #endif
@@ -307,7 +362,7 @@
 
 				if ( rc == 0 || ( rc == -1 && (
 					!LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART)
-						|| sock_errno() != EINTR )))
+						|| sock_errno() != EINTR ) ) )
 				{
 					ld->ld_errno = (rc == -1 ? LDAP_SERVER_DOWN :
 						LDAP_TIMEOUT);
@@ -316,6 +371,7 @@
 
 				if ( rc == -1 ) {
 					rc = LDAP_MSG_X_KEEP_LOOKING;	/* select interrupted: loop */
+
 				} else {
 					rc = LDAP_MSG_X_KEEP_LOOKING;
 #ifdef LDAP_R_COMPILE
@@ -336,7 +392,7 @@
 						rc == LDAP_MSG_X_KEEP_LOOKING && lc != NULL; )
 					{
 						if ( lc->lconn_status == LDAP_CONNST_CONNECTED &&
-							ldap_is_read_ready( ld, lc->lconn_sb ))
+							ldap_is_read_ready( ld, lc->lconn_sb ) )
 						{
 #ifdef LDAP_R_COMPILE
 							ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
@@ -369,23 +425,49 @@
 		}
 
 		if ( rc == LDAP_MSG_X_KEEP_LOOKING && tvp != NULL ) {
-			time_t	delta_time;
+			struct timeval	curr_time_tv = { 0 },
+					delta_time_tv = { 0 };
 
-			tmp_time = time( NULL );
-			delta_time = tmp_time - start_time;
+#ifdef HAVE_GETTIMEOFDAY
+			gettimeofday( &curr_time_tv, NULL );
+#else /* ! HAVE_GETTIMEOFDAY */
+			time( &curr_time_tv.tv_sec );
+			curr_time_tv.tv_usec = 0;
+#endif /* ! HAVE_GETTIMEOFDAY */
 
-			/* do not assume time_t is signed */
-			if ( tv0.tv_sec <= delta_time ) {
-				rc = 0;	/* timed out */
+			/* delta_time = tmp_time - start_time */
+			delta_time_tv.tv_sec = curr_time_tv.tv_sec - start_time_tv.tv_sec;
+			delta_time_tv.tv_usec = curr_time_tv.tv_usec - start_time_tv.tv_usec;
+			if ( delta_time_tv.tv_usec < 0 ) {
+				delta_time_tv.tv_sec--;
+				delta_time_tv.tv_usec += 1000000;
+			}
+
+			/* tv0 < delta_time ? */
+			if ( ( tv0.tv_sec < delta_time_tv.tv_sec ) ||
+			     ( ( tv0.tv_sec == delta_time_tv.tv_sec ) && ( tv0.tv_usec < delta_time_tv.tv_usec ) ) )
+			{
+				rc = 0; /* timed out */
 				ld->ld_errno = LDAP_TIMEOUT;
 				break;
 			}
-			tv0.tv_sec -= delta_time;
+
+			/* tv0 -= delta_time */
+			tv0.tv_sec -= delta_time_tv.tv_sec;
+			tv0.tv_usec -= delta_time_tv.tv_usec;
+			if ( tv0.tv_usec < 0 ) {
+				tv0.tv_sec--;
+				tv0.tv_usec += 1000000;
+			}
+
 			tv.tv_sec = tv0.tv_sec;
+			tv.tv_usec = tv0.tv_usec;
 
-			Debug( LDAP_DEBUG_TRACE, "wait4msg ld %p %ld secs to go\n",
-				(void *)ld, (long) tv.tv_sec, 0 );
-			start_time = tmp_time;
+			Debug( LDAP_DEBUG_TRACE, "wait4msg ld %p %ld s %ld us to go\n",
+				(void *)ld, (long) tv.tv_sec, (long) tv.tv_usec );
+
+			start_time_tv.tv_sec = curr_time_tv.tv_sec;
+			start_time_tv.tv_usec = curr_time_tv.tv_usec;
 		}
 	}
 
@@ -404,10 +486,11 @@
 	BerElement	*ber;
 	LDAPMessage	*newmsg, *l, *prev;
 	ber_int_t	id;
+	int		idx;
 	ber_tag_t	tag;
 	ber_len_t	len;
 	int		foundit = 0;
-	LDAPRequest	*lr, *tmplr;
+	LDAPRequest	*lr, *tmplr, dummy_lr = { 0 };
 	LDAPConn	*lc;
 	BerElement	tmpber;
 	int		rc, refer_cnt, hadref, simple_request;
@@ -418,20 +501,14 @@
 	int		moremsgs = 0, isv2 = 0;
 #endif
 
-	/*
-	 * v3ref = flag for V3 referral / search reference
-	 * 0 = not a ref, 1 = sucessfully chased ref, -1 = pass ref to application
-	 */
-	enum {
-		V3REF_NOREF	= 0,
-		V3REF_SUCCESS	= 1,
-		V3REF_TOAPP	= -1
-	}	v3ref;
-
 	assert( ld != NULL );
 	assert( lcp != NULL );
 	assert( *lcp != NULL );
 	
+#ifdef LDAP_R_COMPILE
+	LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );
+#endif
+
 	Debug( LDAP_DEBUG_TRACE, "read1msg: ld %p msgid %d all %d\n",
 		(void *)ld, msgid, all );
 
@@ -439,9 +516,9 @@
 
 retry:
 	if ( lc->lconn_ber == NULL ) {
-		lc->lconn_ber = ldap_alloc_ber_with_options(ld);
+		lc->lconn_ber = ldap_alloc_ber_with_options( ld );
 
-		if( lc->lconn_ber == NULL ) {
+		if ( lc->lconn_ber == NULL ) {
 			return -1;
 		}
 	}
@@ -455,33 +532,43 @@
 	if ( LDAP_IS_UDP(ld) ) {
 		struct sockaddr from;
 		ber_int_sb_read( lc->lconn_sb, &from, sizeof(struct sockaddr) );
-		if (ld->ld_options.ldo_version == LDAP_VERSION2) isv2=1;
+		if ( ld->ld_options.ldo_version == LDAP_VERSION2 ) isv2 = 1;
 	}
 nextresp3:
 #endif
 	tag = ber_get_next( lc->lconn_sb, &len, ber );
-	if ( tag == LDAP_TAG_MESSAGE ) {
+	switch ( tag ) {
+	case LDAP_TAG_MESSAGE:
 		/*
 	 	 * We read a complete message.
 	 	 * The connection should no longer need this ber.
 	 	 */
 		lc->lconn_ber = NULL;
-	}
-	if ( tag != LDAP_TAG_MESSAGE ) {
-		if ( tag == LBER_DEFAULT) {
+		break;
+
+	case LBER_DEFAULT:
 #ifdef LDAP_DEBUG		   
-			Debug( LDAP_DEBUG_CONNS,
-				"ber_get_next failed.\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_CONNS,
+			"ber_get_next failed.\n", 0, 0, 0 );
 #endif		   
 #ifdef EWOULDBLOCK			
-			if ( sock_errno() == EWOULDBLOCK ) return LDAP_MSG_X_KEEP_LOOKING;
+		if ( sock_errno() == EWOULDBLOCK ) return LDAP_MSG_X_KEEP_LOOKING;
 #endif
 #ifdef EAGAIN
-			if ( sock_errno() == EAGAIN ) return LDAP_MSG_X_KEEP_LOOKING;
+		if ( sock_errno() == EAGAIN ) return LDAP_MSG_X_KEEP_LOOKING;
 #endif
-			ld->ld_errno = LDAP_SERVER_DOWN;
-			return -1;
-		}
+		ld->ld_errno = LDAP_SERVER_DOWN;
+#ifdef LDAP_R_COMPILE
+		ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
+		ldap_free_connection( ld, lc, 1, 0 );
+#ifdef LDAP_R_COMPILE
+		ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
+		lc = *lcp = NULL;
+		return -1;
+
+	default:
 		ld->ld_errno = LDAP_LOCAL_ERROR;
 		return -1;
 	}
@@ -493,33 +580,72 @@
 		return( -1 );
 	}
 
+	/* id == 0 iff unsolicited notification message (RFC 4511) */
+
 	/* if it's been abandoned, toss it */
-	if ( ldap_abandoned( ld, id ) ) {
-		Debug( LDAP_DEBUG_ANY, "abandoned ld %p msgid %ld\n",
-			(void *)ld, (long) id, 0);
+	if ( id > 0 ) {
+		if ( ldap_abandoned( ld, id, &idx ) ) {
+			/* the message type */
+			tag = ber_peek_tag( ber, &len );
+			switch ( tag ) {
+			case LDAP_RES_SEARCH_ENTRY:
+			case LDAP_RES_SEARCH_REFERENCE:
+			case LDAP_RES_INTERMEDIATE:
+			case LBER_ERROR:
+				break;
+
+			default:
+				/* there's no need to keep the id
+				 * in the abandoned list any longer */
+				ldap_mark_abandoned( ld, id, idx );
+				break;
+			}
+
+			Debug( LDAP_DEBUG_ANY,
+				"abandoned/discarded ld %p msgid %ld message type %s\n",
+				(void *)ld, (long)id, ldap_int_msgtype2str( tag ) );
+
 retry_ber:
-		ber_free( ber, 1 );
-		if ( ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_DATA_READY, NULL ) ) {
-			goto retry;
+			ber_free( ber, 1 );
+			if ( ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_DATA_READY, NULL ) ) {
+				goto retry;
+			}
+			return( LDAP_MSG_X_KEEP_LOOKING );	/* continue looking */
 		}
-		return( LDAP_MSG_X_KEEP_LOOKING );	/* continue looking */
-	}
 
-	lr = ldap_find_request_by_msgid( ld, id );
-	if ( lr == NULL ) {
-		Debug( LDAP_DEBUG_ANY,
-			"no request for response on ld %p msgid %ld (tossing)\n",
-			(void *)ld, (long) id, 0 );
-		goto retry_ber;
-	}
+		lr = ldap_find_request_by_msgid( ld, id );
+		if ( lr == NULL ) {
+			const char	*msg = "unknown";
+
+			/* the message type */
+			tag = ber_peek_tag( ber, &len );
+			switch ( tag ) {
+			case LBER_ERROR:
+				break;
+
+			default:
+				msg = ldap_int_msgtype2str( tag );
+				break;
+			}
+
+			Debug( LDAP_DEBUG_ANY,
+				"no request for response on ld %p msgid %ld message type %s (tossing)\n",
+				(void *)ld, (long)id, msg );
+
+			goto retry_ber;
+		}
+
 #ifdef LDAP_CONNECTIONLESS
-	if (LDAP_IS_UDP(ld) && isv2) {
-		ber_scanf(ber, "x{");
-	}
+		if ( LDAP_IS_UDP(ld) && isv2 ) {
+			ber_scanf(ber, "x{");
+		}
 nextresp2:
 #endif
+	}
+
 	/* the message type */
-	if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
+	tag = ber_peek_tag( ber, &len );
+	if ( tag == LBER_ERROR ) {
 		ld->ld_errno = LDAP_DECODING_ERROR;
 		ber_free( ber, 1 );
 		return( -1 );
@@ -527,8 +653,46 @@
 
 	Debug( LDAP_DEBUG_TRACE,
 		"read1msg: ld %p msgid %ld message type %s\n",
-		(void *)ld, (long) lr->lr_msgid, ldap_int_msgtype2str( tag ));
+		(void *)ld, (long)lr->lr_msgid, ldap_int_msgtype2str( tag ) );
 
+	if ( id == 0 ) {
+		/* unsolicited notification message (RFC 4511) */
+		if ( tag != LDAP_RES_EXTENDED ) {
+			/* toss it */
+			goto retry_ber;
+
+			/* strictly speaking, it's an error; from RFC 4511:
+
+4.4.  Unsolicited Notification
+
+   An unsolicited notification is an LDAPMessage sent from the server to
+   the client that is not in response to any LDAPMessage received by the
+   server.  It is used to signal an extraordinary condition in the
+   server or in the LDAP session between the client and the server.  The
+   notification is of an advisory nature, and the server will not expect
+   any response to be returned from the client.
+
+   The unsolicited notification is structured as an LDAPMessage in which
+   the messageID is zero and protocolOp is set to the extendedResp
+   choice using the ExtendedResponse type (See Section 4.12).  The
+   responseName field of the ExtendedResponse always contains an LDAPOID
+   that is unique for this notification.
+
+			 * however, since unsolicited responses
+			 * are of advisory nature, better
+			 * toss it, right now
+			 */
+
+#if 0
+			ld->ld_errno = LDAP_DECODING_ERROR;
+			ber_free( ber, 1 );
+			return( -1 );
+#endif
+		}
+
+		lr = &dummy_lr;
+	}
+
 	id = lr->lr_origid;
 	refer_cnt = 0;
 	hadref = simple_request = 0;
@@ -536,230 +700,151 @@
 	lr->lr_res_msgtype = tag;
 
 	/*
-	 * This code figures out if we are going to chase a
-	 * referral / search reference, or pass it back to the application
+	 * Check for V3 search reference
 	 */
-	v3ref = V3REF_NOREF;	/* Assume not a V3 search reference/referral */
-	if( (tag != LDAP_RES_SEARCH_ENTRY) && (ld->ld_version > LDAP_VERSION2) ) {
-		BerElement	tmpber = *ber; 	/* struct copy */
-		char **refs = NULL;
-
-		if( tag == LDAP_RES_SEARCH_REFERENCE ) {
+	if ( tag == LDAP_RES_SEARCH_REFERENCE ) {
+		if ( ld->ld_version > LDAP_VERSION2 ) {
 			/* This is a V3 search reference */
-			/* Assume we do not chase the reference,
-			 * but pass it to application */
-			v3ref = V3REF_TOAPP;
-			if( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) ||
-					(lr->lr_parent != NULL) )
+			if ( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) ||
+					lr->lr_parent != NULL )
 			{
+				char **refs = NULL;
+				tmpber = *ber;
+
 				/* Get the referral list */
 				if ( ber_scanf( &tmpber, "{v}", &refs ) == LBER_ERROR ) {
 					rc = LDAP_DECODING_ERROR;
+
 				} else {
 					/* Note: refs array is freed by ldap_chase_v3referrals */
 					refer_cnt = ldap_chase_v3referrals( ld, lr, refs,
-					    1, &lr->lr_res_error, &hadref );
+						1, &lr->lr_res_error, &hadref );
 					if ( refer_cnt > 0 ) {
-						/* sucessfully chased reference */
+						/* successfully chased reference */
 						/* If haven't got end search, set chasing referrals */
-						if( lr->lr_status != LDAP_REQST_COMPLETED) {
+						if ( lr->lr_status != LDAP_REQST_COMPLETED ) {
 							lr->lr_status = LDAP_REQST_CHASINGREFS;
 							Debug( LDAP_DEBUG_TRACE,
 								"read1msg:  search ref chased, "
 								"mark request chasing refs, "
 								"id = %d\n",
-								lr->lr_msgid, 0, 0);
+								lr->lr_msgid, 0, 0 );
 						}
-
-						/* We successfully chased the reference */
-						v3ref = V3REF_SUCCESS;
 					}
 				}
 			}
-		} else {
-			/* Check for V3 referral */
-			ber_len_t	len;
-			char		*lr_res_error = NULL;
+		}
 
-#ifdef LDAP_NULL_IS_NULL
-			if ( ber_scanf( &tmpber, "{eAA",/*}*/ &lderr,
-				    &lr->lr_res_matched, &lr_res_error )
-				    != LBER_ERROR )
-#else /* ! LDAP_NULL_IS_NULL */
-			if ( ber_scanf( &tmpber, "{eaa",/*}*/ &lderr,
-				    &lr->lr_res_matched, &lr_res_error )
-				    != LBER_ERROR )
-#endif /* ! LDAP_NULL_IS_NULL */
-			{
-				if ( lr_res_error != NULL ) {
-#ifndef LDAP_NULL_IS_NULL
-					if ( lr_res_error[ 0 ] == '\0' ) {
-						LDAP_FREE( lr_res_error );
-						lr_res_error = NULL;
-					} else
-#endif /* ! LDAP_NULL_IS_NULL */
-					{
-						if ( lr->lr_res_error != NULL ) {
-							(void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
-							LDAP_FREE( (char *)lr_res_error );
+	} else if ( tag != LDAP_RES_SEARCH_ENTRY && tag != LDAP_RES_INTERMEDIATE ) {
+		/* All results that just return a status, i.e. don't return data
+		 * go through the following code.  This code also chases V2 referrals
+		 * and checks if all referrals have been chased.
+		 */
+		char		*lr_res_error = NULL;
 
-						} else {
-							lr->lr_res_error = lr_res_error;
-						}
-					}
-					lr_res_error = NULL;
+		tmpber = *ber; 	/* struct copy */
+		if ( ber_scanf( &tmpber, "{eAA", &lderr,
+				&lr->lr_res_matched, &lr_res_error )
+				!= LBER_ERROR )
+		{
+			if ( lr_res_error != NULL ) {
+				if ( lr->lr_res_error != NULL ) {
+					(void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
+					LDAP_FREE( (char *)lr_res_error );
+
+				} else {
+					lr->lr_res_error = lr_res_error;
 				}
+				lr_res_error = NULL;
+			}
 
+			/* Do we need to check for referrals? */
+			if ( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) ||
+					lr->lr_parent != NULL )
+			{
+				char		**refs = NULL;
+				ber_len_t	len;
+
 				/* Check if V3 referral */
 				if ( ber_peek_tag( &tmpber, &len ) == LDAP_TAG_REFERRAL ) {
-					/* We have a V3 referral, assume we cannot chase it */
-					v3ref = V3REF_TOAPP;
-					if( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS)
-							 || (lr->lr_parent != NULL) )
-					{
+					if ( ld->ld_version > LDAP_VERSION2 ) {
 						/* Get the referral list */
-						if( ber_scanf( &tmpber, "{v}", &refs) == LBER_ERROR) {
+						if ( ber_scanf( &tmpber, "{v}", &refs) == LBER_ERROR) {
 							rc = LDAP_DECODING_ERROR;
 							lr->lr_status = LDAP_REQST_COMPLETED;
 							Debug( LDAP_DEBUG_TRACE,
-								"read1msg: referral decode error, mark request completed, ld %p msgid %d\n",
-								(void *)ld, lr->lr_msgid, 0);
+								"read1msg: referral decode error, "
+								"mark request completed, ld %p msgid %d\n",
+								(void *)ld, lr->lr_msgid, 0 );
+
 						} else {
 							/* Chase the referral 
-							 * Note: refs arrary is freed by ldap_chase_v3referrals
+							 * refs array is freed by ldap_chase_v3referrals
 							 */
 							refer_cnt = ldap_chase_v3referrals( ld, lr, refs,
-							    0, &lr->lr_res_error, &hadref );
+								0, &lr->lr_res_error, &hadref );
 							lr->lr_status = LDAP_REQST_COMPLETED;
 							Debug( LDAP_DEBUG_TRACE,
 								"read1msg: referral %s chased, "
 								"mark request completed, ld %p msgid %d\n",
-								hadref ? "" : "not",
+								refer_cnt > 0 ? "" : "not",
 								(void *)ld, lr->lr_msgid);
-							if( refer_cnt > 0) {
-								/* Referral successfully chased */
-								v3ref = V3REF_SUCCESS;
-							} else {
+							if ( refer_cnt < 0 ) {
 								refer_cnt = 0;
 							}
 						}
 					}
-				}
+				} else {
+					switch ( lderr ) {
+					case LDAP_SUCCESS:
+					case LDAP_COMPARE_TRUE:
+					case LDAP_COMPARE_FALSE:
+						break;
 
-				if( lr->lr_res_matched != NULL ) {
-					LDAP_FREE( lr->lr_res_matched );
-					lr->lr_res_matched = NULL;
-				}
-				if( lr->lr_res_error != NULL ) {
-					LDAP_FREE( lr->lr_res_error );
-					lr->lr_res_error = NULL;
-				}
-			}
-		}
-	}
+					default:
+						if ( lr->lr_res_error == NULL ) {
+							break;
+						}
 
-	/* All results that just return a status, i.e. don't return data
-	 * go through the following code.  This code also chases V2 referrals
-	 * and checks if all referrals have been chased.
-	 */
-	if ( tag != LDAP_RES_SEARCH_ENTRY &&
-		tag != LDAP_RES_SEARCH_REFERENCE &&
-		tag != LDAP_RES_INTERMEDIATE )
-	{
-		/* For a v3 search referral/reference, only come here if already chased it */
-		if ( ld->ld_version >= LDAP_VERSION2 &&
-			v3ref != V3REF_TOAPP &&
-			( lr->lr_parent != NULL ||
-			LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) ) )
-		{
-			char		*lr_res_error = NULL;
-
-			tmpber = *ber;	/* struct copy */
-			if ( v3ref == V3REF_SUCCESS ) {
-				/* V3 search reference or V3 referral
-				 * sucessfully chased. If this message
-				 * is a search result, then it has no more
-				 * outstanding referrals.
-				 */
-				if ( tag == LDAP_RES_SEARCH_RESULT )
-					refer_cnt = 0;
-#ifdef LDAP_NULL_IS_NULL
-			} else if ( ber_scanf( &tmpber, "{eAA}", &lderr,
-				&lr->lr_res_matched, &lr_res_error )
-				!= LBER_ERROR )
-#else /* ! LDAP_NULL_IS_NULL */
-			} else if ( ber_scanf( &tmpber, "{eaa}", &lderr,
-				&lr->lr_res_matched, &lr_res_error )
-				!= LBER_ERROR )
-#endif /* ! LDAP_NULL_IS_NULL */
-			{
-				if ( lr_res_error != NULL ) {
-#ifndef LDAP_NULL_IS_NULL
-					if ( lr_res_error[ 0 ] == '\0' ) {
-						LDAP_FREE( lr_res_error );
-					} else
-#endif /* ! LDAP_NULL_IS_NULL */
-					{
-						if ( lr->lr_res_error != NULL ) {
-							(void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
-							LDAP_FREE( (char *)lr_res_error );
-						} else {
-							lr->lr_res_error = lr_res_error;
+						/* pedantic, should never happen */
+						if ( lr->lr_res_error[ 0 ] == '\0' ) {
+							LDAP_FREE( lr->lr_res_error );
+							lr->lr_res_error = NULL;
+							break;	
 						}
-					}
-					lr_res_error = NULL;
-				}
 
-				switch ( lderr ) {
-				case LDAP_SUCCESS:
-				case LDAP_COMPARE_TRUE:
-				case LDAP_COMPARE_FALSE:
-					break;
-
-				default:
-					if ( lr->lr_res_error == NULL
-						|| lr->lr_res_error[ 0 ] == '\0' )
-					{
+						/* V2 referrals are in error string */
+						refer_cnt = ldap_chase_referrals( ld, lr,
+							&lr->lr_res_error, -1, &hadref );
+						lr->lr_status = LDAP_REQST_COMPLETED;
+						Debug( LDAP_DEBUG_TRACE,
+							"read1msg:  V2 referral chased, "
+							"mark request completed, id = %d\n",
+							lr->lr_msgid, 0, 0 );
 						break;
 					}
-
-					/* referrals are in error string */
-					refer_cnt = ldap_chase_referrals( ld, lr,
-						&lr->lr_res_error, -1, &hadref );
-					lr->lr_status = LDAP_REQST_COMPLETED;
-					Debug( LDAP_DEBUG_TRACE,
-						"read1msg:  V2 referral chased, "
-						"mark request completed, id = %d\n",
-						lr->lr_msgid, 0, 0 );
-					break;
 				}
+			}
 
-				/* save errno, message, and matched string */
-				if ( !hadref || lr->lr_res_error == NULL ) {
-					lr->lr_res_errno = ( lderr ==
-					LDAP_PARTIAL_RESULTS ) ? LDAP_SUCCESS
-					: lderr;
-				} else if ( ld->ld_errno != LDAP_SUCCESS ) {
-					lr->lr_res_errno = ld->ld_errno;
-				} else {
-					lr->lr_res_errno = LDAP_PARTIAL_RESULTS;
-				}
+			/* save errno, message, and matched string */
+			if ( !hadref || lr->lr_res_error == NULL ) {
+				lr->lr_res_errno =
+					lderr == LDAP_PARTIAL_RESULTS
+					? LDAP_SUCCESS : lderr;
 
-				Debug( LDAP_DEBUG_TRACE, "new result:  "
-					"res_errno: %d, "
-					"res_error: <%s>, "
-					"res_matched: <%s>\n",
-    					lr->lr_res_errno,
-					lr->lr_res_error ? lr->lr_res_error : "",
-					lr->lr_res_matched ? lr->lr_res_matched : "" );
-			}
+			} else if ( ld->ld_errno != LDAP_SUCCESS ) {
+				lr->lr_res_errno = ld->ld_errno;
 
-			/* in any case, don't leave any lr_res_error 'round */
-			if ( lr_res_error ) {
-				LDAP_FREE( lr_res_error );
+			} else {
+				lr->lr_res_errno = LDAP_PARTIAL_RESULTS;
 			}
 		}
 
+		/* in any case, don't leave any lr_res_error 'round */
+		if ( lr_res_error ) {
+			LDAP_FREE( lr_res_error );
+		}
+
 		Debug( LDAP_DEBUG_TRACE,
 			"read1msg: ld %p %d new referrals\n",
 			(void *)ld, refer_cnt, 0 );
@@ -768,13 +853,16 @@
 			ber_free( ber, 1 );
 			ber = NULL;
 			if ( refer_cnt < 0 ) {
+				ldap_return_request( ld, lr, 0 );
 				return( -1 );	/* fatal error */
 			}
 			lr->lr_res_errno = LDAP_SUCCESS; /* sucessfully chased referral */
+
 		} else {
 			if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL ) {
 				/* request without any referrals */
 				simple_request = ( hadref ? 0 : 1 );
+
 			} else {
 				/* request with referrals or child request */
 				ber_free( ber, 1 );
@@ -796,45 +884,123 @@
 
 			/* Check if all requests are finished, lr is now parent */
 			tmplr = lr;
-			if (tmplr->lr_status == LDAP_REQST_COMPLETED) {
-				for ( tmplr=lr->lr_child;
+			if ( tmplr->lr_status == LDAP_REQST_COMPLETED ) {
+				for ( tmplr = lr->lr_child;
 					tmplr != NULL;
-					tmplr=tmplr->lr_refnext)
+					tmplr = tmplr->lr_refnext )
 				{
-					if( tmplr->lr_status != LDAP_REQST_COMPLETED) break;
+					if ( tmplr->lr_status != LDAP_REQST_COMPLETED ) break;
 				}
 			}
 
 			/* This is the parent request if the request has referrals */
-			if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL &&
+			if ( lr->lr_outrefcnt <= 0 &&
+				lr->lr_parent == NULL &&
 				tmplr == NULL )
 			{
 				id = lr->lr_msgid;
 				tag = lr->lr_res_msgtype;
-				Debug( LDAP_DEBUG_ANY, "request done: ld %p msgid %ld\n",
+				Debug( LDAP_DEBUG_TRACE, "request done: ld %p msgid %ld\n",
 					(void *)ld, (long) id, 0 );
-Debug( LDAP_DEBUG_TRACE,
-"res_errno: %d, res_error: <%s>, res_matched: <%s>\n",
-lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "",
-lr->lr_res_matched ? lr->lr_res_matched : "" );
+				Debug( LDAP_DEBUG_TRACE,
+					"res_errno: %d, res_error: <%s>, "
+					"res_matched: <%s>\n",
+					lr->lr_res_errno,
+					lr->lr_res_error ? lr->lr_res_error : "",
+					lr->lr_res_matched ? lr->lr_res_matched : "" );
 				if ( !simple_request ) {
 					ber_free( ber, 1 );
 					ber = NULL;
 					if ( build_result_ber( ld, &ber, lr )
-					    == LBER_ERROR ) {
+					    == LBER_ERROR )
+					{
 						rc = -1; /* fatal error */
 					}
 				}
 
+				if ( lr != &dummy_lr ) {
+					ldap_return_request( ld, lr, 1 );
+				}
+				lr = NULL;
+			}
+
+			/*
+			 * RF 4511 unsolicited (id == 0) responses
+			 * shouldn't necessarily end the connection
+			 */
+			if ( lc != NULL && id != 0 ) {
 #ifdef LDAP_R_COMPILE
 				ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
 #endif
-				ldap_free_request( ld, lr );
+				ldap_free_connection( ld, lc, 0, 1 );
 #ifdef LDAP_R_COMPILE
 				ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
 #endif
+				lc = *lcp = NULL;
 			}
+		}
+	}
 
+	if ( lr != NULL ) {
+		if ( lr != &dummy_lr ) {
+			ldap_return_request( ld, lr, 0 );
+		}
+		lr = NULL;
+	}
+
+	if ( ber == NULL ) {
+		return( rc );
+	}
+
+	/* try to handle unsolicited responses as appropriate */
+	if ( id == 0 && msgid > LDAP_RES_UNSOLICITED ) {
+		int	is_nod = 0;
+
+		tag = ber_peek_tag( &tmpber, &len );
+
+		/* we have a res oid */
+		if ( tag == LDAP_TAG_EXOP_RES_OID ) {
+			static struct berval	bv_nod = BER_BVC( LDAP_NOTICE_OF_DISCONNECTION );
+			struct berval		resoid = BER_BVNULL;
+
+			if ( ber_scanf( &tmpber, "m", &resoid ) == LBER_ERROR ) {
+				ld->ld_errno = LDAP_DECODING_ERROR;
+				ber_free( ber, 1 );
+				return -1;
+			}
+
+			assert( !BER_BVISEMPTY( &resoid ) );
+
+			is_nod = ber_bvcmp( &resoid, &bv_nod ) == 0;
+
+			tag = ber_peek_tag( &tmpber, &len );
+		}
+
+#if 0 /* don't need right now */
+		/* we have res data */
+		if ( tag == LDAP_TAG_EXOP_RES_VALUE ) {
+			struct berval resdata;
+
+			if ( ber_scanf( &tmpber, "m", &resdata ) == LBER_ERROR ) {
+				ld->ld_errno = LDAP_DECODING_ERROR;
+				ber_free( ber, 0 );
+				return ld->ld_errno;
+			}
+
+			/* use it... */
+		}
+#endif
+
+		/* handle RFC 4511 "Notice of Disconnection" locally */
+
+		if ( is_nod ) {
+			if ( tag == LDAP_TAG_EXOP_RES_VALUE ) {
+				ld->ld_errno = LDAP_DECODING_ERROR;
+				ber_free( ber, 1 );
+				return -1;
+			}
+
+			/* get rid of the connection... */
 			if ( lc != NULL ) {
 #ifdef LDAP_R_COMPILE
 				ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
@@ -845,13 +1011,13 @@
 #endif
 				lc = *lcp = NULL;
 			}
+
+			/* need to return -1, because otherwise
+			 * a valid result is expected */
+			return -1;
 		}
 	}
 
-	if ( ber == NULL ) {
-		return( rc );
-	}
-
 	/* make a new ldap message */
 	newmsg = (LDAPMessage *) LDAP_CALLOC( 1, sizeof(LDAPMessage) );
 	if ( newmsg == NULL ) {
@@ -885,18 +1051,18 @@
 				 */
 				ber = ber_dup( ber );
 				ber_scanf( ber, "x" );
-				if (ber_peek_tag(ber, &len) != LBER_DEFAULT) {
+				if ( ber_peek_tag( ber, &len ) != LBER_DEFAULT ) {
 					/* There's more - dup the ber buffer so they can all be
 					 * individually freed by ldap_msgfree.
 					 */
 					struct berval bv;
-					ber_get_option(ber, LBER_OPT_BER_REMAINING_BYTES, &len);
-					bv.bv_val = LDAP_MALLOC(len);
-					if (bv.bv_val) {
-						ok=1;
-						ber_read(ber, bv.bv_val, len);
+					ber_get_option( ber, LBER_OPT_BER_REMAINING_BYTES, &len );
+					bv.bv_val = LDAP_MALLOC( len );
+					if ( bv.bv_val ) {
+						ok = 1;
+						ber_read( ber, bv.bv_val, len );
 						bv.bv_len = len;
-						ber_init2(ber, &bv, ld->ld_lberoptions );
+						ber_init2( ber, &bv, ld->ld_lberoptions );
 					}
 				}
 			} else {
@@ -918,16 +1084,20 @@
 			chain_head->lm_chain_tail = newmsg;
 			tmp = newmsg;
 			/* "ok" means there's more to parse */
-			if (ok) {
-				if (isv2) goto nextresp2;
-				else goto nextresp3;
+			if ( ok ) {
+				if ( isv2 ) {
+					goto nextresp2;
+
+				} else {
+					goto nextresp3;
+				}
 			} else {
 				/* got to end of datagram without a SearchResult. Free
 				 * our dup'd ber, but leave any buffer alone. For v2 case,
 				 * the previous response is still using this buffer. For v3,
 				 * the new ber has no buffer to free yet.
 				 */
-				ber_free(ber, 0);
+				ber_free( ber, 0 );
 				return -1;
 			}
 		} else if ( moremsgs ) {
@@ -947,12 +1117,14 @@
 	/* is this the one we're looking for? */
 	if ( msgid == LDAP_RES_ANY || id == msgid ) {
 		if ( all == LDAP_MSG_ONE
-		    || (newmsg->lm_msgtype != LDAP_RES_SEARCH_RESULT
-		    && newmsg->lm_msgtype != LDAP_RES_SEARCH_ENTRY
-		    && newmsg->lm_msgtype != LDAP_RES_SEARCH_REFERENCE) ) {
+			|| ( newmsg->lm_msgtype != LDAP_RES_SEARCH_RESULT
+			    	&& newmsg->lm_msgtype != LDAP_RES_SEARCH_ENTRY
+			  	&& newmsg->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) )
+		{
 			*result = newmsg;
 			ld->ld_errno = LDAP_SUCCESS;
 			return( tag );
+
 		} else if ( newmsg->lm_msgtype == LDAP_RES_SEARCH_RESULT) {
 			foundit = 1;	/* return the chain later */
 		}
@@ -966,8 +1138,9 @@
 
 	prev = NULL;
 	for ( l = ld->ld_responses; l != NULL; l = l->lm_next ) {
-		if ( l->lm_msgid == newmsg->lm_msgid )
+		if ( l->lm_msgid == newmsg->lm_msgid ) {
 			break;
+		}
 		prev = l;
 	}
 
@@ -992,10 +1165,11 @@
 
 	/* return the whole chain if that's what we were looking for */
 	if ( foundit ) {
-		if ( prev == NULL )
+		if ( prev == NULL ) {
 			ld->ld_responses = l->lm_next;
-		else
+		} else {
 			prev->lm_next = l->lm_next;
+		}
 		*result = l;
 	}
 
@@ -1033,7 +1207,7 @@
 		lr->lr_res_error ? lr->lr_res_error : "" ) == -1 )
 	{
 		ld->ld_errno = LDAP_ENCODING_ERROR;
-		ber_free(ber, 1);
+		ber_free( ber, 1 );
 		return( LBER_ERROR );
 	}
 
@@ -1041,13 +1215,13 @@
 
 	if ( ber_skip_tag( ber, &len ) == LBER_ERROR ) {
 		ld->ld_errno = LDAP_DECODING_ERROR;
-		ber_free(ber, 1);
+		ber_free( ber, 1 );
 		return( LBER_ERROR );
 	}
 
 	if ( ber_get_enum( ber, &along ) == LBER_ERROR ) {
 		ld->ld_errno = LDAP_DECODING_ERROR;
-		ber_free(ber, 1);
+		ber_free( ber, 1 );
 		return( LBER_ERROR );
 	}
 
@@ -1055,7 +1229,7 @@
 
 	if ( tag == LBER_ERROR ) {
 		ld->ld_errno = LDAP_DECODING_ERROR;
-		ber_free(ber, 1);
+		ber_free( ber, 1 );
 		return( LBER_ERROR );
 	}
 
@@ -1064,18 +1238,19 @@
 }
 
 
+/*
+ * Merge error information in "lr" with "parentr" error code and string.
+ */
 static void
 merge_error_info( LDAP *ld, LDAPRequest *parentr, LDAPRequest *lr )
 {
-/*
- * Merge error information in "lr" with "parentr" error code and string.
- */
 	if ( lr->lr_res_errno == LDAP_PARTIAL_RESULTS ) {
 		parentr->lr_res_errno = lr->lr_res_errno;
 		if ( lr->lr_res_error != NULL ) {
 			(void)ldap_append_referral( ld, &parentr->lr_res_error,
-			    lr->lr_res_error );
+				lr->lr_res_error );
 		}
+
 	} else if ( lr->lr_res_errno != LDAP_SUCCESS &&
 		parentr->lr_res_errno == LDAP_SUCCESS )
 	{
@@ -1095,11 +1270,11 @@
 	}
 
 	Debug( LDAP_DEBUG_TRACE, "merged parent (id %d) error info:  ",
-	    parentr->lr_msgid, 0, 0 );
+		parentr->lr_msgid, 0, 0 );
 	Debug( LDAP_DEBUG_TRACE, "result errno %d, error <%s>, matched <%s>\n",
-	    parentr->lr_res_errno, parentr->lr_res_error ?
-	    parentr->lr_res_error : "", parentr->lr_res_matched ?
-	    parentr->lr_res_matched : "" );
+		parentr->lr_res_errno,
+		parentr->lr_res_error ?  parentr->lr_res_error : "",
+		parentr->lr_res_matched ?  parentr->lr_res_matched : "" );
 }
 
 
@@ -1121,7 +1296,8 @@
 }
 
 
-char * ldap_int_msgtype2str( ber_tag_t tag )
+const char *
+ldap_int_msgtype2str( ber_tag_t tag )
 {
 	switch( tag ) {
 	case LDAP_RES_ADD: return "add";
@@ -1154,7 +1330,7 @@
 		LDAP_FREE( (char *) lm );
 	}
 
-	return( type );
+	return type;
 }
 
 /*
@@ -1166,77 +1342,93 @@
 ldap_msgdelete( LDAP *ld, int msgid )
 {
 	LDAPMessage	*lm, *prev;
-	int rc = 0;
+	int		rc = 0;
 
 	assert( ld != NULL );
 
-	Debug( LDAP_DEBUG_TRACE, "ldap_msgdelete\n", 0, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE, "ldap_msgdelete ld=%p msgid=%d\n",
+		(void *)ld, msgid, 0 );
 
-	prev = NULL;
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
 #endif
+	prev = NULL;
 	for ( lm = ld->ld_responses; lm != NULL; lm = lm->lm_next ) {
-		if ( lm->lm_msgid == msgid )
+		if ( lm->lm_msgid == msgid ) {
 			break;
+		}
 		prev = lm;
 	}
 
 	if ( lm == NULL ) {
 		rc = -1;
+
 	} else {
-		if ( prev == NULL )
+		if ( prev == NULL ) {
 			ld->ld_responses = lm->lm_next;
-		else
+		} else {
 			prev->lm_next = lm->lm_next;
+		}
 	}
 #ifdef LDAP_R_COMPILE
 	ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
 #endif
-	if ( lm && ldap_msgfree( lm ) == LDAP_RES_SEARCH_ENTRY )
-		rc = -1;
+	if ( lm ) {
+		switch ( ldap_msgfree( lm ) ) {
+		case LDAP_RES_SEARCH_ENTRY:
+		case LDAP_RES_SEARCH_REFERENCE:
+		case LDAP_RES_INTERMEDIATE:
+			rc = -1;
+			break;
 
-	return( rc );
+		default:
+			break;
+		}
+	}
+
+	return rc;
 }
 
 
 /*
- * return 1 if message msgid is waiting to be abandoned, 0 otherwise
+ * ldap_abandoned
+ *
+ * return the location of the message id in the array of abandoned
+ * message ids, or -1
+ *
+ * expects ld_res_mutex to be locked
  */
 static int
-ldap_abandoned( LDAP *ld, ber_int_t msgid )
+ldap_abandoned( LDAP *ld, ber_int_t msgid, int *idxp )
 {
-	int	i;
+#ifdef LDAP_R_COMPILE
+	LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );
+#endif
 
-	if ( ld->ld_abandoned == NULL )
-		return( 0 );
+	assert( idxp != NULL );
+	assert( msgid >= 0 );
+	assert( ld->ld_nabandoned >= 0 );
 
-	for ( i = 0; ld->ld_abandoned[i] != -1; i++ )
-		if ( ld->ld_abandoned[i] == msgid )
-			return( 1 );
-
-	return( 0 );
+	return ldap_int_bisect_find( ld->ld_abandoned, ld->ld_nabandoned, msgid, idxp );
 }
 
-
+/*
+ * ldap_mark_abandoned
+ *
+ * expects ld_res_mutex to be locked
+ */
 static int
-ldap_mark_abandoned( LDAP *ld, ber_int_t msgid )
+ldap_mark_abandoned( LDAP *ld, ber_int_t msgid, int idx )
 {
-	int	i;
+#ifdef LDAP_R_COMPILE
+	LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );
+#endif
 
-	if ( ld->ld_abandoned == NULL )
-		return( -1 );
+	/* NOTE: those assertions are repeated in ldap_int_bisect_delete() */
+	assert( idx >= 0 );
+	assert( idx < ld->ld_nabandoned );
+	assert( ld->ld_abandoned[ idx ] == msgid );
 
-	for ( i = 0; ld->ld_abandoned[i] != -1; i++ )
-		if ( ld->ld_abandoned[i] == msgid )
-			break;
-
-	if ( ld->ld_abandoned[i] == -1 )
-		return( -1 );
-
-	for ( ; ld->ld_abandoned[i] != -1; i++ ) {
-		ld->ld_abandoned[i] = ld->ld_abandoned[i + 1];
-	}
-
-	return( 0 );
+	return ldap_int_bisect_delete( &ld->ld_abandoned, &ld->ld_nabandoned,
+		msgid, idx );
 }

Modified: openldap/trunk/libraries/libldap/sasl.c
===================================================================
--- openldap/trunk/libraries/libldap/sasl.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/sasl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/sasl.c,v 1.58.2.5 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/sasl.c,v 1.64.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -12,9 +12,6 @@
  * top-level directory of the distribution or, alternatively, at
  * <http://www.OpenLDAP.org/license.html>.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
 /*
  *	BindRequest ::= SEQUENCE {
@@ -22,10 +19,8 @@
  *		name		DistinguishedName,	 -- who
  *		authentication	CHOICE {
  *			simple		[0] OCTET STRING -- passwd
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
- *			krbv42ldap	[1] OCTET STRING
- *			krbv42dsa	[2] OCTET STRING
-#endif
+ *			krbv42ldap	[1] OCTET STRING -- OBSOLETE
+ *			krbv42dsa	[2] OCTET STRING -- OBSOLETE
  *			sasl		[3] SaslCredentials	-- LDAPv3
  *		}
  *	}
@@ -196,7 +191,7 @@
 	}
 #endif
 
-	if ( ldap_result( ld, msgid, 1, NULL, &result ) == -1 ) {
+	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1 || !result ) {
 		return( ld->ld_errno );	/* ldap_result sets ld_errno */
 	}
 
@@ -294,13 +289,8 @@
 	}
 
 	if ( ld->ld_version < LDAP_VERSION2 ) {
-#ifdef LDAP_NULL_IS_NULL
 		tag = ber_scanf( ber, "{iA}",
 			&errcode, &ld->ld_error );
-#else /* ! LDAP_NULL_IS_NULL */
-		tag = ber_scanf( ber, "{ia}",
-			&errcode, &ld->ld_error );
-#endif /* ! LDAP_NULL_IS_NULL */
 
 		if( tag == LBER_ERROR ) {
 			ber_free( ber, 0 );
@@ -311,13 +301,8 @@
 	} else {
 		ber_len_t len;
 
-#ifdef LDAP_NULL_IS_NULL
 		tag = ber_scanf( ber, "{eAA" /*}*/,
 			&errcode, &ld->ld_matched, &ld->ld_error );
-#else /* ! LDAP_NULL_IS_NULL */
-		tag = ber_scanf( ber, "{eaa" /*}*/,
-			&errcode, &ld->ld_matched, &ld->ld_error );
-#endif /* ! LDAP_NULL_IS_NULL */
 
 		if( tag == LBER_ERROR ) {
 			ber_free( ber, 0 );

Modified: openldap/trunk/libraries/libldap/sbind.c
===================================================================
--- openldap/trunk/libraries/libldap/sbind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/sbind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/sbind.c,v 1.23.2.3 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/sbind.c,v 1.25.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -15,9 +15,6 @@
 /* Portions Copyright (c) 1993 Regents of the University of Michigan.
  * All rights reserved.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
 /*
  *	BindRequest ::= SEQUENCE {
@@ -25,10 +22,8 @@
  *		name		DistinguishedName,	 -- who
  *		authentication	CHOICE {
  *			simple		[0] OCTET STRING -- passwd
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
- *			krbv42ldap	[1] OCTET STRING
- *			krbv42dsa	[2] OCTET STRING
-#endif
+ *			krbv42ldap	[1] OCTET STRING  -- OBSOLETE
+ *			krbv42dsa	[2] OCTET STRING  -- OBSOLETE
  *			sasl		[3] SaslCredentials	-- LDAPv3
  *		}
  *	}

Modified: openldap/trunk/libraries/libldap/schema.c
===================================================================
--- openldap/trunk/libraries/libldap/schema.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/schema.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/schema.c,v 1.66.2.7 2007/01/02 21:43:49 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/schema.c,v 1.77.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -1028,7 +1028,7 @@
 			**sp != '$' &&
 			**sp != '\'' &&
 			/* for suggested minimum upper bound on the number
-			 * of characters <draft-ietf-ldapbis-syntaxes> */
+			 * of characters (RFC 4517) */
 			**sp != '{' &&
 			**sp != '\0' )
 			(*sp)++;

Modified: openldap/trunk/libraries/libldap/search.c
===================================================================
--- openldap/trunk/libraries/libldap/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/search.c,v 1.64.2.9 2007/06/08 07:43:26 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/search.c,v 1.76.2.3 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -138,7 +138,7 @@
 		return( rc );
 	}
 
-	rc = ldap_result( ld, msgid, 1, timeout, res );
+	rc = ldap_result( ld, msgid, LDAP_MSG_ALL, timeout, res );
 
 	if( rc <= 0 ) {
 		/* error(-1) or timeout(0) */
@@ -261,7 +261,7 @@
 	if ( LDAP_IS_UDP(ld) ) {
 		struct sockaddr sa = {0};
 		/* dummy, filled with ldo_peer in request.c */
-		err = ber_write( ber, &sa, sizeof( sa ), 0 );
+	    err = ber_write( ber, &sa, sizeof( sa ), 0 );
 	}
 	if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == LDAP_VERSION2) {
 	    char *dn = ld->ld_options.ldo_cldapdn;
@@ -301,18 +301,27 @@
 
 #ifdef LDAP_DEBUG
 	if ( ldap_debug & LDAP_DEBUG_ARGS ) {
-		if ( attrs == NULL ) {
-			Debug( LDAP_DEBUG_ARGS, "ldap_build_search_req ATTRS: *\n", 0, 0, 0 );
-			
-		} else {
+		char	buf[ BUFSIZ ] = { ' ', '*', '\0' };
+
+		if ( attrs != NULL ) {
+			char	*ptr;
 			int	i;
 
-			Debug( LDAP_DEBUG_ARGS, "ldap_build_search_req ATTRS:\n", 0, 0, 0 );
+			for ( ptr = buf, i = 0;
+				attrs[ i ] != NULL && ptr < &buf[ sizeof( buf ) ];
+				i++ )
+			{
+				ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ),
+					" %s", attrs[ i ] );
+			}
 
-			for ( i = 0; attrs[ i ]; i++ ) {
-				Debug( LDAP_DEBUG_ARGS, "    %s\n", attrs[ i ], 0, 0 );
-			}
+			if ( ptr >= &buf[ sizeof( buf ) ] ) {
+				AC_MEMCPY( &buf[ sizeof( buf ) - STRLENOF( "...(truncated)" ) - 1 ],
+					"...(truncated)", STRLENOF( "...(truncated)" ) + 1 );
+			} 
 		}
+
+		Debug( LDAP_DEBUG_ARGS, "ldap_build_search_req ATTRS:%s\n", buf, 0, 0 );
 	}
 #endif /* LDAP_DEBUG */
 
@@ -349,7 +358,7 @@
 	    == -1 )
 		return( ld->ld_errno );
 
-	if ( ldap_result( ld, msgid, 1, timeout, res ) == -1 )
+	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, timeout, res ) == -1 )
 		return( ld->ld_errno );
 
 	if ( ld->ld_errno == LDAP_TIMEOUT ) {
@@ -377,7 +386,7 @@
 	    == -1 )
 		return( ld->ld_errno );
 
-	if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, res ) == -1 )
+	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, res ) == -1 || !res )
 		return( ld->ld_errno );
 
 	return( ldap_result2error( ld, *res, 0 ) );
@@ -407,8 +416,7 @@
 #define	NEEDFLTESCAPE(c)	((c) & 0x80 || escape[ (unsigned)(c) ])
 
 /*
- * compute the length of the escaped value;
- * returns ((ber_len_t)(-1)) if no escaping is required.
+ * compute the length of the escaped value
  */
 ber_len_t
 ldap_bv2escaped_filter_value_len( struct berval *in )
@@ -421,7 +429,6 @@
 		return 0;
 	}
 
-	/* assume we'll escape everything */
 	for( l = 0, i = 0; i < in->bv_len; l++, i++ ) {
 		char c = in->bv_val[ i ];
 		if ( NEEDFLTESCAPE( c ) ) {

Modified: openldap/trunk/libraries/libldap/sort.c
===================================================================
--- openldap/trunk/libraries/libldap/sort.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/sort.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* sort.c -- LDAP library entry and value sort routines */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/sort.c,v 1.25.2.4 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/sort.c,v 1.27.2.3 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/sortctrl.c
===================================================================
--- openldap/trunk/libraries/libldap/sortctrl.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/sortctrl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/sortctrl.c,v 1.12.2.3 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/sortctrl.c,v 1.19.2.3 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -27,9 +27,6 @@
  * can be found in the file "build/LICENSE-2.0.1" in this distribution
  * of OpenLDAP Software.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
 #include "portable.h"
 
@@ -260,9 +257,9 @@
 
 
 /* ---------------------------------------------------------------------------
-   ldap_create_sort_control
+   ldap_create_sort_control_value
    
-   Create and encode the server-side sort control.
+   Create and encode the value of the server-side sort control.
    
    ld          (IN) An LDAP session handle, as obtained from a call to
 					ldap_init().
@@ -273,11 +270,8 @@
 					consists of an attribute name, ascending/descending flag,
 					and an optional matching rule (OID) to use.
 			   
-   isCritical  (IN) 0 - Indicates the control is not critical to the operation.
-					non-zero - The control is critical to the operation.
-					 
-   ctrlp      (OUT) Returns a pointer to the LDAPControl created.  This control
-					SHOULD be freed by calling ldap_control_free() when done.
+   value      (OUT) Contains the control value; the bv_val member of the berval structure
+					SHOULD be freed by calling ldap_memfree() when done.
    
    
    Ber encoding
@@ -290,82 +284,165 @@
    ---------------------------------------------------------------------------*/
 
 int
-ldap_create_sort_control (
+ldap_create_sort_control_value(
 	LDAP *ld,
 	LDAPSortKey **keyList,
-	int isCritical,
-	LDAPControl **ctrlp )
+	struct berval *value )
 {
-	int         i;
-	BerElement  *ber;
-	ber_tag_t tag;
+	int		i;
+	BerElement	*ber = NULL;
+	ber_tag_t	tag;
 
+	assert( ld != NULL );
+	assert( LDAP_VALID( ld ) );
 
-	if ( (ld == NULL) || (keyList == NULL) || (ctrlp == NULL) ) {
+	if ( ld == NULL ) return LDAP_PARAM_ERROR;
+	if ( keyList == NULL || value == NULL ) {
 		ld->ld_errno = LDAP_PARAM_ERROR;
-		return(ld->ld_errno);
+		return LDAP_PARAM_ERROR;
 	}
 
-	if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
+	value->bv_val = NULL;
+	value->bv_len = 0;
+
+	ber = ldap_alloc_ber_with_options( ld );
+	if ( ber == NULL) {
 		ld->ld_errno = LDAP_NO_MEMORY;
-		return( ld->ld_errno );
+		return ld->ld_errno;
 	}
 
-	tag = ber_printf(ber, "{" /*}*/);
-	if (tag == LBER_ERROR) goto exit;
+	tag = ber_printf( ber, "{" /*}*/ );
+	if ( tag == LBER_ERROR ) {
+		goto error_return;
+	}
 
-	for (i = 0; keyList[i] != NULL; i++) {
-		tag = ber_printf(ber, "{s" /*}*/, (keyList[i])->attributeType);
-		if (tag == LBER_ERROR) goto exit;
+	for ( i = 0; keyList[i] != NULL; i++ ) {
+		tag = ber_printf( ber, "{s" /*}*/, keyList[i]->attributeType );
+		if ( tag == LBER_ERROR ) {
+			goto error_return;
+		}
 
-		if ((keyList[i])->orderingRule != NULL) {
+		if ( keyList[i]->orderingRule != NULL ) {
 			tag = ber_printf( ber, "ts",
 				LDAP_MATCHRULE_IDENTIFIER,
-				(keyList[i])->orderingRule );
+				keyList[i]->orderingRule );
 
-			if( tag == LBER_ERROR ) goto exit;
+			if ( tag == LBER_ERROR ) {
+				goto error_return;
+			}
 		}
 
-		if ((keyList[i])->reverseOrder) {
-			tag = ber_printf(ber, "tb",
+		if ( keyList[i]->reverseOrder ) {
+			tag = ber_printf( ber, "tb",
 				LDAP_REVERSEORDER_IDENTIFIER,
-				(keyList[i])->reverseOrder );
+				keyList[i]->reverseOrder );
 
-			if( tag == LBER_ERROR ) goto exit;
+			if ( tag == LBER_ERROR ) {
+				goto error_return;
+			}
 		}
 
-		tag = ber_printf(ber, /*{*/ "N}");
-		if( tag == LBER_ERROR ) goto exit;
+		tag = ber_printf( ber, /*{*/ "N}" );
+		if ( tag == LBER_ERROR ) {
+			goto error_return;
+		}
 	}
 
-	tag = ber_printf(ber, /*{*/ "N}");
-	if( tag == LBER_ERROR ) goto exit;
+	tag = ber_printf( ber, /*{*/ "N}" );
+	if ( tag == LBER_ERROR ) {
+		goto error_return;
+	}
 
-	ld->ld_errno = ldap_create_control( LDAP_CONTROL_SORTREQUEST,
-		ber, isCritical, ctrlp);
+	if ( ber_flatten2( ber, value, 1 ) == -1 ) {
+		ld->ld_errno = LDAP_NO_MEMORY;
+	}
 
-	ber_free(ber, 1);
+	if ( 0 ) {
+error_return:;
+		ld->ld_errno =  LDAP_ENCODING_ERROR;
+	}
 
-	return(ld->ld_errno);
+	if ( ber != NULL ) {
+		ber_free( ber, 1 );
+	}
 
-exit:
-	ber_free(ber, 1);
-	ld->ld_errno =  LDAP_ENCODING_ERROR;
-	return(ld->ld_errno);
+	return ld->ld_errno;
 }
 
 
 /* ---------------------------------------------------------------------------
-   ldap_parse_sort_control
+   ldap_create_sort_control
    
+   Create and encode the server-side sort control.
+   
+   ld          (IN) An LDAP session handle, as obtained from a call to
+					ldap_init().
+
+   keyList     (IN) Points to a null-terminated array of pointers to
+					LDAPSortKey structures, containing a description of
+					each of the sort keys to be used.  The description
+					consists of an attribute name, ascending/descending flag,
+					and an optional matching rule (OID) to use.
+			   
+   isCritical  (IN) 0 - Indicates the control is not critical to the operation.
+					non-zero - The control is critical to the operation.
+					 
+   ctrlp      (OUT) Returns a pointer to the LDAPControl created.  This control
+					SHOULD be freed by calling ldap_control_free() when done.
+   
+   
+   Ber encoding
+   
+   SortKeyList ::= SEQUENCE OF SEQUENCE {
+		   attributeType   AttributeDescription,
+		   orderingRule    [0] MatchingRuleId OPTIONAL,
+		   reverseOrder    [1] BOOLEAN DEFAULT FALSE }
+   
+   ---------------------------------------------------------------------------*/
+
+int
+ldap_create_sort_control(
+	LDAP *ld,
+	LDAPSortKey **keyList,
+	int isCritical,
+	LDAPControl **ctrlp )
+{
+	struct berval	value;
+
+	assert( ld != NULL );
+	assert( LDAP_VALID( ld ) );
+
+	if ( ld == NULL ) {
+		return LDAP_PARAM_ERROR;
+	}
+
+	if ( ctrlp == NULL ) {
+		ld->ld_errno = LDAP_PARAM_ERROR;
+		return ld->ld_errno;
+	}
+
+	ld->ld_errno = ldap_create_sort_control_value( ld, keyList, &value );
+	if ( ld->ld_errno == LDAP_SUCCESS ) {
+		ld->ld_errno = ldap_control_create( LDAP_CONTROL_SORTREQUEST,
+			isCritical, &value, 0, ctrlp );
+		if ( ld->ld_errno != LDAP_SUCCESS ) {
+			LDAP_FREE( value.bv_val );
+		}
+	}
+
+	return ld->ld_errno;
+}
+
+
+/* ---------------------------------------------------------------------------
+   ldap_parse_sortedresult_control
+   
    Decode the server-side sort control return information.
 
    ld          (IN) An LDAP session handle, as obtained from a call to
 					ldap_init().
 
-   ctrls       (IN) The address of a NULL-terminated array of LDAPControl
-					structures, typically obtained by a call to
-					ldap_parse_result().
+   ctrl        (IN) The address of the LDAP Control Structure.
 				  
    returnCode (OUT) This result parameter is filled in with the sort control
 					result code.  This parameter MUST not be NULL.
@@ -405,25 +482,25 @@
    ---------------------------------------------------------------------------*/
 
 int
-ldap_parse_sort_control(
-	LDAP           *ld,
-	LDAPControl    **ctrls,
-	unsigned long  *returnCode,
-	char           **attribute )
+ldap_parse_sortresponse_control(
+	LDAP *ld,
+	LDAPControl *ctrl,
+	ber_int_t *returnCode,
+	char **attribute )
 {
 	BerElement *ber;
-	LDAPControl *pControl;
-	int i;
 	ber_tag_t tag, berTag;
 	ber_len_t berLen;
 
+	assert( ld != NULL );
+	assert( LDAP_VALID( ld ) );
+
 	if (ld == NULL) {
-		ld->ld_errno = LDAP_PARAM_ERROR;
-		return(ld->ld_errno);
+		return LDAP_PARAM_ERROR;
 	}
 
-	if (ctrls == NULL) {
-		ld->ld_errno =  LDAP_CONTROL_NOT_FOUND;
+	if (ctrl == NULL) {
+		ld->ld_errno =  LDAP_PARAM_ERROR;
 		return(ld->ld_errno);
 	}
 
@@ -431,20 +508,14 @@
 		*attribute = NULL;
 	}
 
-	/* Search the list of control responses for a sort control. */
-	for (i=0; ctrls[i]; i++) {
-		pControl = ctrls[i];
-		if (!strcmp(LDAP_CONTROL_SORTRESPONSE, pControl->ldctl_oid))
-			goto foundSortControl;
+	if ( strcmp(LDAP_CONTROL_SORTRESPONSE, ctrl->ldctl_oid) != 0 ) {
+		/* Not sort result control */
+		ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
+		return(ld->ld_errno);
 	}
 
-	/* No sort control was found. */
-	ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
-	return(ld->ld_errno);
-
-foundSortControl:
 	/* Create a BerElement from the berval returned in the control. */
-	ber = ber_init(&pControl->ldctl_value);
+	ber = ber_init(&ctrl->ldctl_value);
 
 	if (ber == NULL) {
 		ld->ld_errno = LDAP_NO_MEMORY;

Copied: openldap/trunk/libraries/libldap/stctrl.c (from rev 891, openldap/vendor/openldap-2.4.7/libraries/libldap/stctrl.c)
===================================================================
--- openldap/trunk/libraries/libldap/stctrl.c	                        (rev 0)
+++ openldap/trunk/libraries/libldap/stctrl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,301 @@
+/* $OpenLDAP: pkg/ldap/libraries/libldap/stctrl.c,v 1.3.2.1 2007/08/31 23:13:56 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2007 The OpenLDAP Foundation.
+ * Portions Copyright 2007 Pierangelo Masarati.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was developed by Pierangelo Masarati for inclusion in
+ * OpenLDAP Software.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+
+#ifdef LDAP_CONTROL_X_SESSION_TRACKING
+
+/*
+ * Client-side of <draft-wahl-ldap-session-03>
+ */
+
+int
+ldap_create_session_tracking_value(
+	LDAP		*ld,
+	char		*sessionSourceIp,
+	char		*sessionSourceName,
+	char		*formatOID,
+	struct berval	*sessionTrackingIdentifier,
+	struct berval	*value )
+{
+	BerElement	*ber = NULL;
+	ber_tag_t	tag;
+
+	struct berval	ip, name, oid, id;
+
+	if ( ld == NULL ||
+		formatOID == NULL ||
+		value == NULL )
+	{
+param_error:;
+		if ( ld ) {
+			ld->ld_errno = LDAP_PARAM_ERROR;
+		}
+
+		return LDAP_PARAM_ERROR;
+	}
+
+	assert( LDAP_VALID( ld ) );
+
+	/* check sizes according to I.D. */
+	if ( sessionSourceIp == NULL ) {
+		BER_BVSTR( &ip, "" );
+
+	} else {
+		ber_str2bv( sessionSourceIp, 0, 0, &ip );
+		/* NOTE: we're strict because we don't want
+		 * to send out bad data */
+		if ( ip.bv_len > 128 ) goto param_error;
+	}
+
+	if ( sessionSourceName == NULL ) {
+		BER_BVSTR( &name, "" );
+
+	} else {
+		ber_str2bv( sessionSourceName, 0, 0, &name );
+		/* NOTE: we're strict because we don't want
+		 * to send out bad data */
+		if ( name.bv_len > 65536 ) goto param_error;
+	}
+
+	ber_str2bv( formatOID, 0, 0, &oid );
+	/* NOTE: we're strict because we don't want
+	 * to send out bad data */
+	if ( oid.bv_len > 1024 ) goto param_error;
+
+	if ( sessionTrackingIdentifier == NULL ||
+		sessionTrackingIdentifier->bv_val == NULL )
+	{
+		BER_BVSTR( &id, "" );
+
+	} else {
+		id = *sessionTrackingIdentifier;
+	}
+
+	/* prepare value */
+	value->bv_val = NULL;
+	value->bv_len = 0;
+
+	ber = ldap_alloc_ber_with_options( ld );
+	if ( ber == NULL ) {
+		ld->ld_errno = LDAP_NO_MEMORY;
+		return ld->ld_errno;
+	}
+
+	tag = ber_printf( ber, "{OOOO}", &ip, &name, &oid, &id );
+	if ( tag == LBER_ERROR ) {
+		ld->ld_errno = LDAP_ENCODING_ERROR;
+		goto done;
+	}
+
+	if ( ber_flatten2( ber, value, 1 ) == -1 ) {
+		ld->ld_errno = LDAP_NO_MEMORY;
+	}
+
+done:;
+	if ( ber != NULL ) {
+		ber_free( ber, 1 );
+	}
+
+	return ld->ld_errno;
+}
+
+/*
+ * NOTE: this API is bad; it could be much more efficient...
+ */
+int
+ldap_create_session_tracking_control(
+	LDAP		*ld,
+	char		*sessionSourceIp,
+	char		*sessionSourceName,
+	char		*formatOID,
+	struct berval	*sessionTrackingIdentifier,
+	LDAPControl	**ctrlp )
+{
+	struct berval	value;
+
+	if ( ctrlp == NULL ) {
+		ld->ld_errno = LDAP_PARAM_ERROR;
+		return ld->ld_errno;
+	}
+
+	ld->ld_errno = ldap_create_session_tracking_value( ld,
+		sessionSourceIp, sessionSourceName, formatOID,
+		sessionTrackingIdentifier, &value );
+	if ( ld->ld_errno == LDAP_SUCCESS ) {
+		ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_SESSION_TRACKING,
+			0, &value, 0, ctrlp );
+		if ( ld->ld_errno != LDAP_SUCCESS ) {
+			LDAP_FREE( value.bv_val );
+		}
+	}
+
+	return ld->ld_errno;
+}
+
+int
+ldap_parse_session_tracking_control(
+	LDAP *ld,
+	LDAPControl *ctrl,
+	struct berval *ip,
+	struct berval *name,
+	struct berval *oid,
+	struct berval *id )
+{
+	BerElement	*ber;
+	ber_tag_t	tag;
+	ber_len_t	len;
+
+	if ( ld == NULL || 
+		ctrl == NULL || 
+		ip == NULL ||
+		name == NULL ||
+		oid == NULL ||
+		id == NULL )
+	{
+		if ( ld ) {
+			ld->ld_errno = LDAP_PARAM_ERROR;
+		}
+
+		/* NOTE: we want the caller to get all or nothing;
+		 * we could allow some of the pointers to be NULL,
+		 * if one does not want part of the data */
+		return LDAP_PARAM_ERROR;
+	}
+
+	BER_BVZERO( ip );
+	BER_BVZERO( name );
+	BER_BVZERO( oid );
+	BER_BVZERO( id );
+
+	ber = ber_init( &ctrl->ldctl_value );
+
+	if ( ber == NULL ) {
+		ld->ld_errno = LDAP_NO_MEMORY;
+		return ld->ld_errno;
+	}
+
+	tag = ber_skip_tag( ber, &len );
+	if ( tag != LBER_SEQUENCE ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	/* sessionSourceIp */
+	tag = ber_peek_tag( ber, &len );
+	if ( tag == LBER_DEFAULT ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	if ( len == 0 ) {
+		tag = ber_skip_tag( ber, &len );
+
+	} else {
+		if ( len > 128 ) {
+			/* should be LDAP_DECODING_ERROR,
+			 * but we're liberal in what we accept */
+		}
+		tag = ber_scanf( ber, "o", ip );
+	}
+
+	/* sessionSourceName */
+	tag = ber_peek_tag( ber, &len );
+	if ( tag == LBER_DEFAULT ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	if ( len == 0 ) {
+		tag = ber_skip_tag( ber, &len );
+
+	} else {
+		if ( len > 65536 ) {
+			/* should be LDAP_DECODING_ERROR,
+			 * but we're liberal in what we accept */
+		}
+		tag = ber_scanf( ber, "o", name );
+	}
+
+	/* formatOID */
+	tag = ber_peek_tag( ber, &len );
+	if ( tag == LBER_DEFAULT ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	if ( len == 0 ) {
+		ld->ld_errno = LDAP_DECODING_ERROR;
+		goto error;
+
+	} else {
+		if ( len > 1024 ) {
+			/* should be LDAP_DECODING_ERROR,
+			 * but we're liberal in what we accept */
+		}
+		tag = ber_scanf( ber, "o", oid );
+	}
+
+	/* FIXME: should check if it is an OID... leave it to the caller */
+
+	/* sessionTrackingIdentifier */
+	tag = ber_peek_tag( ber, &len );
+	if ( tag == LBER_DEFAULT ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	if ( len == 0 ) {
+		tag = ber_skip_tag( ber, &len );
+
+	} else {
+#if 0
+		if ( len > 65536 ) {
+			/* should be LDAP_DECODING_ERROR,
+			 * but we're liberal in what we accept */
+		}
+#endif
+		tag = ber_scanf( ber, "o", id );
+	}
+
+	/* closure */
+	tag = ber_skip_tag( ber, &len );
+	if ( tag == LBER_DEFAULT && len == 0 ) {
+		tag = 0;
+	}
+
+error:;
+	(void)ber_free( ber, 1 );
+
+	if ( tag == LBER_ERROR ) {
+		return LDAP_DECODING_ERROR;
+	}
+
+	return ld->ld_errno;
+}
+
+#endif /* LDAP_CONTROL_X_SESSION_TRACKING */

Modified: openldap/trunk/libraries/libldap/string.c
===================================================================
--- openldap/trunk/libraries/libldap/string.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/string.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/string.c,v 1.20.2.4 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/string.c,v 1.23.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/t61.c
===================================================================
--- openldap/trunk/libraries/libldap/t61.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/t61.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/t61.c,v 1.7.2.3 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/t61.c,v 1.9.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2002-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/test.c
===================================================================
--- openldap/trunk/libraries/libldap/test.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/test.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/test.c,v 1.50.2.7 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/test.c,v 1.55.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -252,17 +252,7 @@
 	printf("rebind for request=%ld msgid=%ld url=%s\n",
 		request, (long) msgid, url );
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-		get_line( dn, sizeof(dn), stdin,
-		    "re-bind method (0->simple, 1->krbv41, 2->krbv42, 3->krbv41&2)? " );
-	if (( authmethod = atoi( dn )) == 3 ) {
-		authmethod = LDAP_AUTH_KRBV4;
-		} else {
-		authmethod |= 0x80;
-		}
-#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 	authmethod = LDAP_AUTH_SIMPLE;
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 
 		get_line( dn, sizeof(dn), stdin, "re-bind dn? " );
 		strcat( dn, dnsuffix );
@@ -287,7 +277,8 @@
 	char		passwd[64], dn[256], rdn[64], attr[64], value[256];
 	char		filter[256], *host, **types;
 	char		**exdn;
-	char		*usage = "usage: %s [-u] [-h host] [-d level] [-s dnsuffix] [-p port] [-t file] [-T file]\n";
+	static const char usage[] =
+		"usage: %s [-u] [-h host] [-d level] [-s dnsuffix] [-p port] [-t file] [-T file]\n";
 	int		bound, all, scope, attrsonly;
 	LDAPMessage	*res;
 	LDAPMod		**mods, **attrs;
@@ -412,13 +403,7 @@
 			break;
 
 		case 'b':	/* asynch bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-			get_line( line, sizeof(line), stdin,
-			    "method (0->simple, 1->krbv41, 2->krbv42)? " );
-			method = atoi( line ) | 0x80;
-#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 			method = LDAP_AUTH_SIMPLE;
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 			get_line( dn, sizeof(dn), stdin, "dn? " );
 			strcat( dn, dnsuffix );
 
@@ -438,17 +423,7 @@
 			break;
 
 		case 'B':	/* synch bind */
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-			get_line( line, sizeof(line), stdin,
-			    "method 0->simple 1->krbv41 2->krbv42 3->krb? " );
-			method = atoi( line );
-			if ( method == 3 )
-				method = LDAP_AUTH_KRBV4;
-			else
-				method = method | 0x80;
-#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 			method = LDAP_AUTH_SIMPLE;
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
 			get_line( dn, sizeof(dn), stdin, "dn? " );
 			strcat( dn, dnsuffix );
 

Modified: openldap/trunk/libraries/libldap/tls.c
===================================================================
--- openldap/trunk/libraries/libldap/tls.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/tls.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
-/* tls.c - Handle tls/ssl using SSLeay or OpenSSL. */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/tls.c,v 1.118.2.17 2007/01/25 02:28:40 hyc Exp $ */
+/* tls.c - Handle tls/ssl using SSLeay, OpenSSL or GNUTLS. */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/tls.c,v 1.133.2.7 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -13,6 +13,10 @@
  * top-level directory of the distribution or, alternatively, at
  * <http://www.OpenLDAP.org/license.html>.
  */
+/* ACKNOWLEDGEMENTS: GNUTLS support written by Howard Chu and
+ * Matt Backes; sponsored by The Written Word (thewrittenword.com)
+ * and Stanford University (stanford.edu).
+ */
 
 #include "portable.h"
 #include "ldap_config.h"
@@ -37,6 +41,14 @@
 #include <ldap_pvt_thread.h>
 #endif
 
+#ifdef HAVE_GNUTLS
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gcrypt.h>
+
+#define DH_BITS	(1024)
+
+#else
 #ifdef HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
 #include <openssl/x509v3.h>
@@ -46,35 +58,323 @@
 #elif defined( HAVE_SSL_H )
 #include <ssl.h>
 #endif
-
-static int  tls_opt_trace = 1;
-static char *tls_opt_certfile = NULL;
-static char *tls_opt_keyfile = NULL;
-static char *tls_opt_dhfile = NULL;
-static char *tls_opt_cacertfile = NULL;
-static char *tls_opt_cacertdir = NULL;
-static int  tls_opt_require_cert = LDAP_OPT_X_TLS_DEMAND;
-#ifdef HAVE_OPENSSL_CRL
-static int  tls_opt_crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
 #endif
-static char *tls_opt_ciphersuite = NULL;
-static char *tls_opt_randfile = NULL;
 
 #define HAS_TLS( sb )	ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
 				(void *)&sb_tls_sbio )
 
+#endif /* HAVE_TLS */
+
+/* RFC2459 minimum required set of supported attribute types
+ * in a certificate DN
+ */
+typedef struct oid_name {
+	struct berval oid;
+	struct berval name;
+} oid_name;
+
+#define	CN_OID	oids[0].oid.bv_val
+
+static oid_name oids[] = {
+	{ BER_BVC("2.5.4.3"), BER_BVC("cn") },
+	{ BER_BVC("2.5.4.4"), BER_BVC("sn") },
+	{ BER_BVC("2.5.4.6"), BER_BVC("c") },
+	{ BER_BVC("2.5.4.7"), BER_BVC("l") },
+	{ BER_BVC("2.5.4.8"), BER_BVC("st") },
+	{ BER_BVC("2.5.4.10"), BER_BVC("o") },
+	{ BER_BVC("2.5.4.11"), BER_BVC("ou") },
+	{ BER_BVC("2.5.4.12"), BER_BVC("title") },
+	{ BER_BVC("2.5.4.41"), BER_BVC("name") },
+	{ BER_BVC("2.5.4.42"), BER_BVC("givenName") },
+	{ BER_BVC("2.5.4.43"), BER_BVC("initials") },
+	{ BER_BVC("2.5.4.44"), BER_BVC("generationQualifier") },
+	{ BER_BVC("2.5.4.46"), BER_BVC("dnQualifier") },
+	{ BER_BVC("1.2.840.113549.1.9.1"), BER_BVC("email") },
+	{ BER_BVC("0.9.2342.19200300.100.1.25"), BER_BVC("dc") },
+	{ BER_BVNULL, BER_BVNULL }
+};
+
+#ifdef HAVE_TLS
+#ifdef HAVE_GNUTLS
+
+typedef struct tls_cipher_suite {
+	const char *name;
+	gnutls_kx_algorithm_t kx;
+	gnutls_cipher_algorithm_t cipher;
+	gnutls_mac_algorithm_t mac;
+	gnutls_protocol_t version;
+} tls_cipher_suite;
+
+static tls_cipher_suite *ciphers;
+static int n_ciphers;
+
+/* sorta replacing SSL_CTX */
+typedef struct tls_ctx {
+	struct ldapoptions *lo;
+	gnutls_certificate_credentials_t cred;
+	gnutls_dh_params_t dh_params;
+	unsigned long verify_depth;
+	int refcount;
+	int *kx_list;
+	int *cipher_list;
+	int *mac_list;
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_t ref_mutex;
+#endif
+} tls_ctx;
+
+/* sorta replacing SSL */
+typedef struct tls_session {
+	tls_ctx *ctx;
+	gnutls_session_t session;
+	struct berval peer_der_dn;
+} tls_session;
+
+#ifdef LDAP_R_COMPILE
+
+static int
+ldap_pvt_gcry_mutex_init( void **priv )
+{
+	int err = 0;
+	ldap_pvt_thread_mutex_t *lock = LDAP_MALLOC( sizeof( ldap_pvt_thread_mutex_t ));
+
+	if ( !lock )
+		err = ENOMEM;
+	if ( !err ) {
+		err = ldap_pvt_thread_mutex_init( lock );
+		if ( err )
+			LDAP_FREE( lock );
+		else
+			*priv = lock;
+	}
+	return err;
+}
+static int
+ldap_pvt_gcry_mutex_destroy( void **lock )
+{
+	int err = ldap_pvt_thread_mutex_destroy( *lock );
+	LDAP_FREE( *lock );
+	return err;
+}
+static int
+ldap_pvt_gcry_mutex_lock( void **lock )
+{
+	return ldap_pvt_thread_mutex_lock( *lock );
+}
+static int
+ldap_pvt_gcry_mutex_unlock( void **lock )
+{
+	return ldap_pvt_thread_mutex_unlock( *lock );
+}
+
+static struct gcry_thread_cbs ldap_generic_thread_cbs = {
+	GCRY_THREAD_OPTION_USER,
+	NULL,
+	ldap_pvt_gcry_mutex_init,
+	ldap_pvt_gcry_mutex_destroy,
+	ldap_pvt_gcry_mutex_lock,
+	ldap_pvt_gcry_mutex_unlock,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+static void
+tls_init_threads( void )
+{
+	gcry_control (GCRYCTL_SET_THREAD_CBS, &ldap_generic_thread_cbs);
+}
+#endif /* LDAP_R_COMPILE */
+
+void
+ldap_pvt_tls_ctx_free ( void *c )
+{
+	int refcount;
+	tls_ctx *ctx = c;
+
+	if ( !ctx ) return;
+
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_lock( &ctx->ref_mutex );
+#endif
+	refcount = --ctx->refcount;
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_unlock( &ctx->ref_mutex );
+#endif
+	if ( refcount )
+		return;
+	LDAP_FREE( ctx->kx_list );
+	gnutls_certificate_free_credentials( ctx->cred );
+	ber_memfree ( ctx );
+}
+
+static void *
+tls_ctx_new ( struct ldapoptions *lo )
+{
+	tls_ctx *ctx;
+
+	ctx = ber_memcalloc ( 1, sizeof (*ctx) );
+	if ( ctx ) {
+		ctx->lo = lo;
+		if ( gnutls_certificate_allocate_credentials( &ctx->cred )) {
+			ber_memfree( ctx );
+			return NULL;
+		}
+		ctx->refcount = 1;
+#ifdef LDAP_R_COMPILE
+		ldap_pvt_thread_mutex_init( &ctx->ref_mutex );
+#endif
+	}
+	return ctx;
+}
+
+static void
+tls_ctx_ref( tls_ctx *ctx )
+{
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_lock( &ctx->ref_mutex );
+#endif
+	ctx->refcount++;
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_unlock( &ctx->ref_mutex );
+#endif
+}
+
+tls_session *
+tls_session_new ( tls_ctx * ctx, int is_server )
+{
+	tls_session *session;
+
+	session = ber_memcalloc ( 1, sizeof (*session) );
+	if ( !session )
+		return NULL;
+
+	session->ctx = ctx;
+	gnutls_init( &session->session, is_server ? GNUTLS_SERVER : GNUTLS_CLIENT );
+	gnutls_set_default_priority( session->session );
+	if ( ctx->kx_list ) {
+		gnutls_kx_set_priority( session->session, ctx->kx_list );
+		gnutls_cipher_set_priority( session->session, ctx->cipher_list );
+		gnutls_mac_set_priority( session->session, ctx->mac_list );
+	}
+	if ( ctx->cred )
+		gnutls_credentials_set( session->session, GNUTLS_CRD_CERTIFICATE, ctx->cred );
+	
+	if ( is_server ) {
+		int flag = 0;
+		if ( ctx->lo->ldo_tls_require_cert ) {
+			flag = GNUTLS_CERT_REQUEST;
+			if ( ctx->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND ||
+				ctx->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD )
+				flag = GNUTLS_CERT_REQUIRE;
+			gnutls_certificate_server_set_request( session->session, flag );
+		}
+	}
+	return session;
+} 
+
+void
+tls_session_free ( tls_session * session )
+{
+	ber_memfree ( session );
+}
+
+#define	tls_session_connect( ssl )	gnutls_handshake( ssl->session )
+#define	tls_session_accept( ssl )	gnutls_handshake( ssl->session )
+
+/* suites is a string of colon-separated cipher suite names. */
+static int
+tls_parse_ciphers( tls_ctx *ctx, char *suites )
+{
+	char *ptr, *end;
+	int i, j, len, num;
+	int *list, nkx = 0, ncipher = 0, nmac = 0;
+	int *kx, *cipher, *mac;
+
+	num = 0;
+	ptr = suites;
+	do {
+		end = strchr(ptr, ':');
+		if ( end )
+			len = end - ptr;
+		else
+			len = strlen(ptr);
+		for (i=0; i<n_ciphers; i++) {
+			if ( !strncasecmp( ciphers[i].name, ptr, len )) {
+				num++;
+				break;
+			}
+		}
+		if ( i == n_ciphers ) {
+			/* unrecognized cipher suite */
+			return -1;
+		}
+	} while (end);
+
+	/* Space for all 3 lists */
+	list = LDAP_MALLOC( (num+1) * sizeof(int) * 3 );
+	if ( !list )
+		return -1;
+	kx = list;
+	cipher = kx+num+1;
+	mac = cipher+num+1;
+
+	ptr = suites;
+	do {
+		end = strchr(ptr, ':');
+		if ( end )
+			len = end - ptr;
+		else
+			len = strlen(ptr);
+		for (i=0; i<n_ciphers; i++) {
+			/* For each cipher suite, insert its algorithms into
+			 * their respective priority lists. Make sure they
+			 * only appear once in each list.
+			 */
+			if ( !strncasecmp( ciphers[i].name, ptr, len )) {
+				for (j=0; j<nkx; j++)
+					if ( kx[j] == ciphers[i].kx )
+						break;
+				if ( j == nkx )
+					kx[nkx++] = ciphers[i].kx;
+				for (j=0; j<ncipher; j++)
+					if ( cipher[j] == ciphers[i].cipher )
+						break;
+				if ( j == ncipher ) 
+					cipher[ncipher++] = ciphers[i].cipher;
+				for (j=0; j<nmac; j++)
+					if ( mac[j] == ciphers[i].mac )
+						break;
+				if ( j == nmac )
+					mac[nmac++] = ciphers[i].mac;
+				break;
+			}
+		}
+	} while (end);
+	kx[nkx] = 0;
+	cipher[ncipher] = 0;
+	mac[nmac] = 0;
+	ctx->kx_list = kx;
+	ctx->cipher_list = cipher;
+	ctx->mac_list = mac;
+	return 0;
+}
+
+#else /* OpenSSL */
+
+typedef SSL_CTX tls_ctx;
+typedef SSL tls_session;
+
+static int  tls_opt_trace = 1;
+static char *tls_opt_randfile = NULL;
+
 static void tls_report_error( void );
 
 static void tls_info_cb( const SSL *ssl, int where, int ret );
 static int tls_verify_cb( int ok, X509_STORE_CTX *ctx );
 static int tls_verify_ok( int ok, X509_STORE_CTX *ctx );
 static RSA * tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length );
-static STACK_OF(X509_NAME) * get_ca_list( char * bundle, char * dir );
 
 static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
 
-static SSL_CTX *tls_def_ctx = NULL;
-
 typedef struct dhplist {
 	struct dhplist *next;
 	int keylength;
@@ -100,13 +400,19 @@
 	}
 }
 
-/*
- * an extra mutex for the default ctx.
- */
+static unsigned long tls_thread_self( void )
+{
+	/* FIXME: CRYPTO_set_id_callback only works when ldap_pvt_thread_t
+	 * is an integral type that fits in an unsigned long
+	 */
 
-static ldap_pvt_thread_mutex_t tls_def_ctx_mutex;
-static ldap_pvt_thread_mutex_t tls_connect_mutex;
+	/* force an error if the ldap_pvt_thread_t type is too large */
+	enum { ok = sizeof( ldap_pvt_thread_t ) <= sizeof( unsigned long ) };
+	typedef struct { int dummy: ok ? 1 : -1; } Check[ok ? 1 : -1];
 
+	return (unsigned long) ldap_pvt_thread_self();
+}
+
 static void tls_init_threads( void )
 {
 	int i;
@@ -115,57 +421,139 @@
 		ldap_pvt_thread_mutex_init( &tls_mutexes[i] );
 	}
 	CRYPTO_set_locking_callback( tls_locking_cb );
-	CRYPTO_set_id_callback( ldap_pvt_thread_self );
-	/* FIXME: CRYPTO_set_id_callback only works when ldap_pvt_thread_t
-	 * is an integral type that fits in an unsigned long
-	 */
-
-	ldap_pvt_thread_mutex_init( &tls_def_ctx_mutex );
-	ldap_pvt_thread_mutex_init( &tls_connect_mutex );
+	CRYPTO_set_id_callback( tls_thread_self );
 }
 #endif /* LDAP_R_COMPILE */
 
+void
+ldap_pvt_tls_ctx_free ( void *c )
+{
+
+	SSL_CTX_free( c );
+}
+
+static void *
+tls_ctx_new( struct ldapoptions *lo )
+{
+	return SSL_CTX_new( SSLv23_method() );
+}
+
+static void
+tls_ctx_ref( void *c )
+{
+	SSL_CTX *ctx = c;
+	CRYPTO_add( &ctx->references, 1, CRYPTO_LOCK_SSL_CTX );
+}
+
+static tls_session *
+tls_session_new( tls_ctx *ctx, int is_server )
+{
+	return SSL_new( ctx );
+}
+
+#define	tls_session_connect( ssl )	SSL_connect( ssl )
+#define	tls_session_accept( ssl )	SSL_accept( ssl )
+
+static STACK_OF(X509_NAME) *
+get_ca_list( char * bundle, char * dir )
+{
+	STACK_OF(X509_NAME) *ca_list = NULL;
+
+	if ( bundle ) {
+		ca_list = SSL_load_client_CA_file( bundle );
+	}
+#if defined(HAVE_DIRENT_H) || defined(dirent)
+	if ( dir ) {
+		int freeit = 0;
+
+		if ( !ca_list ) {
+			ca_list = sk_X509_NAME_new_null();
+			freeit = 1;
+		}
+		if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
+			freeit ) {
+			sk_X509_NAME_free( ca_list );
+			ca_list = NULL;
+		}
+	}
+#endif
+	return ca_list;
+}
+
+#endif /* HAVE_GNUTLS */
+
+#ifdef LDAP_R_COMPILE
 /*
+ * an extra mutex for the default ctx.
+ */
+static ldap_pvt_thread_mutex_t tls_def_ctx_mutex;
+#endif
+
+void
+ldap_int_tls_destroy( struct ldapoptions *lo )
+{
+	if ( lo->ldo_tls_ctx ) {
+		ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
+		lo->ldo_tls_ctx = NULL;
+	}
+
+	if ( lo->ldo_tls_certfile ) {
+		LDAP_FREE( lo->ldo_tls_certfile );
+		lo->ldo_tls_certfile = NULL;
+	}
+	if ( lo->ldo_tls_keyfile ) {
+		LDAP_FREE( lo->ldo_tls_keyfile );
+		lo->ldo_tls_keyfile = NULL;
+	}
+	if ( lo->ldo_tls_dhfile ) {
+		LDAP_FREE( lo->ldo_tls_dhfile );
+		lo->ldo_tls_dhfile = NULL;
+	}
+	if ( lo->ldo_tls_cacertfile ) {
+		LDAP_FREE( lo->ldo_tls_cacertfile );
+		lo->ldo_tls_cacertfile = NULL;
+	}
+	if ( lo->ldo_tls_cacertdir ) {
+		LDAP_FREE( lo->ldo_tls_cacertdir );
+		lo->ldo_tls_cacertdir = NULL;
+	}
+	if ( lo->ldo_tls_ciphersuite ) {
+		LDAP_FREE( lo->ldo_tls_ciphersuite );
+		lo->ldo_tls_ciphersuite = NULL;
+	}
+#ifdef HAVE_GNUTLS
+	if ( lo->ldo_tls_crlfile ) {
+		LDAP_FREE( lo->ldo_tls_crlfile );
+		lo->ldo_tls_crlfile = NULL;
+	}
+#endif
+}
+
+/*
  * Tear down the TLS subsystem. Should only be called once.
  */
 void
 ldap_pvt_tls_destroy( void )
 {
-	SSL_CTX_free(tls_def_ctx);
-	tls_def_ctx = NULL;
+	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   
 
+	ldap_int_tls_destroy( lo );
+
+#ifdef HAVE_GNUTLS
+	LDAP_FREE( ciphers );
+	ciphers = NULL;
+
+	gnutls_global_deinit();
+#else
 	EVP_cleanup();
 	ERR_remove_state(0);
 	ERR_free_strings();
 
-	if ( tls_opt_certfile ) {
-		LDAP_FREE( tls_opt_certfile );
-		tls_opt_certfile = NULL;
-	}
-	if ( tls_opt_keyfile ) {
-		LDAP_FREE( tls_opt_keyfile );
-		tls_opt_keyfile = NULL;
-	}
-	if ( tls_opt_dhfile ) {
-		LDAP_FREE( tls_opt_dhfile );
-		tls_opt_dhfile = NULL;
-	}
-	if ( tls_opt_cacertfile ) {
-		LDAP_FREE( tls_opt_cacertfile );
-		tls_opt_cacertfile = NULL;
-	}
-	if ( tls_opt_cacertdir ) {
-		LDAP_FREE( tls_opt_cacertdir );
-		tls_opt_cacertdir = NULL;
-	}
-	if ( tls_opt_ciphersuite ) {
-		LDAP_FREE( tls_opt_ciphersuite );
-		tls_opt_ciphersuite = NULL;
-	}
 	if ( tls_opt_randfile ) {
 		LDAP_FREE( tls_opt_randfile );
 		tls_opt_randfile = NULL;
 	}
+#endif
 }
 
 /*
@@ -178,6 +566,43 @@
 
 	if ( tls_initialized++ ) return 0;
 
+#ifdef LDAP_R_COMPILE
+	tls_init_threads();
+	ldap_pvt_thread_mutex_init( &tls_def_ctx_mutex );
+#endif
+
+#ifdef HAVE_GNUTLS
+	gnutls_global_init ();
+
+	/* GNUtls cipher suite handling: The library ought to parse suite
+	 * names for us, but it doesn't. It will return a list of suite names
+	 * that it supports, so we can do parsing ourselves. It ought to tell
+	 * us how long the list is, but it doesn't do that either, so we just
+	 * have to count it manually...
+	 */
+	{
+		int i = 0;
+		tls_cipher_suite *ptr, tmp;
+		char cs_id[2];
+
+		while ( gnutls_cipher_suite_info( i, cs_id, &tmp.kx, &tmp.cipher,
+			&tmp.mac, &tmp.version ))
+			i++;
+		n_ciphers = i;
+
+		/* Store a copy */
+		ciphers = LDAP_MALLOC(n_ciphers * sizeof(tls_cipher_suite));
+		if ( !ciphers )
+			return -1;
+		for ( i=0; i<n_ciphers; i++ ) {
+			ciphers[i].name = gnutls_cipher_suite_info( i, cs_id,
+				&ciphers[i].kx, &ciphers[i].cipher, &ciphers[i].mac,
+				&ciphers[i].version );
+		}
+	}
+
+#else /* !HAVE_GNUTLS */
+
 #ifdef HAVE_EBCDIC
 	{
 		char *file = LDAP_STRDUP( tls_opt_randfile );
@@ -189,42 +614,41 @@
 	(void) tls_seed_PRNG( tls_opt_randfile );
 #endif
 
-#ifdef LDAP_R_COMPILE
-	tls_init_threads();
-#endif
-
 	SSL_load_error_strings();
 	SSLeay_add_ssl_algorithms();
 
 	/* FIXME: mod_ssl does this */
 	X509V3_add_standard_extensions();
+
+#endif /* HAVE_GNUTLS */
 	return 0;
 }
 
 /*
- * initialize the default context
+ * initialize a new TLS context
  */
-int
-ldap_pvt_tls_init_def_ctx( int is_server )
+static int
+ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server )
 {
-	STACK_OF(X509_NAME) *calist;
-	int rc = 0;
-	char *ciphersuite = tls_opt_ciphersuite;
-	char *cacertfile = tls_opt_cacertfile;
-	char *cacertdir = tls_opt_cacertdir;
-	char *certfile = tls_opt_certfile;
-	char *keyfile = tls_opt_keyfile;
-	char *dhfile = tls_opt_dhfile;
-
-#ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
+	int i, rc = 0;
+	char *ciphersuite = lo->ldo_tls_ciphersuite;
+	char *cacertfile = lo->ldo_tls_cacertfile;
+	char *cacertdir = lo->ldo_tls_cacertdir;
+	char *certfile = lo->ldo_tls_certfile;
+	char *keyfile = lo->ldo_tls_keyfile;
+#ifdef HAVE_GNUTLS
+	char *crlfile = lo->ldo_tls_crlfile;
+#else
+	char *dhfile = lo->ldo_tls_dhfile;
 #endif
 
+	if ( lo->ldo_tls_ctx )
+		return 0;
+
+	ldap_pvt_tls_init();
+
 	if ( is_server && !certfile && !keyfile && !cacertfile && !cacertdir ) {
 		/* minimum configuration not provided */
-#ifdef LDAP_R_COMPILE
-		ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
-#endif
 		return LDAP_NOT_SUPPORTED;
 	}
 
@@ -238,10 +662,6 @@
 		cacertfile = LDAP_STRDUP( cacertfile );
 		__atoe( cacertfile );
 	}
-	if ( cacertdir ) {
-		cacertdir = LDAP_STRDUP( cacertdir );
-		__atoe( cacertdir );
-	}
 	if ( certfile ) {
 		certfile = LDAP_STRDUP( certfile );
 		__atoe( certfile );
@@ -250,217 +670,287 @@
 		keyfile = LDAP_STRDUP( keyfile );
 		__atoe( keyfile );
 	}
+#ifdef HAVE_GNUTLS
+	if ( crlfile ) {
+		crlfile = LDAP_STRDUP( crlfile );
+		__atoe( crlfile );
+	}
+#else
+	if ( cacertdir ) {
+		cacertdir = LDAP_STRDUP( cacertdir );
+		__atoe( cacertdir );
+	}
 	if ( dhfile ) {
 		dhfile = LDAP_STRDUP( dhfile );
 		__atoe( dhfile );
 	}
 #endif
-	if ( tls_def_ctx == NULL ) {
-		int i;
-		tls_def_ctx = SSL_CTX_new( SSLv23_method() );
-		if ( tls_def_ctx == NULL ) {
-			Debug( LDAP_DEBUG_ANY,
-			   "TLS: could not allocate default ctx (%lu).\n",
-				ERR_peek_error(),0,0);
-			rc = -1;
-			goto error_exit;
-		}
+#endif
+	lo->ldo_tls_ctx = tls_ctx_new( lo );
+	if ( lo->ldo_tls_ctx == NULL ) {
+#ifdef HAVE_GNUTLS
+		Debug( LDAP_DEBUG_ANY,
+		   "TLS: could not allocate default ctx.\n",
+			0,0,0);
+#else
+		Debug( LDAP_DEBUG_ANY,
+		   "TLS: could not allocate default ctx (%lu).\n",
+			ERR_peek_error(),0,0);
+#endif
+		rc = -1;
+		goto error_exit;
+	}
 
-		SSL_CTX_set_session_id_context( tls_def_ctx,
+#ifdef HAVE_GNUTLS
+ 	if ( lo->ldo_tls_ciphersuite &&
+		tls_parse_ciphers( lo->ldo_tls_ctx,
+			ciphersuite )) {
+ 		Debug( LDAP_DEBUG_ANY,
+ 			   "TLS: could not set cipher list %s.\n",
+ 			   lo->ldo_tls_ciphersuite, 0, 0 );
+ 		rc = -1;
+ 		goto error_exit;
+ 	}
+
+	if (lo->ldo_tls_cacertdir != NULL) {
+		Debug( LDAP_DEBUG_ANY, 
+		       "TLS: warning: cacertdir not implemented for gnutls\n",
+		       NULL, NULL, NULL );
+	}
+
+	if (lo->ldo_tls_cacertfile != NULL) {
+		rc = gnutls_certificate_set_x509_trust_file( 
+			((tls_ctx*) lo->ldo_tls_ctx)->cred,
+			cacertfile,
+			GNUTLS_X509_FMT_PEM );
+		if ( rc < 0 ) goto error_exit;
+	}
+
+	if ( lo->ldo_tls_certfile && lo->ldo_tls_keyfile ) {
+		rc = gnutls_certificate_set_x509_key_file( 
+			((tls_ctx*) lo->ldo_tls_ctx)->cred,
+			certfile,
+			keyfile,
+			GNUTLS_X509_FMT_PEM );
+		if ( rc ) goto error_exit;
+	} else if ( lo->ldo_tls_certfile || lo->ldo_tls_keyfile ) {
+		Debug( LDAP_DEBUG_ANY, 
+		       "TLS: only one of certfile and keyfile specified\n",
+		       NULL, NULL, NULL );
+		rc = 1;
+		goto error_exit;
+	}
+
+	if ( lo->ldo_tls_dhfile ) {
+		Debug( LDAP_DEBUG_ANY, 
+		       "TLS: warning: ignoring dhfile\n", 
+		       NULL, NULL, NULL );
+	}
+
+	if ( lo->ldo_tls_crlfile ) {
+		rc = gnutls_certificate_set_x509_crl_file( 
+			((tls_ctx*) lo->ldo_tls_ctx)->cred,
+			crlfile,
+			GNUTLS_X509_FMT_PEM );
+		if ( rc < 0 ) goto error_exit;
+	}
+	if ( is_server ) {
+		gnutls_dh_params_init (&((tls_ctx*) 
+					lo->ldo_tls_ctx)->dh_params);
+		gnutls_dh_params_generate2 (((tls_ctx*) 
+						 lo->ldo_tls_ctx)->dh_params, 
+						DH_BITS);
+	}
+
+#else /* !HAVE_GNUTLS */
+
+	if ( is_server ) {
+		SSL_CTX_set_session_id_context( lo->ldo_tls_ctx,
 			(const unsigned char *) "OpenLDAP", sizeof("OpenLDAP")-1 );
+	}
 
-		if ( tls_opt_ciphersuite &&
-			!SSL_CTX_set_cipher_list( tls_def_ctx, ciphersuite ) )
+	if ( lo->ldo_tls_ciphersuite &&
+		!SSL_CTX_set_cipher_list( lo->ldo_tls_ctx, ciphersuite ) )
+	{
+		Debug( LDAP_DEBUG_ANY,
+			   "TLS: could not set cipher list %s.\n",
+			   lo->ldo_tls_ciphersuite, 0, 0 );
+		tls_report_error();
+		rc = -1;
+		goto error_exit;
+	}
+
+	if (lo->ldo_tls_cacertfile != NULL || lo->ldo_tls_cacertdir != NULL) {
+		if ( !SSL_CTX_load_verify_locations( lo->ldo_tls_ctx,
+				cacertfile, cacertdir ) ||
+			!SSL_CTX_set_default_verify_paths( lo->ldo_tls_ctx ) )
 		{
-			Debug( LDAP_DEBUG_ANY,
-				   "TLS: could not set cipher list %s.\n",
-				   tls_opt_ciphersuite, 0, 0 );
+			Debug( LDAP_DEBUG_ANY, "TLS: "
+				"could not load verify locations (file:`%s',dir:`%s').\n",
+				lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
+				lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "",
+				0 );
 			tls_report_error();
 			rc = -1;
 			goto error_exit;
 		}
 
-		if (tls_opt_cacertfile != NULL || tls_opt_cacertdir != NULL) {
-			if ( !SSL_CTX_load_verify_locations( tls_def_ctx,
-					cacertfile, cacertdir ) ||
-				!SSL_CTX_set_default_verify_paths( tls_def_ctx ) )
-			{
-				Debug( LDAP_DEBUG_ANY, "TLS: "
-					"could not load verify locations (file:`%s',dir:`%s').\n",
-					tls_opt_cacertfile ? tls_opt_cacertfile : "",
-					tls_opt_cacertdir ? tls_opt_cacertdir : "",
-					0 );
-				tls_report_error();
-				rc = -1;
-				goto error_exit;
-			}
-
+		if ( is_server ) {
+			STACK_OF(X509_NAME) *calist;
+			/* List of CA names to send to a client */
 			calist = get_ca_list( cacertfile, cacertdir );
 			if ( !calist ) {
 				Debug( LDAP_DEBUG_ANY, "TLS: "
 					"could not load client CA list (file:`%s',dir:`%s').\n",
-					tls_opt_cacertfile ? tls_opt_cacertfile : "",
-					tls_opt_cacertdir ? tls_opt_cacertdir : "",
+					lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
+					lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "",
 					0 );
 				tls_report_error();
 				rc = -1;
 				goto error_exit;
 			}
 
-			SSL_CTX_set_client_CA_list( tls_def_ctx, calist );
+			SSL_CTX_set_client_CA_list( lo->ldo_tls_ctx, calist );
 		}
+	}
 
-		if ( tls_opt_keyfile &&
-			!SSL_CTX_use_PrivateKey_file( tls_def_ctx,
-				keyfile, SSL_FILETYPE_PEM ) )
-		{
-			Debug( LDAP_DEBUG_ANY,
-				"TLS: could not use key file `%s'.\n",
-				tls_opt_keyfile,0,0);
-			tls_report_error();
-			rc = -1;
-			goto error_exit;
-		}
+	if ( lo->ldo_tls_certfile &&
+		!SSL_CTX_use_certificate_file( lo->ldo_tls_ctx,
+			certfile, SSL_FILETYPE_PEM ) )
+	{
+		Debug( LDAP_DEBUG_ANY,
+			"TLS: could not use certificate `%s'.\n",
+			lo->ldo_tls_certfile,0,0);
+		tls_report_error();
+		rc = -1;
+		goto error_exit;
+	}
 
-		if ( tls_opt_certfile &&
-			!SSL_CTX_use_certificate_file( tls_def_ctx,
-				certfile, SSL_FILETYPE_PEM ) )
-		{
-			Debug( LDAP_DEBUG_ANY,
-				"TLS: could not use certificate `%s'.\n",
-				tls_opt_certfile,0,0);
-			tls_report_error();
-			rc = -1;
-			goto error_exit;
-		}
+	/* Key validity is checked automatically if cert has already been set */
+	if ( lo->ldo_tls_keyfile &&
+		!SSL_CTX_use_PrivateKey_file( lo->ldo_tls_ctx,
+			keyfile, SSL_FILETYPE_PEM ) )
+	{
+		Debug( LDAP_DEBUG_ANY,
+			"TLS: could not use key file `%s'.\n",
+			lo->ldo_tls_keyfile,0,0);
+		tls_report_error();
+		rc = -1;
+		goto error_exit;
+	}
 
-		if ( ( tls_opt_certfile || tls_opt_keyfile ) &&
-			!SSL_CTX_check_private_key( tls_def_ctx ) )
-		{
+	if ( lo->ldo_tls_dhfile ) {
+		DH *dh = NULL;
+		BIO *bio;
+		dhplist *p;
+
+		if (( bio=BIO_new_file( dhfile,"r" )) == NULL ) {
 			Debug( LDAP_DEBUG_ANY,
-				"TLS: private key mismatch.\n",
-				0,0,0);
+				"TLS: could not use DH parameters file `%s'.\n",
+				lo->ldo_tls_dhfile,0,0);
 			tls_report_error();
 			rc = -1;
 			goto error_exit;
 		}
-
-		if ( tls_opt_dhfile ) {
-			DH *dh = NULL;
-			BIO *bio;
-			dhplist *p;
-
-			if (( bio=BIO_new_file( dhfile,"r" )) == NULL ) {
-				Debug( LDAP_DEBUG_ANY,
-					"TLS: could not use DH parameters file `%s'.\n",
-					tls_opt_dhfile,0,0);
-				tls_report_error();
-				rc = -1;
-				goto error_exit;
+		while (( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
+			p = LDAP_MALLOC( sizeof(dhplist) );
+			if ( p != NULL ) {
+				p->keylength = DH_size( dh ) * 8;
+				p->param = dh;
+				p->next = dhparams;
+				dhparams = p;
 			}
-			while (( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
-				p = LDAP_MALLOC( sizeof(dhplist) );
-				if ( p != NULL ) {
-					p->keylength = DH_size( dh ) * 8;
-					p->param = dh;
-					p->next = dhparams;
-					dhparams = p;
-				}
-			}
-			BIO_free( bio );
 		}
+		BIO_free( bio );
+	}
 
-		if ( tls_opt_trace ) {
-			SSL_CTX_set_info_callback( tls_def_ctx, tls_info_cb );
-		}
+	if ( tls_opt_trace ) {
+		SSL_CTX_set_info_callback( (SSL_CTX *)lo->ldo_tls_ctx, tls_info_cb );
+	}
 
-		i = SSL_VERIFY_NONE;
-		if ( tls_opt_require_cert ) {
-			i = SSL_VERIFY_PEER;
-			if ( tls_opt_require_cert == LDAP_OPT_X_TLS_DEMAND ||
-				 tls_opt_require_cert == LDAP_OPT_X_TLS_HARD ) {
-				i |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
-			}
+	i = SSL_VERIFY_NONE;
+	if ( lo->ldo_tls_require_cert ) {
+		i = SSL_VERIFY_PEER;
+		if ( lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND ||
+			 lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD ) {
+			i |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
 		}
+	}
 
-		SSL_CTX_set_verify( tls_def_ctx, i,
-			tls_opt_require_cert == LDAP_OPT_X_TLS_ALLOW ?
-			tls_verify_ok : tls_verify_cb );
-		SSL_CTX_set_tmp_rsa_callback( tls_def_ctx, tls_tmp_rsa_cb );
-		if ( tls_opt_dhfile ) {
-			SSL_CTX_set_tmp_dh_callback( tls_def_ctx, tls_tmp_dh_cb );
-		}
+	SSL_CTX_set_verify( lo->ldo_tls_ctx, i,
+		lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_ALLOW ?
+		tls_verify_ok : tls_verify_cb );
+	SSL_CTX_set_tmp_rsa_callback( lo->ldo_tls_ctx, tls_tmp_rsa_cb );
+	if ( lo->ldo_tls_dhfile ) {
+		SSL_CTX_set_tmp_dh_callback( lo->ldo_tls_ctx, tls_tmp_dh_cb );
+	}
 #ifdef HAVE_OPENSSL_CRL
-		if ( tls_opt_crlcheck ) {
-			X509_STORE *x509_s = SSL_CTX_get_cert_store( tls_def_ctx );
-			if ( tls_opt_crlcheck == LDAP_OPT_X_TLS_CRL_PEER ) {
-				X509_STORE_set_flags( x509_s, X509_V_FLAG_CRL_CHECK );
-			} else if ( tls_opt_crlcheck == LDAP_OPT_X_TLS_CRL_ALL ) {
-				X509_STORE_set_flags( x509_s, 
-						X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL  );
-			}
+	if ( lo->ldo_tls_crlcheck ) {
+		X509_STORE *x509_s = SSL_CTX_get_cert_store( lo->ldo_tls_ctx );
+		if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_PEER ) {
+			X509_STORE_set_flags( x509_s, X509_V_FLAG_CRL_CHECK );
+		} else if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_ALL ) {
+			X509_STORE_set_flags( x509_s, 
+					X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL  );
 		}
+	}
 #endif
-	}
+
+#endif /* HAVE_GNUTLS */
+
 error_exit:
-	if ( rc == -1 && tls_def_ctx != NULL ) {
-		SSL_CTX_free( tls_def_ctx );
-		tls_def_ctx = NULL;
+	if ( rc == -1 && lo->ldo_tls_ctx != NULL ) {
+		ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
+		lo->ldo_tls_ctx = NULL;
 	}
 #ifdef HAVE_EBCDIC
 	LDAP_FREE( ciphersuite );
 	LDAP_FREE( cacertfile );
-	LDAP_FREE( cacertdir );
 	LDAP_FREE( certfile );
 	LDAP_FREE( keyfile );
+#ifdef HAVE_GNUTLS
+	LDAP_FREE( crlfile );
+#else
+	LDAP_FREE( cacertdir );
 	LDAP_FREE( dhfile );
 #endif
-#ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
 #endif
 	return rc;
 }
 
-static STACK_OF(X509_NAME) *
-get_ca_list( char * bundle, char * dir )
+/*
+ * initialize the default context
+ */
+int
+ldap_pvt_tls_init_def_ctx( int is_server )
 {
-	STACK_OF(X509_NAME) *ca_list = NULL;
-
-	if ( bundle ) {
-		ca_list = SSL_load_client_CA_file( bundle );
-	}
-#if defined(HAVE_DIRENT_H) || defined(dirent)
-	if ( dir ) {
-		int freeit = 0;
-
-		if ( !ca_list ) {
-			ca_list = sk_X509_NAME_new_null();
-			freeit = 1;
-		}
-		if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
-			freeit ) {
-			sk_X509_NAME_free( ca_list );
-			ca_list = NULL;
-		}
-	}
+	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   
+	int rc;
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
 #endif
-	return ca_list;
+	rc = ldap_int_tls_init_ctx( lo, is_server );
+#ifdef LDAP_R_COMPILE
+	ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
+#endif
+	return rc;
 }
 
-static SSL *
+static tls_session *
 alloc_handle( void *ctx_arg, int is_server )
 {
-	SSL_CTX	*ctx;
-	SSL	*ssl;
+	tls_ctx	*ctx;
+	tls_session	*ssl;
 
 	if ( ctx_arg ) {
-		ctx = (SSL_CTX *) ctx_arg;
+		ctx = ctx_arg;
 	} else {
+		struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   
 		if ( ldap_pvt_tls_init_def_ctx( is_server ) < 0 ) return NULL;
-		ctx = tls_def_ctx;
+		ctx = lo->ldo_tls_ctx;
 	}
 
-	ssl = SSL_new( ctx );
+	ssl = tls_session_new( ctx, is_server );
 	if ( ssl == NULL ) {
 		Debug( LDAP_DEBUG_ANY,"TLS: can't create ssl handle.\n",0,0,0);
 		return NULL;
@@ -469,24 +959,37 @@
 }
 
 static int
-update_flags( Sockbuf *sb, SSL * ssl, int rc )
+update_flags( Sockbuf *sb, tls_session * ssl, int rc )
 {
-	int err = SSL_get_error(ssl, rc);
-
 	sb->sb_trans_needs_read  = 0;
 	sb->sb_trans_needs_write = 0;
 
-	if (err == SSL_ERROR_WANT_READ) {
+#ifdef HAVE_GNUTLS
+	if ( rc != GNUTLS_E_INTERRUPTED && rc != GNUTLS_E_AGAIN )
+		return 0;
+
+	switch (gnutls_record_get_direction (ssl->session)) {
+	case 0: 
+		sb->sb_trans_needs_read = 1;
+		return 1;
+	case 1:
+		sb->sb_trans_needs_write = 1;
+		return 1;
+	}
+#else /* !HAVE_GNUTLS */
+	rc = SSL_get_error(ssl, rc);
+	if (rc == SSL_ERROR_WANT_READ) {
 		sb->sb_trans_needs_read  = 1;
 		return 1;
 
-	} else if (err == SSL_ERROR_WANT_WRITE) {
+	} else if (rc == SSL_ERROR_WANT_WRITE) {
 		sb->sb_trans_needs_write = 1;
 		return 1;
 
-	} else if (err == SSL_ERROR_WANT_CONNECT) {
+	} else if (rc == SSL_ERROR_WANT_CONNECT) {
 		return 1;
 	}
+#endif /* HAVE_GNUTLS */
 	return 0;
 }
 
@@ -495,17 +998,49 @@
  */
 
 struct tls_data {
-	SSL			*ssl;
+	tls_session			*ssl;
 	Sockbuf_IO_Desc		*sbiod;
 };
 
-static BIO_METHOD sb_tls_bio_method;
+#ifdef HAVE_GNUTLS
 
+static ssize_t
+sb_gtls_recv( gnutls_transport_ptr_t ptr, void *buf, size_t len )
+{
+	struct tls_data		*p;
+
+	if ( buf == NULL || len <= 0 ) return 0;
+
+	p = (struct tls_data *)ptr;
+
+	if ( p == NULL || p->sbiod == NULL ) {
+		return 0;
+	}
+
+	return LBER_SBIOD_READ_NEXT( p->sbiod, buf, len );
+}
+
+static ssize_t
+sb_gtls_send( gnutls_transport_ptr_t ptr, const void *buf, size_t len )
+{
+	struct tls_data		*p;
+	
+	if ( buf == NULL || len <= 0 ) return 0;
+	
+	p = (struct tls_data *)ptr;
+
+	if ( p == NULL || p->sbiod == NULL ) {
+		return 0;
+	}
+
+	return LBER_SBIOD_WRITE_NEXT( p->sbiod, (char *)buf, len );
+}
+
 static int
 sb_tls_setup( Sockbuf_IO_Desc *sbiod, void *arg )
 {
 	struct tls_data		*p;
-	BIO			*bio;
+	tls_session	*session = arg;
 
 	assert( sbiod != NULL );
 
@@ -514,11 +1049,11 @@
 		return -1;
 	}
 	
-	p->ssl = (SSL *)arg;
+	gnutls_transport_set_ptr( session->session, (gnutls_transport_ptr)p );
+	gnutls_transport_set_pull_function( session->session, sb_gtls_recv );
+	gnutls_transport_set_push_function( session->session, sb_gtls_send );
+	p->ssl = arg;
 	p->sbiod = sbiod;
-	bio = BIO_new( &sb_tls_bio_method );
-	bio->ptr = (void *)p;
-	SSL_set_bio( p->ssl, bio, bio );
 	sbiod->sbiod_pvt = p;
 	return 0;
 }
@@ -532,7 +1067,8 @@
 	assert( sbiod->sbiod_pvt != NULL );
 
 	p = (struct tls_data *)sbiod->sbiod_pvt;
-	SSL_free( p->ssl );
+	gnutls_deinit ( p->ssl->session );
+	LBER_FREE( p->ssl );
 	LBER_FREE( sbiod->sbiod_pvt );
 	sbiod->sbiod_pvt = NULL;
 	return 0;
@@ -547,7 +1083,7 @@
 	assert( sbiod->sbiod_pvt != NULL );
 
 	p = (struct tls_data *)sbiod->sbiod_pvt;
-	SSL_shutdown( p->ssl );
+	gnutls_bye ( p->ssl->session, GNUTLS_SHUT_RDWR );
 	return 0;
 }
 
@@ -562,11 +1098,11 @@
 	p = (struct tls_data *)sbiod->sbiod_pvt;
 	
 	if ( opt == LBER_SB_OPT_GET_SSL ) {
-		*((SSL **)arg) = p->ssl;
+		*((tls_session **)arg) = p->ssl;
 		return 1;
-
+		
 	} else if ( opt == LBER_SB_OPT_DATA_READY ) {
-		if( SSL_pending( p->ssl ) > 0 ) {
+		if( gnutls_record_check_pending( p->ssl->session ) > 0 ) {
 			return 1;
 		}
 	}
@@ -586,17 +1122,24 @@
 
 	p = (struct tls_data *)sbiod->sbiod_pvt;
 
-	ret = SSL_read( p->ssl, (char *)buf, len );
-#ifdef HAVE_WINSOCK
-	errno = WSAGetLastError();
-#endif
-	err = SSL_get_error( p->ssl, ret );
-	if (err == SSL_ERROR_WANT_READ ) {
+	ret = gnutls_record_recv ( p->ssl->session, buf, len );
+	switch (ret) {
+	case GNUTLS_E_INTERRUPTED:
+	case GNUTLS_E_AGAIN:
 		sbiod->sbiod_sb->sb_trans_needs_read = 1;
 		sock_errset(EWOULDBLOCK);
+		ret = 0;
+		break;
+	case GNUTLS_E_REHANDSHAKE:
+		for ( ret = gnutls_handshake ( p->ssl->session );
+		      ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN;
+		      ret = gnutls_handshake ( p->ssl->session ) );
+		sbiod->sbiod_sb->sb_trans_needs_read = 1;
+		ret = 0;
+		break;
+	default:
+		sbiod->sbiod_sb->sb_trans_needs_read = 0;
 	}
-	else
-		sbiod->sbiod_sb->sb_trans_needs_read = 0;
 	return ret;
 }
 
@@ -612,30 +1155,19 @@
 
 	p = (struct tls_data *)sbiod->sbiod_pvt;
 
-	ret = SSL_write( p->ssl, (char *)buf, len );
-#ifdef HAVE_WINSOCK
-	errno = WSAGetLastError();
-#endif
-	err = SSL_get_error( p->ssl, ret );
-	if (err == SSL_ERROR_WANT_WRITE ) {
+	ret = gnutls_record_send ( p->ssl->session, (char *)buf, len );
+
+	if ( ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN ) {
 		sbiod->sbiod_sb->sb_trans_needs_write = 1;
 		sock_errset(EWOULDBLOCK);
-
+		ret = 0;
 	} else {
 		sbiod->sbiod_sb->sb_trans_needs_write = 0;
 	}
 	return ret;
 }
 
-static Sockbuf_IO sb_tls_sbio =
-{
-	sb_tls_setup,		/* sbi_setup */
-	sb_tls_remove,		/* sbi_remove */
-	sb_tls_ctrl,		/* sbi_ctrl */
-	sb_tls_read,		/* sbi_read */
-	sb_tls_write,		/* sbi_write */
-	sb_tls_close		/* sbi_close */
-};
+#else /* !HAVE_GNUTLS */
 
 static int
 sb_tls_bio_create( BIO *b ) {
@@ -746,6 +1278,178 @@
 	sb_tls_bio_destroy
 };
 
+static int
+sb_tls_setup( Sockbuf_IO_Desc *sbiod, void *arg )
+{
+	struct tls_data		*p;
+	BIO			*bio;
+
+	assert( sbiod != NULL );
+
+	p = LBER_MALLOC( sizeof( *p ) );
+	if ( p == NULL ) {
+		return -1;
+	}
+	
+	p->ssl = (SSL *)arg;
+	p->sbiod = sbiod;
+	bio = BIO_new( &sb_tls_bio_method );
+	bio->ptr = (void *)p;
+	SSL_set_bio( p->ssl, bio, bio );
+	sbiod->sbiod_pvt = p;
+	return 0;
+}
+
+static int
+sb_tls_remove( Sockbuf_IO_Desc *sbiod )
+{
+	struct tls_data		*p;
+	
+	assert( sbiod != NULL );
+	assert( sbiod->sbiod_pvt != NULL );
+
+	p = (struct tls_data *)sbiod->sbiod_pvt;
+	SSL_free( p->ssl );
+	LBER_FREE( sbiod->sbiod_pvt );
+	sbiod->sbiod_pvt = NULL;
+	return 0;
+}
+
+static int
+sb_tls_close( Sockbuf_IO_Desc *sbiod )
+{
+	struct tls_data		*p;
+	
+	assert( sbiod != NULL );
+	assert( sbiod->sbiod_pvt != NULL );
+
+	p = (struct tls_data *)sbiod->sbiod_pvt;
+	SSL_shutdown( p->ssl );
+	return 0;
+}
+
+static int
+sb_tls_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
+{
+	struct tls_data		*p;
+	
+	assert( sbiod != NULL );
+	assert( sbiod->sbiod_pvt != NULL );
+
+	p = (struct tls_data *)sbiod->sbiod_pvt;
+	
+	if ( opt == LBER_SB_OPT_GET_SSL ) {
+		*((SSL **)arg) = p->ssl;
+		return 1;
+
+	} else if ( opt == LBER_SB_OPT_DATA_READY ) {
+		if( SSL_pending( p->ssl ) > 0 ) {
+			return 1;
+		}
+	}
+	
+	return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
+}
+
+static ber_slen_t
+sb_tls_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+	struct tls_data		*p;
+	ber_slen_t		ret;
+	int			err;
+
+	assert( sbiod != NULL );
+	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+
+	p = (struct tls_data *)sbiod->sbiod_pvt;
+
+	ret = SSL_read( p->ssl, (char *)buf, len );
+#ifdef HAVE_WINSOCK
+	errno = WSAGetLastError();
+#endif
+	err = SSL_get_error( p->ssl, ret );
+	if (err == SSL_ERROR_WANT_READ ) {
+		sbiod->sbiod_sb->sb_trans_needs_read = 1;
+		sock_errset(EWOULDBLOCK);
+	}
+	else
+		sbiod->sbiod_sb->sb_trans_needs_read = 0;
+	return ret;
+}
+
+static ber_slen_t
+sb_tls_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+	struct tls_data		*p;
+	ber_slen_t		ret;
+	int			err;
+
+	assert( sbiod != NULL );
+	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+
+	p = (struct tls_data *)sbiod->sbiod_pvt;
+
+	ret = SSL_write( p->ssl, (char *)buf, len );
+#ifdef HAVE_WINSOCK
+	errno = WSAGetLastError();
+#endif
+	err = SSL_get_error( p->ssl, ret );
+	if (err == SSL_ERROR_WANT_WRITE ) {
+		sbiod->sbiod_sb->sb_trans_needs_write = 1;
+		sock_errset(EWOULDBLOCK);
+
+	} else {
+		sbiod->sbiod_sb->sb_trans_needs_write = 0;
+	}
+	return ret;
+}
+
+#endif
+
+static Sockbuf_IO sb_tls_sbio =
+{
+	sb_tls_setup,		/* sbi_setup */
+	sb_tls_remove,		/* sbi_remove */
+	sb_tls_ctrl,		/* sbi_ctrl */
+	sb_tls_read,		/* sbi_read */
+	sb_tls_write,		/* sbi_write */
+	sb_tls_close		/* sbi_close */
+};
+
+#ifdef HAVE_GNUTLS
+/* Certs are not automatically varified during the handshake */
+static int
+tls_cert_verify( tls_session *ssl )
+{
+	unsigned int status = 0;
+	int err;
+	time_t now = time(0);
+
+	err = gnutls_certificate_verify_peers2( ssl->session, &status );
+	if ( err < 0 ) {
+		Debug( LDAP_DEBUG_ANY,"TLS: gnutls_certificate_verify_peers2 failed %d\n",
+			err,0,0 );
+		return -1;
+	}
+	if ( status ) {
+		Debug( LDAP_DEBUG_TRACE,"TLS: peer cert untrusted or revoked (0x%x)\n",
+			status, 0,0 );
+		return -1;
+	}
+	if ( gnutls_certificate_expiration_time_peers( ssl->session ) < now ) {
+		Debug( LDAP_DEBUG_ANY, "TLS: peer certificate is expired\n",
+			0, 0, 0 );
+		return -1;
+	}
+	if ( gnutls_certificate_activation_time_peers( ssl->session ) > now ) {
+		Debug( LDAP_DEBUG_ANY, "TLS: peer certificate not yet active\n",
+			0, 0, 0 );
+		return -1;
+	}
+	return 0;
+}
+#endif /* HAVE_GNUTLS */
+
 /*
  * Call this to do a TLS connect on a sockbuf. ctx_arg can be
  * a SSL_CTX * or NULL, in which case the default ctx is used.
@@ -764,17 +1468,16 @@
 {
 	Sockbuf *sb = conn->lconn_sb;
 	int	err;
-	SSL	*ssl;
+	tls_session	*ssl;
 
 	if ( HAS_TLS( sb ) ) {
 		ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
 
 	} else {
 		struct ldapoptions *lo;
-		void *ctx;
+		tls_ctx *ctx;
 
-		lo = &ld->ld_options;
-		ctx = lo->ldo_tls_ctx;
+		ctx = ld->ld_options.ldo_tls_ctx;
 
 		ssl = alloc_handle( ctx, 0 );
 
@@ -787,41 +1490,58 @@
 		ber_sockbuf_add_io( sb, &sb_tls_sbio,
 			LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
 
+		lo = LDAP_INT_GLOBAL_OPT();   
 		if( ctx == NULL ) {
-			ctx = tls_def_ctx;
-			lo->ldo_tls_ctx = ctx;
+			ctx = lo->ldo_tls_ctx;
+			ld->ld_options.ldo_tls_ctx = ctx;
+			tls_ctx_ref( ctx );
 		}
-		if ( lo->ldo_tls_connect_cb )
+		if ( ld->ld_options.ldo_tls_connect_cb )
+			ld->ld_options.ldo_tls_connect_cb( ld, ssl, ctx,
+			ld->ld_options.ldo_tls_connect_arg );
+		if ( lo && lo->ldo_tls_connect_cb && lo->ldo_tls_connect_cb !=
+			ld->ld_options.ldo_tls_connect_cb )
 			lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg );
-		lo = LDAP_INT_GLOBAL_OPT();   
-		if ( lo && lo->ldo_tls_connect_cb )
-			lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg );
 	}
 
-	err = SSL_connect( ssl );
+	err = tls_session_connect( ssl );
 
 #ifdef HAVE_WINSOCK
 	errno = WSAGetLastError();
 #endif
 
-	if ( err <= 0 ) {
+#ifdef HAVE_GNUTLS
+	if ( err < 0 )
+#else
+	if ( err <= 0 )
+#endif
+	{
 		if ( update_flags( sb, ssl, err )) {
 			return 1;
 		}
 
-		if ((err = ERR_peek_error())) {
-			char buf[256];
-
+#ifndef HAVE_GNUTLS
+		if ((err = ERR_peek_error()))
+#endif
+		{
 			if ( ld->ld_error ) {
 				LDAP_FREE( ld->ld_error );
 			}
-			ld->ld_error = LDAP_STRDUP(ERR_error_string(err, buf));
+#ifdef HAVE_GNUTLS
+			ld->ld_error = LDAP_STRDUP(gnutls_strerror( err ));
+#else
+			{
+				char buf[256];
+				ld->ld_error = LDAP_STRDUP(ERR_error_string(err, buf));
+			}
+#endif
 #ifdef HAVE_EBCDIC
 			if ( ld->ld_error ) __etoa(ld->ld_error);
 #endif
 		}
 
-		Debug( LDAP_DEBUG_ANY,"TLS: can't connect.\n",0,0,0);
+		Debug( LDAP_DEBUG_ANY,"TLS: can't connect: %s.\n",
+			ld->ld_error ? ld->ld_error : "" ,0,0);
 
 		ber_sockbuf_remove_io( sb, &sb_tls_sbio,
 			LBER_SBIOD_LEVEL_TRANSPORT );
@@ -832,6 +1552,14 @@
 		return -1;
 	}
 
+#ifdef HAVE_GNUTLS
+	if ( ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER ) {
+		err = tls_cert_verify( ssl );
+		if ( err && ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW )
+			return err;
+	}
+#endif
+
 	return 0;
 }
 
@@ -843,7 +1571,7 @@
 ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
 {
 	int	err;
-	SSL	*ssl;
+	tls_session	*ssl;
 
 	if ( HAS_TLS( sb ) ) {
 		ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
@@ -860,23 +1588,27 @@
 			LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
 	}
 
-#ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_lock( &tls_connect_mutex );
-#endif
-	err = SSL_accept( ssl );
-#ifdef LDAP_R_COMPILE
-	ldap_pvt_thread_mutex_unlock( &tls_connect_mutex );
-#endif
+	err = tls_session_accept( ssl );
 
 #ifdef HAVE_WINSOCK
 	errno = WSAGetLastError();
 #endif
-	if ( err <= 0 ) {
+
+#ifdef HAVE_GNUTLS
+	if ( err < 0 )
+#else
+	if ( err <= 0 )
+#endif
+	{
 		if ( update_flags( sb, ssl, err )) return 1;
 
+#ifdef HAVE_GNUTLS
+		Debug( LDAP_DEBUG_ANY,"TLS: can't accept: %s.\n",
+			gnutls_strerror( err ),0,0 );
+#else
 		Debug( LDAP_DEBUG_ANY,"TLS: can't accept.\n",0,0,0 );
-
 		tls_report_error();
+#endif
 		ber_sockbuf_remove_io( sb, &sb_tls_sbio,
 			LBER_SBIOD_LEVEL_TRANSPORT );
 #ifdef LDAP_DEBUG
@@ -886,6 +1618,13 @@
 		return -1;
 	}
 
+#ifdef HAVE_GNUTLS
+	if ( ssl->ctx->lo->ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER ) {
+		err = tls_cert_verify( ssl );
+		if ( err && ssl->ctx->lo->ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW )
+			return err;
+	}
+#endif
 	return 0;
 }
 
@@ -913,6 +1652,60 @@
 	return ldap_pvt_tls_inplace( sb );
 }
 
+#ifdef HAVE_GNUTLS
+static void
+x509_cert_get_dn( struct berval *cert, struct berval *dn, int get_subject )
+{
+	BerElementBuffer berbuf;
+	BerElement *ber = (BerElement *)&berbuf;
+	ber_tag_t tag;
+	ber_len_t len;
+	ber_int_t i;
+
+	ber_init2( ber, cert, LBER_USE_DER );
+	tag = ber_skip_tag( ber, &len );	/* Sequence */
+	tag = ber_skip_tag( ber, &len );	/* Sequence */
+	tag = ber_skip_tag( ber, &len );	/* Context + Constructed (version) */
+	if ( tag == 0xa0 )	/* Version is optional */
+		tag = ber_get_int( ber, &i );	/* Int: Version */
+	tag = ber_get_int( ber, &i );	/* Int: Serial */
+	tag = ber_skip_tag( ber, &len );	/* Sequence: Signature */
+	ber_skip_data( ber, len );
+	if ( !get_subject ) {
+		tag = ber_peek_tag( ber, &len );	/* Sequence: Issuer DN */
+	} else {
+		tag = ber_skip_tag( ber, &len );
+		ber_skip_data( ber, len );
+		tag = ber_skip_tag( ber, &len );	/* Sequence: Validity */
+		ber_skip_data( ber, len );
+		tag = ber_peek_tag( ber, &len );	/* Sequence: Subject DN */
+	}
+	len = ber_ptrlen( ber );
+	dn->bv_val = cert->bv_val + len;
+	dn->bv_len = cert->bv_len - len;
+}
+
+static int
+tls_get_cert_dn( tls_session *session, struct berval *dnbv )
+{
+	if ( !session->peer_der_dn.bv_val ) {
+		const gnutls_datum_t *peer_cert_list;
+		int list_size;
+		struct berval bv;
+
+		peer_cert_list = gnutls_certificate_get_peers( session->session, 
+							&list_size );
+		if ( !peer_cert_list ) return LDAP_INVALID_CREDENTIALS;
+
+		bv.bv_len = peer_cert_list->size;
+		bv.bv_val = peer_cert_list->data;
+
+		x509_cert_get_dn( &bv, &session->peer_der_dn, 1 );
+		*dnbv = session->peer_der_dn;
+	}
+	return 0;
+}
+#else /* !HAVE_GNUTLS */
 static X509 *
 tls_get_cert( SSL *s )
 {
@@ -927,52 +1720,207 @@
 	return SSL_get_peer_certificate(s);
 }
 
+static int
+tls_get_cert_dn( tls_session *session, struct berval *dnbv )
+{
+	X509_NAME *xn;
+	X509 *x = tls_get_cert( session );
+
+	if ( !x )
+		return LDAP_INVALID_CREDENTIALS;
+
+	xn = X509_get_subject_name(x);
+	dnbv->bv_len = i2d_X509_NAME( xn, NULL );
+	dnbv->bv_val = xn->bytes->data;
+	return 0;
+}
+#endif /* HAVE_GNUTLS */
+
 int
 ldap_pvt_tls_get_peer_dn( void *s, struct berval *dn,
 	LDAPDN_rewrite_dummy *func, unsigned flags )
 {
-	X509 *x;
-	X509_NAME *xn;
+	tls_session *session = s;
+	struct berval bvdn;
 	int rc;
 
-	x = tls_get_cert((SSL *)s);
+	rc = tls_get_cert_dn( session, &bvdn );
+	if ( rc ) return rc;
 
-	if (!x) return LDAP_INVALID_CREDENTIALS;
-	
-	xn = X509_get_subject_name(x);
-	rc = ldap_X509dn2bv(xn, dn, (LDAPDN_rewrite_func *)func, flags);
-	X509_free(x);
+	rc = ldap_X509dn2bv( &bvdn, dn, 
+			    (LDAPDN_rewrite_func *)func, flags);
 	return rc;
 }
 
-char *
-ldap_pvt_tls_get_peer_hostname( void *s )
+/* what kind of hostname were we given? */
+#define	IS_DNS	0
+#define	IS_IP4	1
+#define	IS_IP6	2
+
+#ifdef HAVE_GNUTLS
+
+int
+ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
 {
-	X509 *x;
-	X509_NAME *xn;
-	char buf[2048], *p;
-	int ret;
+	tls_session *session = s;
+	int i, ret;
+	const gnutls_datum_t *peer_cert_list;
+	int list_size;
+	struct berval bv;
+	char altname[NI_MAXHOST];
+	size_t altnamesize;
 
-	x = tls_get_cert((SSL *)s);
-	if (!x) return NULL;
+	gnutls_x509_crt_t cert;
+	gnutls_datum_t *x;
+	const char *name;
+	char *ptr;
+	char *domain = NULL;
+#ifdef LDAP_PF_INET6
+	struct in6_addr addr;
+#else
+	struct in_addr addr;
+#endif
+	int n, len1 = 0, len2 = 0;
+	int ntype = IS_DNS;
+	time_t now = time(0);
+
+	if( ldap_int_hostname &&
+		( !name_in || !strcasecmp( name_in, "localhost" ) ) )
+	{
+		name = ldap_int_hostname;
+	} else {
+		name = name_in;
+	}
+
+	peer_cert_list = gnutls_certificate_get_peers( session->session, 
+						&list_size );
+	if ( !peer_cert_list ) {
+		Debug( LDAP_DEBUG_ANY,
+			"TLS: unable to get peer certificate.\n",
+			0, 0, 0 );
+		/* If this was a fatal condition, things would have
+		 * aborted long before now.
+		 */
+		return LDAP_SUCCESS;
+	}
+	ret = gnutls_x509_crt_init( &cert );
+	if ( ret < 0 )
+		return LDAP_LOCAL_ERROR;
+	ret = gnutls_x509_crt_import( cert, peer_cert_list, GNUTLS_X509_FMT_DER );
+	if ( ret ) {
+		gnutls_x509_crt_deinit( cert );
+		return LDAP_LOCAL_ERROR;
+	}
+
+#ifdef LDAP_PF_INET6
+	if (name[0] == '[' && strchr(name, ']')) {
+		char *n2 = ldap_strdup(name+1);
+		*strchr(n2, ']') = 2;
+		if (inet_pton(AF_INET6, n2, &addr))
+			ntype = IS_IP6;
+		LDAP_FREE(n2);
+	} else 
+#endif
+	if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) {
+		if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4;
+	}
 	
-	xn = X509_get_subject_name(x);
+	if (ntype == IS_DNS) {
+		len1 = strlen(name);
+		domain = strchr(name, '.');
+		if (domain) {
+			len2 = len1 - (domain-name);
+		}
+	}
 
-	ret = X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf));
-	if( ret == -1 ) {
-		X509_free(x);
-		return NULL;
+	for ( i=0, ret=0; ret >= 0; i++ ) {
+		altnamesize = sizeof(altname);
+		ret = gnutls_x509_crt_get_subject_alt_name( cert, i, 
+			altname, &altnamesize, NULL );
+		if ( ret < 0 ) break;
+
+		/* ignore empty */
+		if ( altnamesize == 0 ) continue;
+
+		if ( ret == GNUTLS_SAN_DNSNAME ) {
+			if (ntype != IS_DNS) continue;
+	
+			/* Is this an exact match? */
+			if ((len1 == altnamesize) && !strncasecmp(name, altname, len1)) {
+				break;
+			}
+
+			/* Is this a wildcard match? */
+			if (domain && (altname[0] == '*') && (altname[1] == '.') &&
+				(len2 == altnamesize-1) && !strncasecmp(domain, &altname[1], len2))
+			{
+				break;
+			}
+		} else if ( ret == GNUTLS_SAN_IPADDRESS ) {
+			if (ntype == IS_DNS) continue;
+
+#ifdef LDAP_PF_INET6
+			if (ntype == IS_IP6 && altnamesize != sizeof(struct in6_addr)) {
+				continue;
+			} else
+#endif
+			if (ntype == IS_IP4 && altnamesize != sizeof(struct in_addr)) {
+				continue;
+			}
+			if (!memcmp(altname, &addr, altnamesize)) {
+				break;
+			}
+		}
 	}
+	if ( ret >= 0 ) {
+		ret = LDAP_SUCCESS;
+	} else {
+		altnamesize = sizeof(altname);
+		ret = gnutls_x509_crt_get_dn_by_oid( cert, CN_OID,
+			0, 0, altname, &altnamesize );
+		if ( ret < 0 ) {
+			Debug( LDAP_DEBUG_ANY,
+				"TLS: unable to get common name from peer certificate.\n",
+				0, 0, 0 );
+			ret = LDAP_CONNECT_ERROR;
+			if ( ld->ld_error ) {
+				LDAP_FREE( ld->ld_error );
+			}
+			ld->ld_error = LDAP_STRDUP(
+				_("TLS: unable to get CN from peer certificate"));
 
-	p = LDAP_STRDUP(buf);
-	X509_free(x);
-	return p;
+		} else {
+			ret = LDAP_LOCAL_ERROR;
+			if ( len1 == altnamesize && strncasecmp(name, altname, altnamesize) == 0 ) {
+				ret = LDAP_SUCCESS;
+
+			} else if (( altname[0] == '*' ) && ( altname[1] == '.' )) {
+					/* Is this a wildcard match? */
+				if( domain &&
+					(len2 == altnamesize-1) && !strncasecmp(domain, &altname[1], len2)) {
+					ret = LDAP_SUCCESS;
+				}
+			}
+		}
+
+		if( ret == LDAP_LOCAL_ERROR ) {
+			altname[altnamesize] = '\0';
+			Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
+				"common name in certificate (%s).\n", 
+				name, altname, 0 );
+			ret = LDAP_CONNECT_ERROR;
+			if ( ld->ld_error ) {
+				LDAP_FREE( ld->ld_error );
+			}
+			ld->ld_error = LDAP_STRDUP(
+				_("TLS: hostname does not match CN in peer certificate"));
+		}
+	}
+	gnutls_x509_crt_deinit( cert );
+	return ret;
 }
 
-/* what kind of hostname were we given? */
-#define	IS_DNS	0
-#define	IS_IP4	1
-#define	IS_IP6	2
+#else /* !HAVE_GNUTLS */
 
 int
 ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
@@ -1146,27 +2094,7 @@
 	X509_free(x);
 	return ret;
 }
-
-const char *
-ldap_pvt_tls_get_peer_issuer( void *s )
-{
-#if 0	/* currently unused; see ldap_pvt_tls_get_peer_dn() if needed */
-	X509 *x;
-	X509_NAME *xn;
-	char buf[2048], *p;
-
-	x = SSL_get_peer_certificate((SSL *)s);
-
-	if (!x) return NULL;
-	
-	xn = X509_get_issuer_name(x);
-	p = LDAP_STRDUP(X509_NAME_oneline(xn, buf, sizeof(buf)));
-	X509_free(x);
-	return p;
-#else
-	return NULL;
 #endif
-}
 
 int
 ldap_int_tls_config( LDAP *ld, int option, const char *arg )
@@ -1181,6 +2109,9 @@
 	case LDAP_OPT_X_TLS_RANDOM_FILE:
 	case LDAP_OPT_X_TLS_CIPHER_SUITE:
 	case LDAP_OPT_X_TLS_DHFILE:
+#ifdef HAVE_GNUTLS
+	case LDAP_OPT_X_TLS_CRLFILE:
+#endif
 		return ldap_pvt_tls_set_option( ld, option, (void *) arg );
 
 	case LDAP_OPT_X_TLS_REQUIRE_CERT:
@@ -1256,47 +2187,56 @@
 		*(int *)arg = lo->ldo_tls_mode;
 		break;
 	case LDAP_OPT_X_TLS_CTX:
-		if ( ld == NULL ) {
-			*(void **)arg = (void *) tls_def_ctx;
-		} else {
-			*(void **)arg = lo->ldo_tls_ctx;
+		*(void **)arg = lo->ldo_tls_ctx;
+		if ( lo->ldo_tls_ctx ) {
+			tls_ctx_ref( lo->ldo_tls_ctx );
 		}
 		break;
 	case LDAP_OPT_X_TLS_CACERTFILE:
-		*(char **)arg = tls_opt_cacertfile ?
-			LDAP_STRDUP( tls_opt_cacertfile ) : NULL;
+		*(char **)arg = lo->ldo_tls_cacertfile ?
+			LDAP_STRDUP( lo->ldo_tls_cacertfile ) : NULL;
 		break;
 	case LDAP_OPT_X_TLS_CACERTDIR:
-		*(char **)arg = tls_opt_cacertdir ?
-			LDAP_STRDUP( tls_opt_cacertdir ) : NULL;
+		*(char **)arg = lo->ldo_tls_cacertdir ?
+			LDAP_STRDUP( lo->ldo_tls_cacertdir ) : NULL;
 		break;
 	case LDAP_OPT_X_TLS_CERTFILE:
-		*(char **)arg = tls_opt_certfile ?
-			LDAP_STRDUP( tls_opt_certfile ) : NULL;
+		*(char **)arg = lo->ldo_tls_certfile ?
+			LDAP_STRDUP( lo->ldo_tls_certfile ) : NULL;
 		break;
 	case LDAP_OPT_X_TLS_KEYFILE:
-		*(char **)arg = tls_opt_keyfile ?
-			LDAP_STRDUP( tls_opt_keyfile ) : NULL;
+		*(char **)arg = lo->ldo_tls_keyfile ?
+			LDAP_STRDUP( lo->ldo_tls_keyfile ) : NULL;
 		break;
 	case LDAP_OPT_X_TLS_DHFILE:
-		*(char **)arg = tls_opt_dhfile ?
-			LDAP_STRDUP( tls_opt_dhfile ) : NULL;
+		*(char **)arg = lo->ldo_tls_dhfile ?
+			LDAP_STRDUP( lo->ldo_tls_dhfile ) : NULL;
 		break;
+#ifdef HAVE_GNUTLS
+	case LDAP_OPT_X_TLS_CRLFILE:
+		*(char **)arg = lo->ldo_tls_crlfile ?
+			LDAP_STRDUP( lo->ldo_tls_crlfile ) : NULL;
+		break;
+#endif
 	case LDAP_OPT_X_TLS_REQUIRE_CERT:
-		*(int *)arg = tls_opt_require_cert;
+		*(int *)arg = lo->ldo_tls_require_cert;
 		break;
 #ifdef HAVE_OPENSSL_CRL
 	case LDAP_OPT_X_TLS_CRLCHECK:
-		*(int *)arg = tls_opt_crlcheck;
+		*(int *)arg = lo->ldo_tls_crlcheck;
 		break;
 #endif
 	case LDAP_OPT_X_TLS_CIPHER_SUITE:
-		*(char **)arg = tls_opt_ciphersuite ?
-			LDAP_STRDUP( tls_opt_ciphersuite ) : NULL;
+		*(char **)arg = lo->ldo_tls_ciphersuite ?
+			LDAP_STRDUP( lo->ldo_tls_ciphersuite ) : NULL;
 		break;
 	case LDAP_OPT_X_TLS_RANDOM_FILE:
+#ifdef HAVE_OPENSSL
 		*(char **)arg = tls_opt_randfile ?
 			LDAP_STRDUP( tls_opt_randfile ) : NULL;
+#else
+		*(char **)arg = NULL;
+#endif
 		break;
 	case LDAP_OPT_X_TLS_SSL_CTX: {
 		void *retval = 0;
@@ -1346,6 +2286,8 @@
 
 	switch( option ) {
 	case LDAP_OPT_X_TLS:
+		if ( !arg ) return -1;
+
 		switch( *(int *) arg ) {
 		case LDAP_OPT_X_TLS_NEVER:
 		case LDAP_OPT_X_TLS_DEMAND:
@@ -1361,12 +2303,10 @@
 		return -1;
 
 	case LDAP_OPT_X_TLS_CTX:
-		if ( ld == NULL ) {
-			tls_def_ctx = (SSL_CTX *) arg;
-
-		} else {
-			lo->ldo_tls_ctx = arg;
-		}
+		if ( lo->ldo_tls_ctx )
+			ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
+		lo->ldo_tls_ctx = arg;
+		tls_ctx_ref( lo->ldo_tls_ctx );
 		return 0;
 	case LDAP_OPT_X_TLS_CONNECT_CB:
 		lo->ldo_tls_connect_cb = (LDAP_TLS_CONNECT_CB *)arg;
@@ -1374,63 +2314,76 @@
 	case LDAP_OPT_X_TLS_CONNECT_ARG:
 		lo->ldo_tls_connect_arg = arg;
 		return 0;
-	}
-
-	if ( ld != NULL ) {
-		return -1;
-	}
-
-	switch( option ) {
 	case LDAP_OPT_X_TLS_CACERTFILE:
-		if ( tls_opt_cacertfile ) LDAP_FREE( tls_opt_cacertfile );
-		tls_opt_cacertfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
-		break;
+		if ( lo->ldo_tls_cacertfile ) LDAP_FREE( lo->ldo_tls_cacertfile );
+		lo->ldo_tls_cacertfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+		return 0;
 	case LDAP_OPT_X_TLS_CACERTDIR:
-		if ( tls_opt_cacertdir ) LDAP_FREE( tls_opt_cacertdir );
-		tls_opt_cacertdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
-		break;
+		if ( lo->ldo_tls_cacertdir ) LDAP_FREE( lo->ldo_tls_cacertdir );
+		lo->ldo_tls_cacertdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+		return 0;
 	case LDAP_OPT_X_TLS_CERTFILE:
-		if ( tls_opt_certfile ) LDAP_FREE( tls_opt_certfile );
-		tls_opt_certfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
-		break;
+		if ( lo->ldo_tls_certfile ) LDAP_FREE( lo->ldo_tls_certfile );
+		lo->ldo_tls_certfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+		return 0;
 	case LDAP_OPT_X_TLS_KEYFILE:
-		if ( tls_opt_keyfile ) LDAP_FREE( tls_opt_keyfile );
-		tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
-		break;
+		if ( lo->ldo_tls_keyfile ) LDAP_FREE( lo->ldo_tls_keyfile );
+		lo->ldo_tls_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+		return 0;
 	case LDAP_OPT_X_TLS_DHFILE:
-		if ( tls_opt_dhfile ) LDAP_FREE( tls_opt_dhfile );
-		tls_opt_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
-		break;
+		if ( lo->ldo_tls_dhfile ) LDAP_FREE( lo->ldo_tls_dhfile );
+		lo->ldo_tls_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+		return 0;
+#ifdef HAVE_GNUTLS
+	case LDAP_OPT_X_TLS_CRLFILE:
+		if ( lo->ldo_tls_crlfile ) LDAP_FREE( lo->ldo_tls_crlfile );
+		lo->ldo_tls_crlfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+		return 0;
+#endif
 	case LDAP_OPT_X_TLS_REQUIRE_CERT:
+		if ( !arg ) return -1;
 		switch( *(int *) arg ) {
 		case LDAP_OPT_X_TLS_NEVER:
 		case LDAP_OPT_X_TLS_DEMAND:
 		case LDAP_OPT_X_TLS_ALLOW:
 		case LDAP_OPT_X_TLS_TRY:
 		case LDAP_OPT_X_TLS_HARD:
-			tls_opt_require_cert = * (int *) arg;
+			lo->ldo_tls_require_cert = * (int *) arg;
 			return 0;
 		}
 		return -1;
 #ifdef HAVE_OPENSSL_CRL
 	case LDAP_OPT_X_TLS_CRLCHECK:
+		if ( !arg ) return -1;
 		switch( *(int *) arg ) {
 		case LDAP_OPT_X_TLS_CRL_NONE:
 		case LDAP_OPT_X_TLS_CRL_PEER:
 		case LDAP_OPT_X_TLS_CRL_ALL:
-			tls_opt_crlcheck = * (int *) arg;
+			lo->ldo_tls_crlcheck = * (int *) arg;
 			return 0;
 		}
 		return -1;
 #endif
 	case LDAP_OPT_X_TLS_CIPHER_SUITE:
-		if ( tls_opt_ciphersuite ) LDAP_FREE( tls_opt_ciphersuite );
-		tls_opt_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
-		break;
+		if ( lo->ldo_tls_ciphersuite ) LDAP_FREE( lo->ldo_tls_ciphersuite );
+		lo->ldo_tls_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+		return 0;
+
 	case LDAP_OPT_X_TLS_RANDOM_FILE:
+		if ( ld != NULL )
+			return -1;
+#ifdef HAVE_OPENSSL
 		if (tls_opt_randfile ) LDAP_FREE (tls_opt_randfile );
 		tls_opt_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+#endif
 		break;
+
+	case LDAP_OPT_X_TLS_NEWCTX:
+		if ( !arg ) return -1;
+		if ( lo->ldo_tls_ctx )
+			ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
+		lo->ldo_tls_ctx = NULL;
+		return ldap_int_tls_init_ctx( lo, *(int *)arg );
 	default:
 		return -1;
 	}
@@ -1471,7 +2424,7 @@
 	/* 
 	 * compare host with name(s) in certificate
 	 */
-	if (tls_opt_require_cert != LDAP_OPT_X_TLS_NEVER) {
+	if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER) {
 		ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
 		if (ld->ld_errno != LDAP_SUCCESS) {
 			return ld->ld_errno;
@@ -1481,6 +2434,7 @@
 	return LDAP_SUCCESS;
 }
 
+#ifdef HAVE_OPENSSL
 /* Derived from openssl/apps/s_cb.c */
 static void
 tls_info_cb( const SSL *ssl, int where, int ret )
@@ -1808,6 +2762,8 @@
 }
 #endif
 
+#endif /* HAVE_OPENSSL */
+
 void *
 ldap_pvt_tls_sb_ctx( Sockbuf *sb )
 {
@@ -1826,11 +2782,17 @@
 int
 ldap_pvt_tls_get_strength( void *s )
 {
-#ifdef HAVE_TLS
+#ifdef HAVE_OPENSSL
 	SSL_CIPHER *c;
 
 	c = SSL_get_current_cipher((SSL *)s);
 	return SSL_CIPHER_get_bits(c, NULL);
+#elif defined(HAVE_GNUTLS)
+	tls_session *session = s;
+	gnutls_cipher_algorithm_t c;
+
+	c = gnutls_cipher_get( session->session );
+	return gnutls_cipher_get_key_size( c );
 #else
 	return 0;
 #endif
@@ -1841,18 +2803,36 @@
 ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func, unsigned flags )
 {
 #ifdef HAVE_TLS
+	struct berval der_dn;
+	int rc;
+#ifdef HAVE_OPENSSL
 	X509 *x;
 	X509_NAME *xn;
-	int rc;
 
 	x = SSL_get_certificate((SSL *)s);
 
 	if (!x) return LDAP_INVALID_CREDENTIALS;
 	
 	xn = X509_get_subject_name(x);
-	rc = ldap_X509dn2bv(xn, dn, (LDAPDN_rewrite_func *)func, flags );
+	der_dn.bv_len = i2d_X509_NAME( xn, NULL );
+	der_dn.bv_val = xn->bytes->data;
+#elif defined(HAVE_GNUTLS)
+	tls_session *session = s;
+	const gnutls_datum_t *x;
+	struct berval bv;
+
+	x = gnutls_certificate_get_ours( session->session );
+
+	if (!x) return LDAP_INVALID_CREDENTIALS;
+	
+	bv.bv_val = x->data;
+	bv.bv_len = x->size;
+
+	x509_cert_get_dn( &bv, &der_dn, 1 );
+#endif
+	rc = ldap_X509dn2bv(&der_dn, dn, (LDAPDN_rewrite_func *)func, flags );
 	return rc;
-#else
+#else /* !HAVE_TLS */
 	return LDAP_NOT_SUPPORTED;
 #endif
 }
@@ -1918,3 +2898,234 @@
 #endif
 }
 
+/* These tags probably all belong in lber.h, but they're
+ * not normally encountered when processing LDAP, so maybe
+ * they belong somewhere else instead.
+ */
+
+#define LBER_TAG_OID		((ber_tag_t) 0x06UL)
+
+/* Tags for string types used in a DirectoryString.
+ *
+ * Note that IA5string is not one of the defined choices for
+ * DirectoryString in X.520, but it gets used for email AVAs.
+ */
+#define	LBER_TAG_UTF8		((ber_tag_t) 0x0cUL)
+#define	LBER_TAG_PRINTABLE	((ber_tag_t) 0x13UL)
+#define	LBER_TAG_TELETEX	((ber_tag_t) 0x14UL)
+#define	LBER_TAG_IA5		((ber_tag_t) 0x16UL)
+#define	LBER_TAG_UNIVERSAL	((ber_tag_t) 0x1cUL)
+#define	LBER_TAG_BMP		((ber_tag_t) 0x1eUL)
+
+static oid_name *
+find_oid( struct berval *oid )
+{
+	int i;
+
+	for ( i=0; !BER_BVISNULL( &oids[i].oid ); i++ ) {
+		if ( oids[i].oid.bv_len != oid->bv_len ) continue;
+		if ( !strcmp( oids[i].oid.bv_val, oid->bv_val ))
+			return &oids[i];
+	}
+	return NULL;
+}
+
+/* Convert a structured DN from an X.509 certificate into an LDAPV3 DN.
+ * x509_name must be raw DER. If func is non-NULL, the
+ * constructed DN will use numeric OIDs to identify attributeTypes,
+ * and the func() will be invoked to rewrite the DN with the given
+ * flags.
+ *
+ * Otherwise the DN will use shortNames from a hardcoded table.
+ */
+int
+ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func,
+	unsigned flags )
+{
+	LDAPDN	newDN;
+	LDAPRDN	newRDN;
+	LDAPAVA *newAVA, *baseAVA;
+	BerElementBuffer berbuf;
+	BerElement *ber = (BerElement *)&berbuf;
+	char oids[8192], *oidptr = oids, *oidbuf = NULL;
+	void *ptrs[2048];
+	char *dn_end, *rdn_end;
+	int i, navas, nrdns, rc = LDAP_SUCCESS;
+	size_t dnsize, oidrem = sizeof(oids), oidsize = 0;
+	int csize;
+	ber_tag_t tag;
+	ber_len_t len;
+	oid_name *oidname;
+
+	struct berval	Oid, Val, oid2, *in = x509_name;
+
+	assert( bv != NULL );
+
+	bv->bv_len = 0;
+	bv->bv_val = NULL;
+
+	navas = 0;
+	nrdns = 0;
+
+	/* A DN is a SEQUENCE of RDNs. An RDN is a SET of AVAs.
+	 * An AVA is a SEQUENCE of attr and value.
+	 * Count the number of AVAs and RDNs
+	 */
+	ber_init2( ber, in, LBER_USE_DER );
+	tag = ber_peek_tag( ber, &len );
+	if ( tag != LBER_SEQUENCE )
+		return LDAP_DECODING_ERROR;
+
+	for ( tag = ber_first_element( ber, &len, &dn_end );
+		tag == LBER_SET;
+		tag = ber_next_element( ber, &len, dn_end )) {
+		nrdns++;
+		for ( tag = ber_first_element( ber, &len, &rdn_end );
+			tag == LBER_SEQUENCE;
+			tag = ber_next_element( ber, &len, rdn_end )) {
+			tag = ber_skip_tag( ber, &len );
+			ber_skip_data( ber, len );
+			navas++;
+		}
+	}
+
+	/* Allocate the DN/RDN/AVA stuff as a single block */    
+	dnsize = sizeof(LDAPRDN) * (nrdns+1);
+	dnsize += sizeof(LDAPAVA *) * (navas+nrdns);
+	dnsize += sizeof(LDAPAVA) * navas;
+	if (dnsize > sizeof(ptrs)) {
+		newDN = (LDAPDN)LDAP_MALLOC( dnsize );
+		if ( newDN == NULL )
+			return LDAP_NO_MEMORY;
+	} else {
+		newDN = (LDAPDN)(char *)ptrs;
+	}
+	
+	newDN[nrdns] = NULL;
+	newRDN = (LDAPRDN)(newDN + nrdns+1);
+	newAVA = (LDAPAVA *)(newRDN + navas + nrdns);
+	baseAVA = newAVA;
+
+	/* Rewind and start extracting */
+	ber_rewind( ber );
+
+	tag = ber_first_element( ber, &len, &dn_end );
+	for ( i = nrdns - 1; i >= 0; i-- ) {
+		newDN[i] = newRDN;
+
+		for ( tag = ber_first_element( ber, &len, &rdn_end );
+			tag == LBER_SEQUENCE;
+			tag = ber_next_element( ber, &len, rdn_end )) {
+
+			*newRDN++ = newAVA;
+			tag = ber_skip_tag( ber, &len );
+			tag = ber_get_stringbv( ber, &Oid, LBER_BV_NOTERM );
+			if ( tag != LBER_TAG_OID ) {
+				rc = LDAP_DECODING_ERROR;
+				goto nomem;
+			}
+
+			oid2.bv_val = oidptr;
+			oid2.bv_len = oidrem;
+			if ( ber_decode_oid( &Oid, &oid2 ) < 0 ) {
+				rc = LDAP_DECODING_ERROR;
+				goto nomem;
+			}
+			oidname = find_oid( &oid2 );
+			if ( !oidname ) {
+				newAVA->la_attr = oid2;
+				oidptr += oid2.bv_len + 1;
+				oidrem -= oid2.bv_len + 1;
+
+				/* Running out of OID buffer space? */
+				if (oidrem < 128) {
+					if ( oidsize == 0 ) {
+						oidsize = sizeof(oids) * 2;
+						oidrem = oidsize;
+						oidbuf = LDAP_MALLOC( oidsize );
+						if ( oidbuf == NULL ) goto nomem;
+						oidptr = oidbuf;
+					} else {
+						char *old = oidbuf;
+						oidbuf = LDAP_REALLOC( oidbuf, oidsize*2 );
+						if ( oidbuf == NULL ) goto nomem;
+						/* Buffer moved! Fix AVA pointers */
+						if ( old != oidbuf ) {
+							LDAPAVA *a;
+							long dif = oidbuf - old;
+
+							for (a=baseAVA; a<=newAVA; a++){
+								if (a->la_attr.bv_val >= old &&
+									a->la_attr.bv_val <= (old + oidsize))
+									a->la_attr.bv_val += dif;
+							}
+						}
+						oidptr = oidbuf + oidsize - oidrem;
+						oidrem += oidsize;
+						oidsize *= 2;
+					}
+				}
+			} else {
+				if ( func ) {
+					newAVA->la_attr = oidname->oid;
+				} else {
+					newAVA->la_attr = oidname->name;
+				}
+			}
+			tag = ber_get_stringbv( ber, &Val, LBER_BV_NOTERM );
+			switch(tag) {
+			case LBER_TAG_UNIVERSAL:
+				/* This uses 32-bit ISO 10646-1 */
+				csize = 4; goto to_utf8;
+			case LBER_TAG_BMP:
+				/* This uses 16-bit ISO 10646-1 */
+				csize = 2; goto to_utf8;
+			case LBER_TAG_TELETEX:
+				/* This uses 8-bit, assume ISO 8859-1 */
+				csize = 1;
+to_utf8:		rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value );
+				newAVA->la_flags |= LDAP_AVA_FREE_VALUE;
+				if (rc != LDAP_SUCCESS) goto nomem;
+				newAVA->la_flags = LDAP_AVA_NONPRINTABLE;
+				break;
+			case LBER_TAG_UTF8:
+				newAVA->la_flags = LDAP_AVA_NONPRINTABLE;
+				/* This is already in UTF-8 encoding */
+			case LBER_TAG_IA5:
+			case LBER_TAG_PRINTABLE:
+				/* These are always 7-bit strings */
+				newAVA->la_value = Val;
+			default:
+				;
+			}
+			newAVA->la_private = NULL;
+			newAVA->la_flags = LDAP_AVA_STRING;
+			newAVA++;
+		}
+		*newRDN++ = NULL;
+		tag = ber_next_element( ber, &len, dn_end );
+	}
+		
+	if ( func ) {
+		rc = func( newDN, flags, NULL );
+		if ( rc != LDAP_SUCCESS )
+			goto nomem;
+	}
+
+	rc = ldap_dn2bv_x( newDN, bv, LDAP_DN_FORMAT_LDAPV3, NULL );
+
+nomem:
+	for (;baseAVA < newAVA; baseAVA++) {
+		if (baseAVA->la_flags & LDAP_AVA_FREE_ATTR)
+			LDAP_FREE( baseAVA->la_attr.bv_val );
+		if (baseAVA->la_flags & LDAP_AVA_FREE_VALUE)
+			LDAP_FREE( baseAVA->la_value.bv_val );
+	}
+
+	if ( oidsize != 0 )
+		LDAP_FREE( oidbuf );
+	if ( newDN != (LDAPDN)(char *) ptrs )
+		LDAP_FREE( newDN );
+	return rc;
+}
+

Modified: openldap/trunk/libraries/libldap/turn.c
===================================================================
--- openldap/trunk/libraries/libldap/turn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/turn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/turn.c,v 1.1.2.4 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/turn.c,v 1.3.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2005-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/txn.c
===================================================================
--- openldap/trunk/libraries/libldap/txn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/txn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,7 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/txn.c,v 1.2.2.3 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/txn.c,v 1.8.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2004-2007 The OpenLDAP Foundation.
+ * Copyright 2006-2007 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -13,40 +13,143 @@
  * <http://www.OpenLDAP.org/license.html>.
  */
 /* ACKNOWLEDGEMENTS:
- * This program was orignally developed by Kurt D. Zeilenga for inclusion in
- * OpenLDAP Software.
+ * This program was orignally developed by Kurt D. Zeilenga for inclusion
+ * in OpenLDAP Software.
  */
 
+/*
+ * LDAPv3 Transactions (draft-zeilenga-ldap-txn)
+ */
+
 #include "portable.h"
 
+#include <stdio.h>
 #include <ac/stdlib.h>
 
+#include <ac/socket.h>
+#include <ac/string.h>
 #include <ac/time.h>
-#include <ac/string.h>
 
 #include "ldap-int.h"
+#include "ldap_log.h"
 
-#ifdef LDAP_GROUP_TRANSACTION
+#ifdef LDAP_X_TXN
+int
+ldap_txn_start(
+	LDAP *ld,
+	LDAPControl **sctrls,
+	LDAPControl **cctrls,
+	int *msgidp )
+{
+	return ldap_extended_operation( ld, LDAP_EXOP_X_TXN_START,
+		NULL, sctrls, cctrls, msgidp );
+}
 
 int
-ldap_txn_create_s(
+ldap_txn_start_s(
 	LDAP *ld,
-	struct berval	**cookie,
-	LDAPControl		**sctrls,
-	LDAPControl		**cctrls )
+	LDAPControl **sctrls,
+	LDAPControl **cctrls,
+	struct berval **txnid )
 {
-	return LDAP_NOT_SUPPORTED;
+	assert( txnid != NULL );
+
+	return ldap_extended_operation_s( ld, LDAP_EXOP_X_TXN_START,
+		NULL, sctrls, cctrls, NULL, txnid );
 }
 
 int
+ldap_txn_end(
+	LDAP *ld,
+	int commit,
+	struct berval *txnid,
+	LDAPControl **sctrls,
+	LDAPControl **cctrls,
+	int *msgidp )
+{
+	int rc;
+	BerElement *txnber = NULL;
+	struct berval *txnval = NULL;
+
+	assert( txnid != NULL );
+
+	txnber = ber_alloc_t( LBER_USE_DER );
+
+	if( commit ) {
+		ber_printf( txnber, "{ON}", txnid );
+	} else {
+		ber_printf( txnber, "{bON}", commit, txnid );
+	}
+
+	ber_flatten( txnber, &txnval );
+
+	rc = ldap_extended_operation( ld, LDAP_EXOP_X_TXN_END,
+		txnval, sctrls, cctrls, msgidp );
+
+	ber_free( txnber, 1 );
+	return rc;
+}
+
+int
 ldap_txn_end_s(
 	LDAP *ld,
-	struct berval	*cookie,
-	int				commit,
-	LDAPControl		**sctrls,
-	LDAPControl		**cctrls )
+	int commit,
+	struct berval *txnid,
+	LDAPControl **sctrls,
+	LDAPControl **cctrls,
+	int *retidp )
 {
-	return LDAP_NOT_SUPPORTED;
+	int rc;
+	BerElement *txnber = NULL;
+	struct berval *txnval = NULL;
+	struct berval *retdata = NULL;
+
+	if ( retidp != NULL ) *retidp = -1;
+
+	txnber = ber_alloc_t( LBER_USE_DER );
+
+	if( commit ) {
+		ber_printf( txnber, "{ON}", txnid );
+	} else {
+		ber_printf( txnber, "{bON}", commit, txnid );
+	}
+
+	ber_flatten( txnber, &txnval );
+
+	rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_TXN_END,
+		txnval, sctrls, cctrls, NULL, &retdata );
+
+	ber_free( txnber, 1 );
+
+	/* parse retdata */
+	if( retdata != NULL ) {
+		BerElement *ber;
+		ber_tag_t tag;
+		ber_int_t retid;
+
+		if( retidp == NULL ) goto done;
+
+		ber = ber_init( retdata );
+
+		if( ber == NULL ) {
+			rc = ld->ld_errno = LDAP_NO_MEMORY;
+			goto done;
+		}
+
+		tag = ber_scanf( ber, "i", &retid );
+		ber_free( ber, 1 );
+
+		if ( tag != LBER_INTEGER ) {
+			rc = ld->ld_errno = LDAP_DECODING_ERROR;
+			goto done;
+		}
+
+		*retidp = (int) retid;
+
+done:
+		ber_bvfree( retdata );
+	}
+
+	return rc;
 }
-
 #endif

Modified: openldap/trunk/libraries/libldap/unbind.c
===================================================================
--- openldap/trunk/libraries/libldap/unbind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/unbind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/unbind.c,v 1.48.2.8 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/unbind.c,v 1.56.2.3 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -15,17 +15,7 @@
 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
  * All rights reserved.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
-/* An Unbind Request looks like this:
- *
- *	UnbindRequest ::= NULL
- *
- * and has no response.
- */
-
 #include "portable.h"
 
 #include <stdio.h>
@@ -37,6 +27,13 @@
 
 #include "ldap-int.h"
 
+/* An Unbind Request looks like this:
+ *
+ *	UnbindRequest ::= [APPLICATION 2] NULL
+ *
+ * and has no response.  (Source: RFC 4511)
+ */
+
 int
 ldap_unbind_ext(
 	LDAP *ld,
@@ -106,7 +103,7 @@
 		next = lm->lm_next;
 		ldap_msgfree( lm );
 	}
-
+    
 	if ( ld->ld_abandoned != NULL ) {
 		LDAP_FREE( ld->ld_abandoned );
 		ld->ld_abandoned = NULL;
@@ -147,16 +144,6 @@
 	}
 #endif
 
-	if ( ld->ld_options.ldo_tm_api != NULL ) {
-		LDAP_FREE( ld->ld_options.ldo_tm_api );
-		ld->ld_options.ldo_tm_api = NULL;
-	}
-
-	if ( ld->ld_options.ldo_tm_net != NULL ) {
-		LDAP_FREE( ld->ld_options.ldo_tm_net );
-		ld->ld_options.ldo_tm_net = NULL;
-	}
-
 #ifdef HAVE_CYRUS_SASL
 	if ( ld->ld_options.ldo_def_sasl_mech != NULL ) {
 		LDAP_FREE( ld->ld_options.ldo_def_sasl_mech );
@@ -179,6 +166,10 @@
 	}
 #endif
 
+#ifdef HAVE_TLS
+	ldap_int_tls_destroy( &ld->ld_options );
+#endif
+
 	if ( ld->ld_options.ldo_sctrls != NULL ) {
 		ldap_controls_free( ld->ld_options.ldo_sctrls );
 		ld->ld_options.ldo_sctrls = NULL;
@@ -257,9 +248,8 @@
 
 	ld->ld_errno = LDAP_SUCCESS;
 	/* send the message */
-	if ( ber_flush( sb, ber, 1 ) == -1 ) {
+	if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) == -1 ) {
 		ld->ld_errno = LDAP_SERVER_DOWN;
-		ber_free( ber, 1 );
 	}
 
 	return( ld->ld_errno );

Modified: openldap/trunk/libraries/libldap/url.c
===================================================================
--- openldap/trunk/libraries/libldap/url.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/url.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
-/* LIBLDAP url.c -- LDAP URL (RFC 2255) related routines */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/url.c,v 1.84.2.8 2007/01/02 21:43:50 kurt Exp $ */
+/* LIBLDAP url.c -- LDAP URL (RFC 4516) related routines */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/url.c,v 1.94.2.4 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -20,12 +20,12 @@
 
 /*
  *  LDAP URLs look like this:
- *    ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
+ *    ldap[is]://host[:port][/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
  *
  *  where:
  *   attributes is a comma separated list
  *   scope is one of these three strings:  base one sub (default=base)
- *   filter is an string-represented filter as in RFC 2254
+ *   filter is an string-represented filter as in RFC 4515
  *
  *  e.g.,  ldap://host:port/dc=com?o,cn?base?(o=openldap)?extension
  *
@@ -257,36 +257,83 @@
 	return( NULL );
 }
 
-
-static int str2scope( const char *p )
+int
+ldap_pvt_scope2bv( int scope, struct berval *bv )
 {
-	if ( strcasecmp( p, "one" ) == 0 ) {
-		return LDAP_SCOPE_ONELEVEL;
+	switch ( scope ) {
+	case LDAP_SCOPE_BASE:
+		BER_BVSTR( bv, "base" );
+		break;
 
-	} else if ( strcasecmp( p, "onelevel" ) == 0 ) {
-		return LDAP_SCOPE_ONELEVEL;
+	case LDAP_SCOPE_ONELEVEL:
+		BER_BVSTR( bv, "one" );
+		break;
 
-	} else if ( strcasecmp( p, "base" ) == 0 ) {
-		return LDAP_SCOPE_BASE;
+	case LDAP_SCOPE_SUBTREE:
+		BER_BVSTR( bv, "sub" );
+		break;
 
-	} else if ( strcasecmp( p, "sub" ) == 0 ) {
-		return LDAP_SCOPE_SUBTREE;
+	case LDAP_SCOPE_SUBORDINATE:
+		BER_BVSTR( bv, "subordinate" );
+		break;
 
-	} else if ( strcasecmp( p, "subtree" ) == 0 ) {
-		return LDAP_SCOPE_SUBTREE;
+	default:
+		return LDAP_OTHER;
+	}
 
-#ifdef LDAP_SCOPE_SUBORDINATE
-	} else if ( strcasecmp( p, "subordinate" ) == 0 ) {
-		return LDAP_SCOPE_SUBORDINATE;
+	return LDAP_SUCCESS;
+}
 
-	} else if ( strcasecmp( p, "children" ) == 0 ) {
-		return LDAP_SCOPE_SUBORDINATE;
-#endif
+const char *
+ldap_pvt_scope2str( int scope )
+{
+	struct berval	bv;
+
+	if ( ldap_pvt_scope2bv( scope, &bv ) == LDAP_SUCCESS ) {
+		return bv.bv_val;
 	}
 
+	return NULL;
+}
+
+int
+ldap_pvt_bv2scope( struct berval *bv )
+{
+	static struct {
+		struct berval	bv;
+		int		scope;
+	}	v[] = {
+		{ BER_BVC( "one" ),		LDAP_SCOPE_ONELEVEL },
+		{ BER_BVC( "onelevel" ),	LDAP_SCOPE_ONELEVEL },
+		{ BER_BVC( "base" ),		LDAP_SCOPE_BASE },
+		{ BER_BVC( "sub" ),		LDAP_SCOPE_SUBTREE },
+		{ BER_BVC( "subtree" ),		LDAP_SCOPE_SUBTREE },
+		{ BER_BVC( "subord" ),		LDAP_SCOPE_SUBORDINATE },
+		{ BER_BVC( "subordinate" ),	LDAP_SCOPE_SUBORDINATE },
+		{ BER_BVC( "children" ),	LDAP_SCOPE_SUBORDINATE },
+		{ BER_BVNULL,			-1 }
+	};
+	int	i;
+
+	for ( i = 0; v[ i ].scope != -1; i++ ) {
+		if ( ber_bvstrcasecmp( bv, &v[ i ].bv ) == 0 ) {
+			return v[ i ].scope;
+		}
+	}
+
 	return( -1 );
 }
 
+int
+ldap_pvt_str2scope( const char *p )
+{
+	struct berval	bv;
+
+	ber_str2bv( p, 0, 0, &bv );
+
+	return ldap_pvt_bv2scope( &bv );
+}
+
 static const char	hex[] = "0123456789ABCDEF";
 
 #define URLESC_NONE	0x0000U
@@ -484,13 +531,19 @@
 static int
 desc2str_len( LDAPURLDesc *u )
 {
-	int	sep = 0;
-	int	len = 0;
+	int		sep = 0;
+	int		len = 0;
+	int		is_ipc = 0;
+	struct berval	scope;
 
-	if ( u == NULL ) {
+	if ( u == NULL || u->lud_scheme == NULL ) {
 		return -1;
 	}
 
+	if ( !strcmp( "ldapi", u->lud_scheme )) {
+		is_ipc = 1;
+	}
+
 	if ( u->lud_exts ) {
 		len += hex_escape_len_list( u->lud_exts, URLESC_COMMA );
 		if ( !sep ) {
@@ -499,51 +552,21 @@
 	}
 
 	if ( u->lud_filter ) {
-		len +=  hex_escape_len( u->lud_filter, URLESC_NONE );
+		len += hex_escape_len( u->lud_filter, URLESC_NONE );
 		if ( !sep ) {
 			sep = 4;
 		}
 	}
 
-	switch ( u->lud_scope ) {
-	case LDAP_SCOPE_BASE:
-	case LDAP_SCOPE_ONELEVEL:
-	case LDAP_SCOPE_SUBTREE:
-#ifdef LDAP_SCOPE_SUBORDINATE
-	case LDAP_SCOPE_SUBORDINATE:
-#endif
-		switch ( u->lud_scope ) {
-		case LDAP_SCOPE_BASE:
-			len += STRLENOF( "base" );
-			break;
-
-		case LDAP_SCOPE_ONELEVEL:
-			len += STRLENOF( "one" );
-			break;
-
-		case LDAP_SCOPE_SUBTREE:
-			len += STRLENOF( "sub" );
-			break;
-
-#ifdef LDAP_SCOPE_SUBORDINATE
-		case LDAP_SCOPE_SUBORDINATE:
-			len += STRLENOF( "subordinate" );
-			break;
-
-#endif
-		}
-
+	if ( ldap_pvt_scope2bv( u->lud_scope, &scope ) == LDAP_SUCCESS ) {
+		len += scope.bv_len;
 		if ( !sep ) {
 			sep = 3;
 		}
-		break;
-
-	default:
-		break;
 	}
 
 	if ( u->lud_attrs ) {
-		len +=  hex_escape_len_list( u->lud_attrs, URLESC_NONE );
+		len += hex_escape_len_list( u->lud_attrs, URLESC_NONE );
 		if ( !sep ) {
 			sep = 2;
 		}
@@ -569,6 +592,9 @@
 	} else {
 		if ( u->lud_host && u->lud_host[0] ) {
 			len += hex_escape_len( u->lud_host, URLESC_SLASH );
+			if ( !is_ipc && strchr( u->lud_host, ':' )) {
+				len += 2;	/* IPv6, [] */
+			}
 		}
 	}
 
@@ -577,13 +603,15 @@
 	return len;
 }
 
-int
+static int
 desc2str( LDAPURLDesc *u, char *s, int len )
 {
-	int	i;
-	int	sep = 0;
-	int	sofar = 0;
-	int	gotscope = 0;
+	int		i;
+	int		sep = 0;
+	int		sofar = 0;
+	int		is_v6 = 0;
+	int		is_ipc = 0;
+	struct berval	scope = BER_BVNULL;
 
 	if ( u == NULL ) {
 		return -1;
@@ -593,22 +621,17 @@
 		return -1;
 	}
 
-	switch ( u->lud_scope ) {
-	case LDAP_SCOPE_BASE:
-	case LDAP_SCOPE_ONELEVEL:
-	case LDAP_SCOPE_SUBTREE:
-#ifdef LDAP_SCOPE_SUBORDINATE
-	case LDAP_SCOPE_SUBORDINATE:
-#endif
-		gotscope = 1;
-		break;
+	if ( u->lud_scheme && !strcmp( "ldapi", u->lud_scheme )) {
+		is_ipc = 1;
 	}
 
+	ldap_pvt_scope2bv( u->lud_scope, &scope );
+
 	if ( u->lud_exts ) {
 		sep = 5;
 	} else if ( u->lud_filter ) {
 		sep = 4;
-	} else if ( gotscope ) {
+	} else if ( !BER_BVISEMPTY( &scope ) ) {
 		sep = 3;
 	} else if ( u->lud_attrs ) {
 		sep = 2;
@@ -616,17 +639,31 @@
 		sep = 1;
 	}
 
+	if ( !is_ipc && u->lud_host && strchr( u->lud_host, ':' )) {
+		is_v6 = 1;
+	}
+
 	if ( u->lud_port ) {
-		len -= sprintf( s, "%s://%s:%d%n", u->lud_scheme,
+		len -= sprintf( s, "%s://%s%s%s:%d%n", u->lud_scheme,
+				is_v6 ? "[" : "",
 				u->lud_host ? u->lud_host : "",
+				is_v6 ? "]" : "",
 				u->lud_port, &sofar );
 
 	} else {
 		len -= sprintf( s, "%s://%n", u->lud_scheme, &sofar );
 		if ( u->lud_host && u->lud_host[0] ) {
+			if ( is_v6 ) {
+				s[sofar++] = '[';
+				len--;
+			}
 			i = hex_escape( &s[sofar], len, u->lud_host, URLESC_SLASH );
 			sofar += i;
 			len -= i;
+			if ( is_v6 ) {
+				s[sofar++] = ']';
+				len--;
+			}
 		}
 	}
 
@@ -671,32 +708,10 @@
 
 	assert( len >= 0 );
 
-	switch ( u->lud_scope ) {
-	case LDAP_SCOPE_BASE:
-		strcpy( &s[sofar], "base" );
-		sofar += STRLENOF("base");
-		len -= STRLENOF("base");
-		break;
-
-	case LDAP_SCOPE_ONELEVEL:
-		strcpy( &s[sofar], "one" );
-		sofar += STRLENOF("one");
-		len -= STRLENOF("one");
-		break;
-
-	case LDAP_SCOPE_SUBTREE:
-		strcpy( &s[sofar], "sub" );
-		sofar += STRLENOF("sub");
-		len -= STRLENOF("sub");
-		break;
-
-#ifdef LDAP_SCOPE_SUBORDINATE
-	case LDAP_SCOPE_SUBORDINATE:
-		strcpy( &s[sofar], "children" );
-		sofar += STRLENOF("children");
-		len -= STRLENOF("children");
-		break;
-#endif
+	if ( !BER_BVISNULL( &scope ) ) {
+		strcpy( &s[sofar], scope.bv_val );
+		sofar += scope.bv_len;
+		len -= scope.bv_len;
 	}
 
 	assert( len >= 0 );
@@ -770,7 +785,7 @@
 }
 
 int
-ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
+ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp, unsigned flags )
 {
 /*
  *  Pick apart the pieces of an LDAP URL.
@@ -778,11 +793,13 @@
 
 	LDAPURLDesc	*ludp;
 	char	*p, *q, *r;
-	int		i, enclosed;
+	int		i, enclosed, proto, is_v6 = 0;
 	const char *scheme = NULL;
 	const char *url_tmp;
 	char *url;
 
+	int	check_dn = 1;
+
 	if( url_in == NULL || ludpp == NULL ) {
 		return LDAP_URL_ERR_PARAM;
 	}
@@ -806,6 +823,11 @@
 
 	assert( scheme != NULL );
 
+	proto = ldap_pvt_url_scheme2proto( scheme );
+	if ( proto == -1 ) {
+		return LDAP_URL_ERR_BADSCHEME;
+	}
+
 	/* make working copy of the remainder of the URL */
 	url = LDAP_STRDUP( url_tmp );
 	if ( url == NULL ) {
@@ -836,7 +858,7 @@
 	ludp->lud_port = 0;
 	ludp->lud_dn = NULL;
 	ludp->lud_attrs = NULL;
-	ludp->lud_scope = LDAP_SCOPE_DEFAULT;
+	ludp->lud_scope = ( flags & LDAP_PVT_URL_PARSE_NODEF_SCOPE ) ? LDAP_SCOPE_BASE : LDAP_SCOPE_DEFAULT;
 	ludp->lud_filter = NULL;
 	ludp->lud_exts = NULL;
 
@@ -850,50 +872,83 @@
 
 	/* scan forward for '/' that marks end of hostport and begin. of dn */
 	p = strchr( url, '/' );
+	q = NULL;
 
 	if( p != NULL ) {
 		/* terminate hostport; point to start of dn */
 		*p++ = '\0';
+	} else {
+		/* check for Novell kludge, see below */
+		p = strchr( url, '?' );
+		if ( p ) {
+			*p++ = '\0';
+			q = p;
+			p = NULL;
+		}
 	}
 
-	/* IPv6 syntax with [ip address]:port */
-	if ( *url == '[' ) {
-		r = strchr( url, ']' );
-		if ( r == NULL ) {
-			LDAP_FREE( url );
-			ldap_free_urldesc( ludp );
-			return LDAP_URL_ERR_BADURL;
+	if ( proto != LDAP_PROTO_IPC ) {
+		/* IPv6 syntax with [ip address]:port */
+		if ( *url == '[' ) {
+			r = strchr( url, ']' );
+			if ( r == NULL ) {
+				LDAP_FREE( url );
+				ldap_free_urldesc( ludp );
+				return LDAP_URL_ERR_BADURL;
+			}
+			*r++ = '\0';
+			q = strchr( r, ':' );
+			if ( q && q != r ) {
+				LDAP_FREE( url );
+				ldap_free_urldesc( ludp );
+				return LDAP_URL_ERR_BADURL;
+			}
+			is_v6 = 1;
+		} else {
+			q = strchr( url, ':' );
 		}
-		*r++ = '\0';
-		q = strchr( r, ':' );
-	} else {
-		q = strchr( url, ':' );
-	}
 
-	if ( q != NULL ) {
-		char	*next;
+		if ( q != NULL ) {
+			char	*next;
 
-		*q++ = '\0';
-		ldap_pvt_hex_unescape( q );
+			*q++ = '\0';
+			ldap_pvt_hex_unescape( q );
 
-		if( *q == '\0' ) {
-			LDAP_FREE( url );
-			ldap_free_urldesc( ludp );
-			return LDAP_URL_ERR_BADURL;
+			if( *q == '\0' ) {
+				LDAP_FREE( url );
+				ldap_free_urldesc( ludp );
+				return LDAP_URL_ERR_BADURL;
+			}
+
+			ludp->lud_port = strtol( q, &next, 10 );
+			if ( next == q || next[0] != '\0' ) {
+				LDAP_FREE( url );
+				ldap_free_urldesc( ludp );
+				return LDAP_URL_ERR_BADURL;
+			}
+			/* check for Novell kludge */
+			if ( !p ) {
+				if ( *next != '\0' ) {
+					q = &next[1];
+				} else {
+					q = NULL;
+				}
+			}
 		}
 
-		ludp->lud_port = strtol( q, &next, 10 );
-		if ( next == q || next[0] != '\0' ) {
-			LDAP_FREE( url );
-			ldap_free_urldesc( ludp );
-			return LDAP_URL_ERR_BADURL;
+		if ( ( flags & LDAP_PVT_URL_PARSE_DEF_PORT ) && ludp->lud_port == 0 ) {
+			if ( strcmp( ludp->lud_scheme, "ldaps" ) == 0 ) {
+				ludp->lud_port = LDAPS_PORT;
+			} else {
+				ludp->lud_port = LDAP_PORT;
+			}
 		}
 	}
 
 	ldap_pvt_hex_unescape( url );
 
 	/* If [ip address]:port syntax, url is [ip and we skip the [ */
-	ludp->lud_host = LDAP_STRDUP( url + ( *url == '[' ) );
+	ludp->lud_host = LDAP_STRDUP( url + is_v6 );
 
 	if( ludp->lud_host == NULL ) {
 		LDAP_FREE( url );
@@ -901,6 +956,14 @@
 		return LDAP_URL_ERR_MEM;
 	}
 
+	if ( ( flags & LDAP_PVT_URL_PARSE_NOEMPTY_HOST )
+		&& ludp->lud_host != NULL
+		&& *ludp->lud_host == '\0' )
+	{
+		LDAP_FREE( ludp->lud_host );
+		ludp->lud_host = NULL;
+	}
+
 	/*
 	 * Kludge.  ldap://111.222.333.444:389??cn=abc,o=company
 	 *
@@ -910,25 +973,26 @@
 	 * but we need to account for it. Fortunately it can't be confused with
 	 * anything real.
 	 */
-	if( (p == NULL) && (q != NULL) && ((q = strchr( q, '?')) != NULL)) {
-		q++;		
+	if( (p == NULL) && (q != NULL) && (*q == '?') ) {
 		/* ? immediately followed by question */
-		if( *q == '?') {
-			q++;
-			if( *q != '\0' ) {
-				/* parse dn part */
-				ldap_pvt_hex_unescape( q );
-				ludp->lud_dn = LDAP_STRDUP( q );
-			} else {
-				ludp->lud_dn = LDAP_STRDUP( "" );
-			}
+		q++;
+		if( *q != '\0' ) {
+			/* parse dn part */
+			ldap_pvt_hex_unescape( q );
+			ludp->lud_dn = LDAP_STRDUP( q );
 
-			if( ludp->lud_dn == NULL ) {
-				LDAP_FREE( url );
-				ldap_free_urldesc( ludp );
-				return LDAP_URL_ERR_MEM;
-			}
+		} else if ( !( flags & LDAP_PVT_URL_PARSE_NOEMPTY_DN ) ) {
+			ludp->lud_dn = LDAP_STRDUP( "" );
+
+		} else {
+			check_dn = 0;
 		}
+
+		if ( check_dn && ludp->lud_dn == NULL ) {
+			LDAP_FREE( url );
+			ldap_free_urldesc( ludp );
+			return LDAP_URL_ERR_MEM;
+		}
 	}
 
 	if( p == NULL ) {
@@ -949,11 +1013,15 @@
 		/* parse dn part */
 		ldap_pvt_hex_unescape( p );
 		ludp->lud_dn = LDAP_STRDUP( p );
+
+	} else if ( !( flags & LDAP_PVT_URL_PARSE_NOEMPTY_DN ) ) {
+		ludp->lud_dn = LDAP_STRDUP( "" );
+
 	} else {
-		ludp->lud_dn = LDAP_STRDUP( "" );
+		check_dn = 0;
 	}
 
-	if( ludp->lud_dn == NULL ) {
+	if( check_dn && ludp->lud_dn == NULL ) {
 		LDAP_FREE( url );
 		ldap_free_urldesc( ludp );
 		return LDAP_URL_ERR_MEM;
@@ -1006,7 +1074,7 @@
 	if( *p != '\0' ) {
 		/* parse the scope */
 		ldap_pvt_hex_unescape( p );
-		ludp->lud_scope = str2scope( p );
+		ludp->lud_scope = ldap_pvt_str2scope( p );
 
 		if( ludp->lud_scope == -1 ) {
 			LDAP_FREE( url );
@@ -1103,34 +1171,7 @@
 int
 ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
 {
-	int rc = ldap_url_parse_ext( url_in, ludpp );
-
-	if( rc != LDAP_URL_SUCCESS ) {
-		return rc;
-	}
-
-	if ((*ludpp)->lud_scope == LDAP_SCOPE_DEFAULT) {
-		(*ludpp)->lud_scope = LDAP_SCOPE_BASE;
-	}
-
-	if ((*ludpp)->lud_host != NULL && *(*ludpp)->lud_host == '\0') {
-		LDAP_FREE( (*ludpp)->lud_host );
-		(*ludpp)->lud_host = NULL;
-	}
-
-	if ((*ludpp)->lud_port == 0) {
-		if( strcmp((*ludpp)->lud_scheme, "ldap") == 0 ) {
-			(*ludpp)->lud_port = LDAP_PORT;
-#ifdef LDAP_CONNECTIONLESS
-		} else if( strcmp((*ludpp)->lud_scheme, "cldap") == 0 ) {
-			(*ludpp)->lud_port = LDAP_PORT;
-#endif
-		} else if( strcmp((*ludpp)->lud_scheme, "ldaps") == 0 ) {
-			(*ludpp)->lud_port = LDAPS_PORT;
-		}
-	}
-
-	return rc;
+	return ldap_url_parse_ext( url_in, ludpp, LDAP_PVT_URL_PARSE_HISTORIC );
 }
 
 LDAPURLDesc *
@@ -1229,8 +1270,8 @@
 }
 
 static int
-ldap_url_parselist_int (LDAPURLDesc **ludlist, const char *url, const char *sep,
-	int (*url_parse)( const char *, LDAPURLDesc ** ) )
+ldap_url_parselist_int (LDAPURLDesc **ludlist, const char *url, const char *sep, unsigned flags )
+	
 {
 	int i, rc;
 	LDAPURLDesc *ludp;
@@ -1241,7 +1282,11 @@
 
 	*ludlist = NULL;
 
-	urls = ldap_str2charray(url, sep);
+	if ( sep == NULL ) {
+		sep = ", ";
+	}
+
+	urls = ldap_str2charray( url, sep );
 	if (urls == NULL)
 		return LDAP_URL_ERR_MEM;
 
@@ -1249,30 +1294,30 @@
 	for (i = 0; urls[i] != NULL; i++) ;
 	/* ...and put them in the "stack" backward */
 	while (--i >= 0) {
-		rc = url_parse( urls[i], &ludp );
+		rc = ldap_url_parse_ext( urls[i], &ludp, flags );
 		if ( rc != 0 ) {
-			ldap_charray_free(urls);
-			ldap_free_urllist(*ludlist);
+			ldap_charray_free( urls );
+			ldap_free_urllist( *ludlist );
 			*ludlist = NULL;
 			return rc;
 		}
 		ludp->lud_next = *ludlist;
 		*ludlist = ludp;
 	}
-	ldap_charray_free(urls);
+	ldap_charray_free( urls );
 	return LDAP_URL_SUCCESS;
 }
 
 int
 ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
 {
-	return ldap_url_parselist_int( ludlist, url, ", ", ldap_url_parse );
+	return ldap_url_parselist_int( ludlist, url, ", ", LDAP_PVT_URL_PARSE_HISTORIC );
 }
 
 int
-ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep )
+ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep, unsigned flags )
 {
-	return ldap_url_parselist_int( ludlist, url, sep, ldap_url_parse_ext );
+	return ldap_url_parselist_int( ludlist, url, sep, flags );
 }
 
 int

Copied: openldap/trunk/libraries/libldap/urltest.c (from rev 891, openldap/vendor/openldap-2.4.7/libraries/libldap/urltest.c)
===================================================================
--- openldap/trunk/libraries/libldap/urltest.c	                        (rev 0)
+++ openldap/trunk/libraries/libldap/urltest.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,128 @@
+/* urltest.c -- OpenLDAP URL API Test Program */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/urltest.c,v 1.1.2.3 2007/08/31 23:13:56 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENT:
+ * This program was initially developed by Pierangelo Masarati
+ * <ando at OpenLDAP.org> for inclusion in OpenLDAP Software.
+ */
+
+/*
+ * This program is designed to test the ldap_url_* functions
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+
+#include <ldap.h>
+
+#include "ldap-int.h"
+
+#include "ldap_defaults.h"
+
+int
+main(int argc, char *argv[])
+{
+	const char	*url,
+			*scope = NULL;
+	LDAPURLDesc	*lud;
+	enum {
+		IS_LDAP = 0,
+		IS_LDAPS,
+		IS_LDAPI
+	} type = IS_LDAP;
+	int		rc;
+
+	if ( argc != 2 ) {
+		fprintf( stderr, "usage: urltest <url>\n" );
+		exit( EXIT_FAILURE );
+	}
+
+	url = argv[ 1 ];
+
+	if ( ldap_is_ldaps_url( url ) ) {
+		fprintf( stdout, "LDAPS url\n" );
+		type = IS_LDAPS;
+
+	} else if ( ldap_is_ldapi_url( url ) ) {
+		fprintf( stdout, "LDAPI url\n" );
+		type = IS_LDAPI;
+
+	} else if ( ldap_is_ldap_url( url ) ) {
+		fprintf( stdout, "generic LDAP url\n" );
+
+	} else {
+		fprintf( stderr, "Need a valid LDAP url\n" );
+		exit( EXIT_FAILURE );
+	}
+
+	rc = ldap_url_parse( url, &lud );
+	if ( rc != LDAP_URL_SUCCESS ) {
+		fprintf( stderr, "ldap_url_parse(%s) failed (%d)\n", url, rc );
+		exit( EXIT_FAILURE );
+	}
+
+	fprintf( stdout, "PROTO: %s\n", lud->lud_scheme );
+	switch ( type ) {
+	case IS_LDAPI:
+		fprintf( stdout, "PATH: %s\n", lud->lud_host );
+		break;
+
+	default:
+		fprintf( stdout, "HOST: %s\n", lud->lud_host );
+		if ( lud->lud_port != 0 ) {
+			fprintf( stdout, "PORT: %d\n", lud->lud_port );
+		}
+	}
+
+	if ( lud->lud_dn && lud->lud_dn[ 0 ] ) {
+		fprintf( stdout, "DN: %s\n", lud->lud_dn );
+	}
+
+	if ( lud->lud_attrs ) {
+		int	i;
+
+		fprintf( stdout, "ATTRS:\n" );
+		for ( i = 0; lud->lud_attrs[ i ]; i++ ) {
+			fprintf( stdout, "\t%s\n", lud->lud_attrs[ i ] );
+		}
+	}
+
+	scope = ldap_pvt_scope2str( lud->lud_scope );
+	if ( scope ) {
+		fprintf( stdout, "SCOPE: %s\n", scope );
+	}
+
+	if ( lud->lud_filter ) {
+		fprintf( stdout, "FILTER: %s\n", lud->lud_filter );
+	}
+
+	if ( lud->lud_exts ) {
+		int	i;
+
+		fprintf( stdout, "EXTS:\n" );
+		for ( i = 0; lud->lud_exts[ i ]; i++ ) {
+			fprintf( stdout, "\t%s\n", lud->lud_exts[ i ] );
+		}
+	}
+
+	fprintf( stdout, "URL: %s\n", ldap_url_desc2str( lud ));
+
+	return EXIT_SUCCESS;
+}

Modified: openldap/trunk/libraries/libldap/utf-8-conv.c
===================================================================
--- openldap/trunk/libraries/libldap/utf-8-conv.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/utf-8-conv.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/utf-8-conv.c,v 1.11.2.5 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/utf-8-conv.c,v 1.16.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/utf-8.c
===================================================================
--- openldap/trunk/libraries/libldap/utf-8.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/utf-8.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* utf-8.c -- Basic UTF-8 routines */
-/* $OpenLDAP: pkg/ldap/libraries/libldap/utf-8.c,v 1.34.2.3 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/utf-8.c,v 1.36.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/util-int.c
===================================================================
--- openldap/trunk/libraries/libldap/util-int.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/util-int.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/util-int.c,v 1.51.2.5 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/util-int.c,v 1.57.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap/vlvctrl.c
===================================================================
--- openldap/trunk/libraries/libldap/vlvctrl.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/vlvctrl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/vlvctrl.c,v 1.13.2.3 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/vlvctrl.c,v 1.21.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -27,9 +27,6 @@
  * can be found in the file "build/LICENSE-2.0.1" in this distribution
  * of OpenLDAP Software.
  */
-/* Portions Copyright (C) The Internet Society (1997)
- * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
- */
 
 #include "portable.h"
 
@@ -50,19 +47,18 @@
    
    Create and encode the Virtual List View control.
 
-   ld        (IN)  An LDAP session handle, as obtained from a call to
-				   ldap_init().
+   ld        (IN)  An LDAP session handle.
    
    vlvinfop  (IN)  The address of an LDAPVLVInfo structure whose contents 
 				   are used to construct the value of the control
 				   that is created.
    
-   ctrlp     (OUT) A result parameter that will be assigned the address
+   value     (OUT) A struct berval that contains the value to be assigned to the ldctl_value member
 				   of an LDAPControl structure that contains the 
-				   VirtualListViewRequest control created by this function.
-				   The memory occupied by the LDAPControl structure
+				   VirtualListViewRequest control.
+				   The bv_val member of the berval structure
 				   SHOULD be freed when it is no longer in use by
-				   calling ldap_control_free().
+				   calling ldap_memfree().
 					  
    
    Ber encoding
@@ -87,75 +83,161 @@
  ---*/
 
 int
-ldap_create_vlv_control( LDAP *ld,
-						 LDAPVLVInfo *vlvinfop,
-						 LDAPControl **ctrlp )
+ldap_create_vlv_control_value(
+	LDAP *ld,
+	LDAPVLVInfo *vlvinfop,
+	struct berval *value )
 {
 	ber_tag_t tag;
 	BerElement *ber;
 
-	assert( ld != NULL );
+	if ( ld == NULL || vlvinfop == NULL || value == NULL ) {
+		if ( ld )
+			ld->ld_errno = LDAP_PARAM_ERROR;
+		return LDAP_PARAM_ERROR;
+	}
+
 	assert( LDAP_VALID( ld ) );
-	assert( vlvinfop != NULL );
-	assert( ctrlp != NULL );
 
-	if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
+	value->bv_val = NULL;
+	value->bv_len = 0;
+
+	ber = ldap_alloc_ber_with_options( ld );
+	if ( ber == NULL ) {
 		ld->ld_errno = LDAP_NO_MEMORY;
-		return(LDAP_NO_MEMORY);
+		return ld->ld_errno;
 	}
 
-	tag = ber_printf(ber, "{ii" /*}*/,
+	tag = ber_printf( ber, "{ii" /*}*/,
 		vlvinfop->ldvlv_before_count,
-		vlvinfop->ldvlv_after_count);
-	if( tag == LBER_ERROR ) goto exit;
+		vlvinfop->ldvlv_after_count );
+	if ( tag == LBER_ERROR ) {
+		goto error_return;
+	}
 
-	if (vlvinfop->ldvlv_attrvalue == NULL) {
-		tag = ber_printf(ber, "t{iiN}",
+	if ( vlvinfop->ldvlv_attrvalue == NULL ) {
+		tag = ber_printf( ber, "t{iiN}",
 			LDAP_VLVBYINDEX_IDENTIFIER,
 			vlvinfop->ldvlv_offset,
-			vlvinfop->ldvlv_count);
-		if( tag == LBER_ERROR ) goto exit;
+			vlvinfop->ldvlv_count );
+		if ( tag == LBER_ERROR ) {
+			goto error_return;
+		}
 
 	} else {
-		tag = ber_printf(ber, "tO",
+		tag = ber_printf( ber, "tO",
 			LDAP_VLVBYVALUE_IDENTIFIER,
-			vlvinfop->ldvlv_attrvalue);
-		if( tag == LBER_ERROR ) goto exit;
+			vlvinfop->ldvlv_attrvalue );
+		if ( tag == LBER_ERROR ) {
+			goto error_return;
+		}
 	}
 
-	if (vlvinfop->ldvlv_context) {
-		tag = ber_printf(ber, "tO",
+	if ( vlvinfop->ldvlv_context ) {
+		tag = ber_printf( ber, "tO",
 			LDAP_VLVCONTEXT_IDENTIFIER,
-			vlvinfop->ldvlv_context);
-		if( tag == LBER_ERROR ) goto exit;
+			vlvinfop->ldvlv_context );
+		if ( tag == LBER_ERROR ) {
+			goto error_return;
+		}
 	}
 
-	tag = ber_printf(ber, /*{*/ "N}"); 
-	if( tag == LBER_ERROR ) goto exit;
+	tag = ber_printf( ber, /*{*/ "N}" ); 
+	if ( tag == LBER_ERROR ) {
+		goto error_return;
+	}
 
-	ld->ld_errno = ldap_create_control(	LDAP_CONTROL_VLVREQUEST,
-		ber, 1, ctrlp);
+	if ( ber_flatten2( ber, value, 1 ) == -1 ) {
+		ld->ld_errno = LDAP_NO_MEMORY;
+	}
 
-	ber_free(ber, 1);
-	return(ld->ld_errno);
+	if ( 0 ) {
+error_return:;
+		ld->ld_errno = LDAP_ENCODING_ERROR;
+	}
 
-exit:
-	ber_free(ber, 1);
-	ld->ld_errno = LDAP_ENCODING_ERROR;
-	return(ld->ld_errno);
+	if ( ber != NULL ) {
+		ber_free( ber, 1 );
+	}
+
+	return ld->ld_errno;
 }
 
+/*---
+   ldap_create_vlv_control
+   
+   Create and encode the Virtual List View control.
 
+   ld        (IN)  An LDAP session handle.
+   
+   vlvinfop  (IN)  The address of an LDAPVLVInfo structure whose contents 
+				   are used to construct the value of the control
+				   that is created.
+   
+   ctrlp     (OUT) A result parameter that will be assigned the address
+				   of an LDAPControl structure that contains the 
+				   VirtualListViewRequest control created by this function.
+				   The memory occupied by the LDAPControl structure
+				   SHOULD be freed when it is no longer in use by
+				   calling ldap_control_free().
+					  
+   
+   Ber encoding
+   
+   VirtualListViewRequest ::= SEQUENCE {
+		beforeCount  INTEGER (0 .. maxInt),
+		afterCount   INTEGER (0 .. maxInt),
+		CHOICE {
+				byoffset [0] SEQUENCE, {
+				offset        INTEGER (0 .. maxInt),
+				contentCount  INTEGER (0 .. maxInt) }
+				[1] greaterThanOrEqual assertionValue }
+		contextID     OCTET STRING OPTIONAL }
+	  
+   
+   Note:  The first time the VLV control is created, the ldvlv_context
+		  field of the LDAPVLVInfo structure should be set to NULL.
+		  The context obtained from calling ldap_parse_vlv_control()
+		  should be used as the context in the next ldap_create_vlv_control
+		  call.
+
+ ---*/
+
+int
+ldap_create_vlv_control(
+	LDAP *ld,
+	LDAPVLVInfo *vlvinfop,
+	LDAPControl **ctrlp )
+{
+	struct berval	value;
+
+	if ( ctrlp == NULL ) {
+		ld->ld_errno = LDAP_PARAM_ERROR;
+		return ld->ld_errno;
+	}
+
+	ld->ld_errno = ldap_create_vlv_control_value( ld, vlvinfop, &value );
+	if ( ld->ld_errno == LDAP_SUCCESS ) {
+
+		ld->ld_errno = ldap_control_create( LDAP_CONTROL_VLVREQUEST,
+			1, &value, 0, ctrlp );
+		if ( ld->ld_errno != LDAP_SUCCESS ) {
+			LDAP_FREE( value.bv_val );
+		}
+	}
+
+	return ld->ld_errno;
+}
+
+
 /*---
-   ldap_parse_vlv_control
+   ldap_parse_vlvresponse_control
    
    Decode the Virtual List View control return information.
 
    ld           (IN)   An LDAP session handle.
    
-   ctrls        (IN)   The address of a NULL-terminated array of 
-					   LDAPControl structures, typically obtained 
-					   by a call to ldap_parse_result().
+   ctrl         (IN)   The address of the LDAPControl structure.
    
    target_posp	(OUT)  This result parameter is filled in with the list
 					   index of the target entry.  If this parameter is
@@ -203,18 +285,16 @@
 ---*/
 
 int
-ldap_parse_vlv_control(
-	LDAP           *ld,
-	LDAPControl    **ctrls,
-	unsigned long  *target_posp,
-	unsigned long  *list_countp,
+ldap_parse_vlvresponse_control(
+	LDAP *ld,
+	LDAPControl *ctrl,
+	ber_int_t *target_posp,
+	ber_int_t *list_countp,
 	struct berval  **contextp,
-	int            *errcodep )
+	ber_int_t *errcodep )
 {
 	BerElement  *ber;
-	LDAPControl *pControl;
-	int i;
-	unsigned long pos, count, err;
+	ber_int_t pos, count, err;
 	ber_tag_t tag, berTag;
 	ber_len_t berLen;
 
@@ -225,25 +305,19 @@
 		*contextp = NULL;	 /* Make sure we return a NULL if error occurs. */
 	}
 
-	if (ctrls == NULL) {
-		ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
+	if (ctrl == NULL) {
+		ld->ld_errno = LDAP_PARAM_ERROR;
 		return(ld->ld_errno);
 	}
 
-	/* Search the list of control responses for a VLV control. */
-	for (i=0; ctrls[i]; i++) {
-		pControl = ctrls[i];
-		if (!strcmp(LDAP_CONTROL_VLVRESPONSE, pControl->ldctl_oid))
-			goto foundVLVControl;
+	if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) {
+		/* Not VLV Response control */
+		ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
+		return(ld->ld_errno);
 	}
 
-	/* No sort control was found. */
-	ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
-	return(ld->ld_errno);
-
-foundVLVControl:
 	/* Create a BerElement from the berval returned in the control. */
-	ber = ber_init(&pControl->ldctl_value);
+	ber = ber_init(&ctrl->ldctl_value);
 
 	if (ber == NULL) {
 		ld->ld_errno = LDAP_NO_MEMORY;
@@ -277,15 +351,9 @@
 	ber_free(ber, 1);
 
 	/* Return data to the caller for items that were requested. */
-	if (target_posp) {
-		*target_posp = pos;
-	}
-	if (list_countp) {
-		*list_countp = count;
-	}
-	if (errcodep) {
-		*errcodep = err;
-	}
+	if (target_posp) *target_posp = pos;
+	if (list_countp) *list_countp = count;
+	if (errcodep) *errcodep = err;
 
 	ld->ld_errno = LDAP_SUCCESS;
 	return(ld->ld_errno);

Modified: openldap/trunk/libraries/libldap/whoami.c
===================================================================
--- openldap/trunk/libraries/libldap/whoami.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap/whoami.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap/whoami.c,v 1.6.2.3 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap/whoami.c,v 1.10.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -68,7 +68,7 @@
 	assert( LDAP_VALID( ld ) );
 	assert( msgidp != NULL );
 
-	rc = ldap_extended_operation( ld, LDAP_EXOP_X_WHO_AM_I,
+	rc = ldap_extended_operation( ld, LDAP_EXOP_WHO_AM_I,
 		NULL, sctrls, cctrls, msgidp );
 
 	return rc;
@@ -88,7 +88,7 @@
 	rc = ldap_whoami( ld, sctrls, cctrls, &msgid );
 	if ( rc != LDAP_SUCCESS ) return rc;
 
-	if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) {
+	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res ) {
 		return ld->ld_errno;
 	}
 

Modified: openldap/trunk/libraries/libldap_r/Makefile.in
===================================================================
--- openldap/trunk/libraries/libldap_r/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for LDAP -lldap
-# $OpenLDAP: pkg/ldap/libraries/libldap_r/Makefile.in,v 1.70.2.5 2007/01/02 21:43:50 kurt Exp $
+# $OpenLDAP: pkg/ldap/libraries/libldap_r/Makefile.in,v 1.79.2.3 2007/08/31 23:13:56 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -22,29 +22,29 @@
 	bind.c open.c result.c error.c compare.c search.c \
 	controls.c messages.c references.c extended.c cyrus.c \
 	modify.c add.c modrdn.c delete.c abandon.c \
-	sasl.c sbind.c kbind.c unbind.c cancel.c \
+	sasl.c sbind.c unbind.c cancel.c \
 	filter.c free.c sort.c passwd.c whoami.c \
 	getdn.c getentry.c getattr.c getvalues.c addentry.c \
-	request.c os-ip.c url.c sortctrl.c vlvctrl.c \
+	request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \
 	init.c options.c print.c string.c util-int.c schema.c \
 	charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \
-	turn.c groupings.c txn.c ppolicy.c
-SRCS	= threads.c rdwr.c tpool.c rq.c \
+	turn.c ppolicy.c dds.c txn.c ldap_sync.c stctrl.c
+SRCS	= threads.c rdwr.c rmutex.c tpool.c rq.c \
 	thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \
 	thr_pth.c thr_stub.c thr_debug.c
-OBJS	= threads.lo rdwr.lo tpool.lo  rq.lo \
+OBJS	= threads.lo rdwr.lo rmutex.lo tpool.lo  rq.lo \
 	thr_posix.lo thr_cthreads.lo thr_thr.lo thr_lwp.lo thr_nt.lo \
 	thr_pth.lo thr_stub.lo thr_debug.lo \
 	bind.lo open.lo result.lo error.lo compare.lo search.lo \
 	controls.lo messages.lo references.lo extended.lo cyrus.lo \
 	modify.lo add.lo modrdn.lo delete.lo abandon.lo \
-	sasl.lo sbind.lo kbind.lo unbind.lo cancel.lo \
+	sasl.lo sbind.lo unbind.lo cancel.lo \
 	filter.lo free.lo sort.lo passwd.lo whoami.lo \
 	getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
-	request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \
+	request.lo os-ip.lo url.lo pagectrl.lo sortctrl.lo vlvctrl.lo \
 	init.lo options.lo print.lo string.lo util-int.lo schema.lo \
 	charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \
-	turn.lo groupings.lo txn.lo ppolicy.lo
+	turn.lo ppolicy.lo dds.lo txn.lo ldap_sync.lo stctrl.lo
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries

Modified: openldap/trunk/libraries/libldap_r/ldap_thr_debug.h
===================================================================
--- openldap/trunk/libraries/libldap_r/ldap_thr_debug.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/ldap_thr_debug.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldap_thr_debug.h - preprocessor magic for LDAP_THREAD_DEBUG */
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/ldap_thr_debug.h,v 1.1.2.3 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/ldap_thr_debug.h,v 1.3.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2005-2007 The OpenLDAP Foundation.
@@ -18,7 +18,7 @@
 
 /*
  * libldap_r .c files should include this file after ldap_pvt_thread.h,
- * with the appropriate LDAP_THREAD*_IMPLEMENTATION macro defined.
+ * with the appropriate LDAP_THREAD*_IMPLEMENTATION macro(s) defined.
  */
 
 #ifndef _LDAP_PVT_THREAD_H
@@ -28,19 +28,35 @@
 /*
  * Support for thr_debug.c:
  *
- * thr_debug.c defines the ldap_pvt_*() as wrappers around
- * ldap_int_*(), and ldap_debug_*() around ldap_int_*().
+ * thr_debug.c defines ldap_pvt_thread_* as wrappers around the real
+ * ldap_pvt_thread_* implementation, which this file renames to
+ * ldap_int_thread_*.
  *
- * Renames ldap_pvt_thread_* names to ldap_int_thread_*, and a few
- * ldap_int_*() names to ldap_debug_*().  Includes "ldap_pvt_thread.h"
- * to declare these renamed functions, and undefines the macros
- * afterwards when included from thr_debug.c.  So,
+ * Implementation:
  *
- * libldap_r/<not thr_debug.c> define ldap_int_* instead of ldap_pvt_*.
+ * This file re#defines selected ldap_pvt_thread_* names to
+ * ldap_int_thread_*, which will be used from wrappers in thr_debug.c.
+ * Two ldap_int_*() calls are redirected to call ldap_debug_*(): These
+ * are wrappers around the originals, whose definitions are not renamed.
+ * This file then #includes ldap_pvt_thread.h to declare the renamed
+ * functions/types.  If #included from thr_debug.c it finally #undefines
+ * the macros again.
+ *
+ * include/ldap_pvt_thread.h declares the typedefs ldap_pvt_thread*_t as
+ * either wrapper types ldap_debug_thread*_t or their usual definitions
+ * ldap_int_thread*_t, depending on the LDAP_THREAD_DEBUG_WRAP option.
+ * When defining the underlying implementation, this file then redirects
+ * the type names back to the original ldap_int_thread*_t types.
+ * include/ldap_<int,pvt>_thread.h also do some thr_debug magic.
+ *
+ * So,
+ * libldap_r/<not thr_debug.c> thus define ldap_int_thread_*() instead
+ * of ldap_pvt_thread_*().
+ * thr_debug.c defines the ldap_pvt_*() and ldap_debug_*() functions.
  * In thread.c, ldap_pvt_thread_<initialize/destroy>() will call
- * ldap_debug_*() instead of ldap_int_*().
- * In tpool.c, ldap_int_thread_pool_shutdown() has thr_debug support
- * which treats ldap_pvt_thread_pool_destroy() the same way.
+ * ldap_debug_thread_*() instead of ldap_int_thread_*().
+ * In tpool.c, ldap_int_thread_pool_shutdown() has explicit thr_debug.c
+ * support which treats ldap_pvt_thread_pool_destroy() the same way.
  */
 
 #ifndef LDAP_THREAD_IMPLEMENTATION		/* for first part of threads.c */

Modified: openldap/trunk/libraries/libldap_r/rdwr.c
===================================================================
--- openldap/trunk/libraries/libldap_r/rdwr.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/rdwr.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/rdwr.c,v 1.23.2.5 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/rdwr.c,v 1.28.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -64,6 +64,7 @@
 #ifdef LDAP_RDWR_DEBUG
 	/* keep track of who has these locks */
 #define	MAX_READERS	32
+	int ltrw_more_readers; /* Set if ltrw_readers[] is incomplete */
 	ldap_pvt_thread_t ltrw_readers[MAX_READERS];
 	ldap_pvt_thread_t ltrw_writer;
 #endif
@@ -173,7 +174,10 @@
 	}
 
 #ifdef LDAP_RDWR_DEBUG
-	rw->ltrw_readers[rw->ltrw_r_active] = ldap_pvt_thread_self();
+	if( rw->ltrw_r_active < MAX_READERS )
+		rw->ltrw_readers[rw->ltrw_r_active] = ldap_pvt_thread_self();
+	else
+		rw->ltrw_more_readers = 1;
 #endif
 	rw->ltrw_r_active++;
 
@@ -209,7 +213,10 @@
 	}
 
 #ifdef LDAP_RDWR_DEBUG
-	rw->ltrw_readers[rw->ltrw_r_active] = ldap_pvt_thread_self();
+	if( rw->ltrw_r_active < MAX_READERS )
+		rw->ltrw_readers[rw->ltrw_r_active] = ldap_pvt_thread_self();
+	else
+		rw->ltrw_more_readers = 1;
 #endif
 	rw->ltrw_r_active++;
 
@@ -233,23 +240,25 @@
 
 	ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
 
+	rw->ltrw_r_active--;
 #ifdef LDAP_RDWR_DEBUG
 	/* Remove us from the list of readers */
-	{ int i, j;
-	ldap_pvt_thread_t self = ldap_pvt_thread_self();
-
-	for (i=0; i<rw->ltrw_r_active;i++)
 	{
-		if (rw->ltrw_readers[i] == self) {
-			for (j=i; j<rw->ltrw_r_active-1; j++)
-				rw->ltrw_readers[j] = rw->ltrw_readers[j+1];
-			rw->ltrw_readers[j] = 0;
-			break;
+		ldap_pvt_thread_t self = ldap_pvt_thread_self();
+		int i, j;
+		for( i = j = rw->ltrw_r_active; i >= 0; i--) {
+			if (rw->ltrw_readers[i] == self) {
+				rw->ltrw_readers[i] = rw->ltrw_readers[j];
+				rw->ltrw_readers[j] = 0;
+				break;
+			}
 		}
+		if( !rw->ltrw_more_readers )
+			assert( i >= 0 );
+		else if( j == 0 )
+			rw->ltrw_more_readers = 0;
 	}
-	}
 #endif
-	rw->ltrw_r_active--;
 
 	assert( rw->ltrw_w_active >= 0 ); 
 	assert( rw->ltrw_w_wait >= 0 ); 
@@ -372,6 +381,7 @@
 	}
 
 #ifdef LDAP_RDWR_DEBUG
+	assert( rw->ltrw_writer == ldap_pvt_thread_self() );
 	rw->ltrw_writer = 0;
 #endif
 	ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );

Copied: openldap/trunk/libraries/libldap_r/rmutex.c (from rev 891, openldap/vendor/openldap-2.4.7/libraries/libldap_r/rmutex.c)
===================================================================
--- openldap/trunk/libraries/libldap_r/rmutex.c	                        (rev 0)
+++ openldap/trunk/libraries/libldap_r/rmutex.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,219 @@
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/rmutex.c,v 1.2.2.3 2007/08/31 23:13:56 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2006-2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* This work was initially developed by Howard Chu for inclusion
+ * in OpenLDAP Software.
+ */
+
+/*
+ * This is an implementation of recursive mutexes.
+ */
+
+#include "portable.h"
+
+#include <ac/stdlib.h>
+
+#include <ac/errno.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+
+struct ldap_int_thread_rmutex_s {
+	ldap_pvt_thread_mutex_t ltrm_mutex;
+	ldap_pvt_thread_cond_t ltrm_cond;
+	ldap_pvt_thread_t ltrm_owner;
+	int ltrm_valid;
+#define LDAP_PVT_THREAD_RMUTEX_VALID	0x0cdb
+	int ltrm_depth;
+	int ltrm_waits;
+};
+
+static const ldap_pvt_thread_t tid_zero;
+
+int 
+ldap_pvt_thread_rmutex_init( ldap_pvt_thread_rmutex_t *rmutex )
+{
+	struct ldap_int_thread_rmutex_s *rm;
+
+	assert( rmutex != NULL );
+
+	rm = (struct ldap_int_thread_rmutex_s *) LDAP_CALLOC( 1,
+		sizeof( struct ldap_int_thread_rmutex_s ) );
+	if ( !rm )
+		return LDAP_NO_MEMORY;
+
+	/* we should check return results */
+	ldap_pvt_thread_mutex_init( &rm->ltrm_mutex );
+	ldap_pvt_thread_cond_init( &rm->ltrm_cond );
+
+	rm->ltrm_valid = LDAP_PVT_THREAD_RMUTEX_VALID;
+
+	*rmutex = rm;
+	return 0;
+}
+
+int 
+ldap_pvt_thread_rmutex_destroy( ldap_pvt_thread_rmutex_t *rmutex )
+{
+	struct ldap_int_thread_rmutex_s *rm;
+
+	assert( rmutex != NULL );
+	rm = *rmutex;
+
+	assert( rm != NULL );
+	assert( rm->ltrm_valid == LDAP_PVT_THREAD_RMUTEX_VALID );
+
+	if( rm->ltrm_valid != LDAP_PVT_THREAD_RMUTEX_VALID )
+		return LDAP_PVT_THREAD_EINVAL;
+
+	ldap_pvt_thread_mutex_lock( &rm->ltrm_mutex );
+
+	assert( rm->ltrm_depth >= 0 );
+	assert( rm->ltrm_waits >= 0 );
+
+	/* in use? */
+	if( rm->ltrm_depth > 0 || rm->ltrm_waits > 0 ) {
+		ldap_pvt_thread_mutex_unlock( &rm->ltrm_mutex );
+		return LDAP_PVT_THREAD_EBUSY;
+	}
+
+	rm->ltrm_valid = 0;
+
+	ldap_pvt_thread_mutex_unlock( &rm->ltrm_mutex );
+
+	ldap_pvt_thread_mutex_destroy( &rm->ltrm_mutex );
+	ldap_pvt_thread_cond_destroy( &rm->ltrm_cond );
+
+	LDAP_FREE(rm);
+	*rmutex = NULL;
+	return 0;
+}
+
+int ldap_pvt_thread_rmutex_lock( ldap_pvt_thread_rmutex_t *rmutex,
+	ldap_pvt_thread_t owner )
+{
+	struct ldap_int_thread_rmutex_s *rm;
+
+	assert( rmutex != NULL );
+	rm = *rmutex;
+
+	assert( rm != NULL );
+	assert( rm->ltrm_valid == LDAP_PVT_THREAD_RMUTEX_VALID );
+
+	if( rm->ltrm_valid != LDAP_PVT_THREAD_RMUTEX_VALID )
+		return LDAP_PVT_THREAD_EINVAL;
+
+	ldap_pvt_thread_mutex_lock( &rm->ltrm_mutex );
+
+	assert( rm->ltrm_depth >= 0 );
+	assert( rm->ltrm_waits >= 0 );
+
+	if( rm->ltrm_depth > 0 ) {
+		/* already locked */
+		if ( !ldap_pvt_thread_equal( rm->ltrm_owner, owner )) {
+			rm->ltrm_waits++;
+			do {
+				ldap_pvt_thread_cond_wait( &rm->ltrm_cond,
+					&rm->ltrm_mutex );
+			} while( rm->ltrm_depth > 0 );
+
+			rm->ltrm_waits--;
+			assert( rm->ltrm_waits >= 0 );
+			rm->ltrm_owner = owner;
+		}
+	} else {
+		rm->ltrm_owner = owner;
+	}
+
+	rm->ltrm_depth++;
+
+	ldap_pvt_thread_mutex_unlock( &rm->ltrm_mutex );
+
+	return 0;
+}
+
+int ldap_pvt_thread_rmutex_trylock( ldap_pvt_thread_rmutex_t *rmutex,
+	ldap_pvt_thread_t owner )
+{
+	struct ldap_int_thread_rmutex_s *rm;
+
+	assert( rmutex != NULL );
+	rm = *rmutex;
+
+	assert( rm != NULL );
+	assert( rm->ltrm_valid == LDAP_PVT_THREAD_RMUTEX_VALID );
+
+	if( rm->ltrm_valid != LDAP_PVT_THREAD_RMUTEX_VALID )
+		return LDAP_PVT_THREAD_EINVAL;
+
+	ldap_pvt_thread_mutex_lock( &rm->ltrm_mutex );
+
+	assert( rm->ltrm_depth >= 0 );
+	assert( rm->ltrm_waits >= 0 );
+
+	if( rm->ltrm_depth > 0 ) {
+		if ( !ldap_pvt_thread_equal( owner, rm->ltrm_owner )) {
+			ldap_pvt_thread_mutex_unlock( &rm->ltrm_mutex );
+			return LDAP_PVT_THREAD_EBUSY;
+		}
+	} else {
+		rm->ltrm_owner = owner;
+	}
+
+	rm->ltrm_depth++;
+
+	ldap_pvt_thread_mutex_unlock( &rm->ltrm_mutex );
+
+	return 0;
+}
+
+int ldap_pvt_thread_rmutex_unlock( ldap_pvt_thread_rmutex_t *rmutex,
+	ldap_pvt_thread_t owner )
+{
+	struct ldap_int_thread_rmutex_s *rm;
+
+	assert( rmutex != NULL );
+	rm = *rmutex;
+
+	assert( rm != NULL );
+	assert( rm->ltrm_valid == LDAP_PVT_THREAD_RMUTEX_VALID );
+
+	if( rm->ltrm_valid != LDAP_PVT_THREAD_RMUTEX_VALID )
+		return LDAP_PVT_THREAD_EINVAL;
+
+	ldap_pvt_thread_mutex_lock( &rm->ltrm_mutex );
+
+	if( !ldap_pvt_thread_equal( owner, rm->ltrm_owner )) {
+		ldap_pvt_thread_mutex_unlock( &rm->ltrm_mutex );
+		return LDAP_PVT_THREAD_EINVAL;
+	}
+
+	rm->ltrm_depth--;
+	if ( !rm->ltrm_depth )
+		rm->ltrm_owner = tid_zero;
+
+	assert( rm->ltrm_depth >= 0 );
+	assert( rm->ltrm_waits >= 0 );
+
+	if ( !rm->ltrm_depth && rm->ltrm_waits ) {
+		ldap_pvt_thread_cond_signal( &rm->ltrm_cond );
+	}
+
+	ldap_pvt_thread_mutex_unlock( &rm->ltrm_mutex );
+
+	return 0;
+}
+

Modified: openldap/trunk/libraries/libldap_r/rq.c
===================================================================
--- openldap/trunk/libraries/libldap_r/rq.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/rq.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/rq.c,v 1.17.2.5 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/rq.c,v 1.23.2.3 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap_r/thr_cthreads.c
===================================================================
--- openldap/trunk/libraries/libldap_r/thr_cthreads.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/thr_cthreads.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* thr_cthreads.c - wrapper for mach cthreads */
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_cthreads.c,v 1.17.2.4 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_cthreads.c,v 1.20.2.3 2007/11/07 20:58:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -153,4 +153,28 @@
 	return cthread_self();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+	return cthread_keycreate( key );
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+	return( 0 );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+	return cthread_setspecific( key, data );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+	return cthread_getspecific( key, data );
+}
+
 #endif /* HAVE_MACH_CTHREADS */

Modified: openldap/trunk/libraries/libldap_r/thr_debug.c
===================================================================
--- openldap/trunk/libraries/libldap_r/thr_debug.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/thr_debug.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* thr_debug.c - wrapper around the chosen thread wrapper, for debugging. */
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_debug.c,v 1.1.2.5 2007/05/31 21:32:43 hallvard Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_debug.c,v 1.5.2.3 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2005-2007 The OpenLDAP Foundation.
@@ -15,19 +15,27 @@
  */
 
 /*
- * This package provides three types of thread operation debugging:
+ * This package provides several types of thread operation debugging:
  *
- * - Print error messages and abort() when thread operations fail:
- *   Operations on threads, mutexes, condition variables, rdwr locks.
- *   Some thread pool operations are also checked, but not those for
- *   which failure can happen in normal slapd operation.
+ * - Check the results of operations on threads, mutexes, condition
+ *   variables and read/write locks.  Also check some thread pool
+ *   operations, but not those for which failure can happen in normal
+ *   slapd operation.
  *
- * - Wrap those types except threads and pools in structs that
- *   contain a state variable or a pointer to dummy allocated memory,
- *   and check that on all operations.  The dummy memory variant lets
- *   malloc debuggers see some incorrect use as memory leaks, access
- *   to freed memory, etc.
+ * - Wrap those types except threads and pools in structs with state
+ *   information, and check that on all operations:
  *
+ *   + Check that the resources are initialized and are only used at
+ *     their original address (i.e. not realloced or copied).
+ *
+ *   + Check the owner (thread ID) on mutex operations.
+ *
+ *   + Optionally allocate a reference to a byte of dummy memory.
+ *     This lets malloc debuggers see some incorrect use as memory
+ *     leaks, access to freed memory, etc.
+ *
+ * - Print an error message and by default abort() upon errors.
+ *
  * - Print a count of leaked thread resources after cleanup.
  *
  * Compile-time (./configure) setup:  Macros defined in CPPFLAGS.
@@ -38,6 +46,8 @@
  *   LDAP_UINTPTR_T=integer type to hold pointers, preferably unsigned.
  *      Used by dummy memory option "scramble". Default = unsigned long.
  *
+ *   LDAP_DEBUG_THREAD_NONE = initializer for a "no thread" thread ID.
+ *
  *   In addition, you may need to set up an implementation-specific way
  *      to enable whatever error checking your thread library provides.
  *      Currently only implemented for Posix threads (pthreads), where
@@ -45,24 +55,39 @@
  *      is PTHREAD_MUTEX_ERRORCHECK, or PTHREAD_MUTEX_ERRORCHECK_NP for
  *      Linux threads.  See pthread_mutexattr_settype(3).
  *
- * Run-time configuration:  Environment variable LDAP_THREAD_DEBUG.
+ * Run-time configuration:
  *
+ *  Memory debugging tools:
+ *   Tools that report uninitialized memory accesses should disable
+ *   such warnings about the function debug_already_initialized().
+ *   Alternatively, include "noreinit" (below) in $LDAP_THREAD_DEBUG.
+ *
+ *  Environment variable $LDAP_THREAD_DEBUG:
  *   The variable may contain a comma- or space-separated option list.
  *   Options:
- *      off      - Disable this package.
- *   Error checking:
+ *      off      - Disable this package.  (It still slows things down).
+ *      tracethreads - Report create/join/exit/kill of threads.
  *      noabort  - Do not abort() on errors.
  *      noerror  - Do not report errors.  Implies noabort.
  *      nocount  - Do not report counts of unreleased resources.
- *   State variable/dummy memory, unless type wrapping is disabled:
- *      noalloc  - Default.  Use a state variable, not dummy memory.
- *      dupinit  - Implies noalloc.  Check if resources that have
- *                 not been destroyed are reinitialized.  Tools that
- *                 report uninitialized memory access should disable
- *                 such warnings about debug_already_initialized().
- *      alloc    - Allocate dummy memory and store pointers as-is.
- *                 Malloc debuggers might not notice unreleased
- *                 resources in global variables as memory leaks.
+ *      nosync   - Disable tests that use synchronizaion and thus
+ *                 clearly affect thread scheduling:
+ *                 Implies nocount, and cancels threadID if that is set.
+ *                 Note that if you turn on tracethreads or malloc
+ *                 debugging, these also use library calls which may
+ *                 affect thread scheduling (fprintf and malloc).
+ *   The following options do not apply if type wrapping is disabled:
+ *      nomem    - Do not check memory operations.
+ *                 Implies noreinit,noalloc.
+ *      noreinit - Do not catch reinitialization of existing resources.
+ *                 (That test accesses uninitialized memory).
+ *      threadID - Trace thread IDs.  Currently mostly useless.
+ *     Malloc debugging -- allocate dummy memory for initialized
+ *     resources, so malloc debuggers will report them as memory leaks:
+ *      noalloc  - Default.  Do not allocate dummy memory.
+ *      alloc    - Store a pointer to dummy memory.   However, leak
+ *                 detectors might not catch unreleased resources in
+ *                 global variables.
  *      scramble - Store bitwise complement of dummy memory pointer.
  *                 That never escapes memory leak detectors -
  *                 but detection while the program is running will
@@ -71,8 +96,6 @@
  *      adjptr   - Point to end of dummy memory.
  *                 Purify reports these as "potential leaks" (PLK).
  *                 I have not checked other malloc debuggers.
- *   Tracing:
- *      tracethreads - Report create/join/exit/kill of threads.
  */
 
 #include "portable.h"
@@ -91,18 +114,42 @@
 #define LDAP_THREAD_POOL_IMPLEMENTATION
 #include "ldap_thr_debug.h"  /* Get the underlying implementation */
 
+#ifndef LDAP_THREAD_DEBUG_WRAP
+#undef	LDAP_THREAD_DEBUG_THREAD_ID
+#elif !defined LDAP_THREAD_DEBUG_THREAD_ID
+#define	LDAP_THREAD_DEBUG_THREAD_ID 1
+#endif
 
+/* Use native malloc - the OpenLDAP wrappers may defeat malloc debuggers */
+#undef malloc
+#undef calloc
+#undef realloc
+#undef free
+
+
 /* Options from environment variable $LDAP_THREAD_DEBUG */
 enum { Count_no = 0, Count_yes, Count_reported, Count_reported_more };
-static int nodebug, noabort, noerror, count = Count_yes, options_done;
+static int count = Count_yes;
 #ifdef LDAP_THREAD_DEBUG_WRAP
 enum { Wrap_noalloc, Wrap_alloc, Wrap_scramble, Wrap_adjptr };
-static int dupinit, wraptype = Wrap_noalloc, wrap_offset, unwrap_offset;
+static int wraptype = Wrap_noalloc, wrap_offset, unwrap_offset;
+static int nomem, noreinit;
 #endif
-static int tracethreads;
+#if LDAP_THREAD_DEBUG_THREAD_ID +0
+static int threadID;
+#else
+enum { threadID = 0 };
+#endif
+static int nodebug, noabort, noerror, nosync, tracethreads;
+static int wrap_threads;
+static int options_done;
 
+
+/* ldap_pvt_thread_initialize() called, ldap_pvt_thread_destroy() not called */
 static int threading_enabled;
 
+
+/* Resource counts */
 enum {
 	Idx_unexited_thread, Idx_unjoined_thread, Idx_locked_mutex,
 	Idx_mutex, Idx_cond, Idx_rdwr, Idx_tpool, Idx_max
@@ -115,52 +162,72 @@
 static ldap_int_thread_mutex_t resource_mutexes[Idx_max];
 
 
-/*
- * Making ldap_pvt_thread_t a wrapper around ldap_int_thread_t would
- * slow down ldap_pvt_thread_self(), so keep a list of threads instead.
- */
-typedef struct ldap_debug_thread_s {
-	ldap_pvt_thread_t			wrapped;
-	ldap_debug_usage_info_t		usage;
-	int							detached;
-	int							freeme, idx;
-} ldap_debug_thread_t;
+/* Hide pointers from malloc debuggers. */
+#define SCRAMBLE(ptr) (~(LDAP_UINTPTR_T) (ptr))
+#define UNSCRAMBLE_usagep(num) ((ldap_debug_usage_info_t *) ~(num))
+#define UNSCRAMBLE_dummyp(num) ((unsigned char *) ~(num))
 
-static ldap_debug_thread_t		**thread_info;
-static unsigned int				thread_info_size, thread_info_used;
-static ldap_int_thread_mutex_t	thread_info_mutex;
 
-
 #define WARN(var, msg)   (warn (__FILE__, __LINE__, (msg), #var, (var)))
-#define ERROR(var,msg)   (error(__FILE__, __LINE__, (msg), #var, (var)))
 #define WARN_IF(rc, msg) {if (rc) warn (__FILE__, __LINE__, (msg), #rc, (rc));}
-#define ERROR_IF(rc,msg) {if (rc) error(__FILE__, __LINE__, (msg), #rc, (rc));}
 
+#define ERROR(var, msg) { \
+	if (!noerror) { \
+		errmsg(__FILE__, __LINE__, (msg), #var, (var)); \
+		if( !noabort ) abort(); \
+	} \
+}
+
+#define ERROR_IF(rc, msg) { \
+	if (!noerror) { \
+		int rc_ = (rc); \
+		if (rc_) { \
+			errmsg(__FILE__, __LINE__, (msg), #rc, rc_); \
+			if( !noabort ) abort(); \
+		} \
+	} \
+}
+
+#ifdef LDAP_THREAD_DEBUG_WRAP
+#define MEMERROR_IF(rc, msg, mem_act) { \
+	if (!noerror) { \
+		int rc_ = (rc); \
+		if (rc_) { \
+			errmsg(__FILE__, __LINE__, (msg), #rc, rc_); \
+			if( wraptype != Wrap_noalloc ) { mem_act; } \
+			if( !noabort ) abort(); \
+		} \
+	} \
+}
+#endif /* LDAP_THREAD_DEBUG_WRAP */
+
 #if 0
 static void
 warn( const char *file, int line, const char *msg, const char *var, int val )
 {
-	fprintf( stderr, "%s:%d: %s warning: %s is %d\n",
+	fprintf( stderr,
+		(strpbrk( var, "!=" )
+		 ? "%s:%d: %s warning: %s\n"
+		 : "%s:%d: %s warning: %s is %d\n"),
 		file, line, msg, var, val );
 }
 #endif
 
 static void
-error( const char *file, int line, const char *msg, const char *var, int val )
+errmsg( const char *file, int line, const char *msg, const char *var, int val )
 {
-	if( !noerror ) {
-		fprintf( stderr, "%s:%d: %s error: %s is %d\n",
-			file, line, msg, var, val );
-		if( !noabort )
-			abort();
-	}
+	fprintf( stderr,
+		(strpbrk( var, "!=" )
+		 ? "%s:%d: %s error: %s\n"
+		 : "%s:%d: %s error: %s is %d\n"),
+		file, line, msg, var, val );
 }
 
 static void
 count_resource_leaks( void )
 {
 	int i, j;
-	char errbuf[200], *delim = "Leaked";
+	char errbuf[200];
 	if( count == Count_yes ) {
 		count = Count_reported;
 #if 0 /* Could break if there are still threads after atexit */
@@ -168,15 +235,12 @@
 			j |= ldap_int_thread_mutex_destroy( &resource_mutexes[i] );
 		WARN_IF( j, "ldap_debug_thread_destroy:mutexes" );
 #endif
-		for( i = j = 0; i < Idx_max; i++ ) {
-			if( resource_counts[i] ) {
-				j += sprintf( errbuf + j, "%s %d %s",
-					delim, resource_counts[i], resource_names[i] );
-				delim = ",";
-			}
-		}
+		for( i = j = 0; i < Idx_max; i++ )
+			if( resource_counts[i] )
+				j += sprintf( errbuf + j, ", %d %s",
+					resource_counts[i], resource_names[i] );
 		if( j )
-			fprintf( stderr, "%s:%d: %s.\n", __FILE__, __LINE__, errbuf );
+			fprintf( stderr, "== thr_debug: Leaked%s. ==\n", errbuf + 1 );
 	}
 }
 
@@ -191,9 +255,14 @@
 		{ "noabort",    &noabort,  1 },
 		{ "noerror",    &noerror,  1 },
 		{ "nocount",    &count,    Count_no },
+		{ "nosync",     &nosync,   1 },
+#if LDAP_THREAD_DEBUG_THREAD_ID +0
+		{ "threadID",   &threadID, 1 },
+#endif
 #ifdef LDAP_THREAD_DEBUG_WRAP
+		{ "nomem",      &nomem,    1 },
+		{ "noreinit",   &noreinit, 1 },
 		{ "noalloc",    &wraptype, Wrap_noalloc },
-		{ "dupinit",    &dupinit,  1 },
 		{ "alloc",      &wraptype, Wrap_alloc },
 		{ "adjptr",     &wraptype, Wrap_adjptr },
 		{ "scramble",	&wraptype, Wrap_scramble },
@@ -212,167 +281,285 @@
 			if( oi->name )
 				*oi->var = oi->val;
 			else
-				fprintf( stderr, "Unknown $%s option '%.*s'\n",
+				fprintf( stderr,
+					"== thr_debug: Unknown $%s option '%.*s' ==\n",
 					"LDAP_THREAD_DEBUG", (int) optlen, s );
 			s += optlen;
 		}
 	}
 	if( nodebug ) {
-		noabort = noerror = 1;
-		tracethreads = dupinit = 0;
+		tracethreads = 0;
+		nosync = noerror = 1;
+	}
+	if( nosync )
 		count = Count_no;
-	}
+	if( noerror )
+		noabort = 1;
+#if LDAP_THREAD_DEBUG_THREAD_ID +0
+	if( nosync )
+		threadID = 0;
+#endif
 #ifdef LDAP_THREAD_DEBUG_WRAP
-	if( nodebug || dupinit ) {
-		wraptype = Wrap_noalloc;
-	} else if( wraptype == Wrap_scramble ) {
-		const unsigned char *dummy = (const unsigned char *)&option_info;
-		if( sizeof(LDAP_UINTPTR_T) < sizeof(void *)
-			|| (unsigned char *)~~(LDAP_UINTPTR_T) dummy != dummy
-			|| (unsigned char *)~~(LDAP_UINTPTR_T) (unsigned char *)0 )
+	if( noerror )
+		nomem = 1;
+	if( !nomem ) {
+		static const ldap_debug_usage_info_t usage;
+		if( sizeof(LDAP_UINTPTR_T) < sizeof(unsigned char *)
+			|| sizeof(LDAP_UINTPTR_T) < sizeof(ldap_debug_usage_info_t *)
+			|| UNSCRAMBLE_usagep( SCRAMBLE( &usage ) ) != &usage
+			|| UNSCRAMBLE_dummyp( SCRAMBLE( (unsigned char *) 0 ) ) )
 		{
-			fprintf( stderr, "Misconfigured for $%s %s.  Using %s.\n",
-				"LDAP_THREAD_DEBUG", "scramble", "adjptr" );
-			wraptype = Wrap_adjptr;
+			fputs( "== thr_debug: Memory checks unsupported, "
+				"adding nomem to $LDAP_THREAD_DEBUG ==\n", stderr );
+			nomem = 1;
 		}
 	}
+	if( nomem ) {
+		noreinit = 1;
+		wraptype = Wrap_noalloc;
+	}
 	unwrap_offset = -(wrap_offset = (wraptype == Wrap_adjptr));
 #endif
+	wrap_threads = (tracethreads || threadID || count);
 	options_done = 1;
 }
 
 
-static char *
-thread_name( char *buf, int bufsize, ldap_pvt_thread_t thread )
-{
-	int i;
-	--bufsize;
-	if( bufsize > 2*sizeof(thread) )
-		bufsize = 2*sizeof(thread);
-	for( i = 0; i < bufsize; i += 2 )
-		snprintf( buf+i, 3, "%02x", ((unsigned char *)&thread)[i/2] );
-	return buf;
-}
-
-static void
-exit_thread_message( ldap_pvt_thread_t thread )
-{
-	if( tracethreads ) {
-		char buf[40];
-		fprintf( stderr, "== Exiting thread %s ==\n",
-			thread_name( buf, sizeof(buf), thread ) );
-	}
-}
-
-
 #ifndef LDAP_THREAD_DEBUG_WRAP
 
 #define	WRAPPED(ptr)			(ptr)
-#define alloc_usage(ptr, msg)	((void) 0)
+#define	GET_OWNER(ptr)			0
+#define	SET_OWNER(ptr, thread)	((void) 0)
+#define	RESET_OWNER(ptr)		((void) 0)
+#define	ASSERT_OWNER(ptr, msg)	((void) 0)
+#define	ASSERT_NO_OWNER(ptr, msg) ((void) 0)
+
+#define init_usage(ptr, msg)	((void) 0)
 #define check_usage(ptr, msg)	((void) 0)
-#define free_usage(ptr, msg)	((void) 0)
+#define destroy_usage(ptr)		((void) 0)
 
-#define with_threads_lock(statement)	{ statement; }
-#define get_new_thread_info(msg)		NULL
-#define update_thread_info(ti, th, det)	{}
-#define remove_thread_info(ti, msg)		((void)0)
-#define get_thread_info(thread, msg)	NULL
-#define exiting_thread(msg)	exit_thread_message(ldap_pvt_thread_self())
-
 #else /* LDAP_THREAD_DEBUG_WRAP */
 
-#define	WRAPPED(ptr)			(&(ptr)->wrapped)
+/* Specialize this if the initializer is not appropriate. */
+/* The ASSERT_NO_OWNER() definition may also need an override. */
+#ifndef LDAP_DEBUG_THREAD_NONE
+#define	LDAP_DEBUG_THREAD_NONE { -1 } /* "no thread" ldap_int_thread_t value */
+#endif
 
-#define INITED_VALUE		0x12345678UL
-#define INITED_BYTE_VALUE	0xd5
+static const ldap_int_thread_t ldap_debug_thread_none = LDAP_DEBUG_THREAD_NONE;
 
-/* Valid programs will access uninitialized memory here if dupinit. */
-static int
-debug_already_initialized( const LDAP_UINTPTR_T *num )
+#define THREAD_MUTEX_OWNER(mutex) \
+	ldap_int_thread_equal( (mutex)->owner, ldap_int_thread_self() )
+
+void
+ldap_debug_thread_assert_mutex_owner(
+	const char *file,
+	int line,
+	const char *msg,
+	ldap_pvt_thread_mutex_t *mutex )
 {
-	/*
-	 * 'ret' keeps the Valgrind warning "Conditional jump or move
-	 * depends on uninitialised value(s)" _inside_ this function.
-	 */
-	volatile int ret = 0;
-	if( dupinit && *num == INITED_VALUE )
-		ret = 1;
-	return ret;
+	if( !(noerror || THREAD_MUTEX_OWNER( mutex )) ) {
+		errmsg( file, line, msg, "ASSERT_MUTEX_OWNER", 0 );
+		if( !noabort ) abort();
+	}
 }
 
+#define	WRAPPED(ptr)			(&(ptr)->wrapped)
+#define	GET_OWNER(ptr)			((ptr)->owner)
+#define	SET_OWNER(ptr, thread)	((ptr)->owner = (thread))
+#define	RESET_OWNER(ptr)		((ptr)->owner = ldap_debug_thread_none)
+#define	ASSERT_OWNER(ptr, msg)	ERROR_IF( !THREAD_MUTEX_OWNER( ptr ), msg )
+#ifndef	ASSERT_NO_OWNER
+#define	ASSERT_NO_OWNER(ptr, msg) ERROR_IF( \
+	!ldap_int_thread_equal( (ptr)->owner, ldap_debug_thread_none ), msg )
+#endif
+
+/* Try to provoke memory access error (for malloc debuggers) */
+#define PEEK(mem) {if (-*(volatile const unsigned char *)(mem)) debug_noop();}
+
+static void debug_noop( void );
+static int debug_already_initialized( const ldap_debug_usage_info_t *usage );
+
+/* Name used for clearer error message */
+#define IS_COPY_OR_MOVED(usage) ((usage)->self != SCRAMBLE( usage ))
+
+#define DUMMY_ADDR(usage) \
+	(wraptype == Wrap_scramble \
+	 ? UNSCRAMBLE_dummyp( (usage)->mem.num ) \
+	 : (usage)->mem.ptr + unwrap_offset)
+
+/* Mark resource as initialized */
 static void
-alloc_usage( ldap_debug_usage_info_t *usage, const char *msg )
+init_usage( ldap_debug_usage_info_t *usage, const char *msg )
 {
 	if( !options_done )
 		get_options();
-	if( wraptype == Wrap_noalloc ) {
-		ERROR_IF( debug_already_initialized( &usage->num ), msg );
-		usage->num = INITED_VALUE;
+	if( !nomem ) {
+		if( !noreinit ) {
+			MEMERROR_IF( debug_already_initialized( usage ), msg, {
+				/* Provoke malloc debuggers */
+				unsigned char *dummy = DUMMY_ADDR( usage );
+				PEEK( dummy );
+				free( dummy );
+				free( dummy );
+			} );
+		}
+		if( wraptype != Wrap_noalloc ) {
+			unsigned char *dummy = malloc( 1 );
+			assert( dummy != NULL );
+			if( wraptype == Wrap_scramble ) {
+				usage->mem.num = SCRAMBLE( dummy );
+				/* Verify that ptr<->integer casts work on this host */
+				assert( UNSCRAMBLE_dummyp( usage->mem.num ) == dummy );
+			} else {
+				usage->mem.ptr = dummy + wrap_offset;
+			}
+		}
 	} else {
-		unsigned char *dummy = malloc( 1 );
-		assert( dummy != NULL );
-		*dummy = INITED_BYTE_VALUE;
-		if( wraptype == Wrap_scramble ) {
-			usage->num = ~(LDAP_UINTPTR_T) dummy;
-			/* Check that ptr<->integer casts work on this host */
-			assert( (unsigned char *)~usage->num == dummy );
-		} else {
-			usage->ptr = dummy + wrap_offset;
-		}
+		/* Unused, but set for readability in debugger */
+		usage->mem.ptr = NULL;
 	}
+	usage->self = SCRAMBLE( usage );	/* If nomem, only for debugger */
+	usage->magic = ldap_debug_magic;
+	usage->state = ldap_debug_state_inited;
 }
 
+/* Check that resource is initialized and not copied/realloced */
 static void
-check_usage( ldap_debug_usage_info_t *usage, const char *msg )
+check_usage( const ldap_debug_usage_info_t *usage, const char *msg )
 {
-	if( wraptype == Wrap_noalloc ) {
-		ERROR_IF( usage->num != INITED_VALUE, msg );
-	} else if( wraptype == Wrap_scramble ) {
-		ERROR_IF( !usage->num, msg );
-		ERROR_IF( *(unsigned char *)~usage->num != INITED_BYTE_VALUE, msg );
-	} else {
-		ERROR_IF( !usage->ptr, msg );
-		ERROR_IF( usage->ptr[unwrap_offset] != INITED_BYTE_VALUE, msg );
+	enum { Is_destroyed = 1 };	/* Name used for clearer error message */
+
+	if( usage->magic != ldap_debug_magic ) {
+		ERROR( usage->magic, msg );
+		return;
 	}
+	switch( usage->state ) {
+	case ldap_debug_state_destroyed:
+		MEMERROR_IF( Is_destroyed, msg, {
+			PEEK( DUMMY_ADDR( usage ) );
+		} );
+		break;
+	default:
+		ERROR( usage->state, msg );
+		break;
+	case ldap_debug_state_inited:
+		if( !nomem ) {
+			MEMERROR_IF( IS_COPY_OR_MOVED( usage ), msg, {
+				PEEK( DUMMY_ADDR( usage ) );
+				PEEK( UNSCRAMBLE_usagep( usage->self ) );
+			} );
+		}
+		break;
+	}
 }
 
+/* Mark resource as destroyed. */
+/* Does not check for errors, call check_usage()/init_usage() first. */
 static void
-free_usage( ldap_debug_usage_info_t *usage, const char *msg )
+destroy_usage( ldap_debug_usage_info_t *usage )
 {
-	if( wraptype == Wrap_noalloc ) {
-		usage->num = ~(LDAP_UINTPTR_T)INITED_VALUE;
-	} else {
-		unsigned char *dummy = (wraptype == Wrap_scramble
-		                        ? (unsigned char *)~usage->num
-		                        : usage->ptr + unwrap_offset);
-		*(volatile unsigned char *)dummy = (unsigned char)-1;
-		free( dummy );
+	if( usage->state == ldap_debug_state_inited ) {
+		if( wraptype != Wrap_noalloc ) {
+			free( DUMMY_ADDR( usage ) );
+			/* Do not reset the DUMMY_ADDR, leave it for malloc debuggers
+			 * in case the resource is used after it is freed. */
+		}
+		usage->state = ldap_debug_state_destroyed;
 	}
 }
 
-#define with_threads_lock(statement) { \
-	if( !nodebug ) { \
-		int rc_wtl_ = ldap_int_thread_mutex_lock( &thread_info_mutex ); \
-		assert( rc_wtl_ == 0 ); \
+/* Define these after they are used, so they are hopefully not inlined */
+
+static void
+debug_noop( void )
+{
+}
+
+/*
+ * Valid programs access uninitialized memory here unless "noreinit".
+ *
+ * Returns true if the resource is initialized and not copied/realloced.
+ */
+static int
+debug_already_initialized( const ldap_debug_usage_info_t *usage )
+{
+	/*
+	 * 'ret' keeps the Valgrind warning "Conditional jump or move
+	 * depends on uninitialised value(s)" _inside_ this function.
+	 */
+	volatile int ret = 0;
+	if( usage->state == ldap_debug_state_inited )
+		if( !IS_COPY_OR_MOVED( usage ) )
+	        if( usage->magic == ldap_debug_magic )
+				ret = 1;
+	return ret;
+}
+
+#endif /* LDAP_THREAD_DEBUG_WRAP */
+
+
+#if !(LDAP_THREAD_DEBUG_THREAD_ID +0)
+
+typedef void ldap_debug_thread_t;
+#define init_thread_info()	{}
+#define with_thread_info_lock(statements) { statements; }
+#define thread_info_detached(t)	0
+#define add_thread_info(msg, thr, det)	((void) 0)
+#define remove_thread_info(tinfo, msg)	((void) 0)
+#define get_thread_info(thread, msg)	NULL
+
+#else /* LDAP_THREAD_DEBUG_THREAD_ID */
+
+/*
+ * Thread ID tracking.  Currently acieves little.
+ * Should be either expanded or deleted.
+ */
+
+/*
+ * Array of threads.  Used instead of making ldap_pvt_thread_t a wrapper
+ * around ldap_int_thread_t, which would slow down ldap_pvt_thread_self().
+ */
+typedef struct {
+	ldap_pvt_thread_t           wrapped;
+	ldap_debug_usage_info_t     usage;
+	int                         detached;
+	int                         idx;
+} ldap_debug_thread_t;
+
+static ldap_debug_thread_t      **thread_info;
+static unsigned int             thread_info_size, thread_info_used;
+static ldap_int_thread_mutex_t  thread_info_mutex;
+
+#define init_thread_info() { \
+	if( threadID ) { \
+		int mutex_init_rc = ldap_int_thread_mutex_init( &thread_info_mutex ); \
+		assert( mutex_init_rc == 0 ); \
 	} \
-    statement; \
-	if( !nodebug ) { \
-		int rc_wtl_ = ldap_int_thread_mutex_unlock( &thread_info_mutex ); \
-		assert( rc_wtl_ == 0 ); \
-	} \
 }
 
-static ldap_debug_thread_t *
-get_new_thread_info( const char *msg )
+#define with_thread_info_lock(statements) { \
+	int rc_wtl_ = ldap_int_thread_mutex_lock( &thread_info_mutex ); \
+	assert( rc_wtl_ == 0 ); \
+	{ statements; } \
+	rc_wtl_ = ldap_int_thread_mutex_unlock( &thread_info_mutex ); \
+	assert( rc_wtl_ == 0 ); \
+}
+
+#define thread_info_detached(t) ((t)->detached)
+
+static void
+add_thread_info(
+	const char *msg,
+	const ldap_pvt_thread_t *thread,
+	int detached )
 {
-	if( nodebug )
-		return NULL;
+	ldap_debug_thread_t *t;
 	if( thread_info_used >= thread_info_size ) {
-		unsigned int more = thread_info_size + 1; /* debug value. increase. */
+		unsigned int more = thread_info_size + 8;
 		unsigned int new_size = thread_info_size + more;
-		ldap_debug_thread_t *t = calloc( more, sizeof(ldap_debug_thread_t) );
+		t = calloc( more, sizeof(ldap_debug_thread_t) );
 		assert( t != NULL );
-		t->freeme = 1;
 		thread_info = realloc( thread_info, new_size * sizeof(*thread_info) );
 		assert( thread_info != NULL );
 		while( thread_info_size < new_size ) {
@@ -380,36 +567,26 @@
 			thread_info[thread_info_size++] = t++;
 		}
 	}
-	alloc_usage( &thread_info[thread_info_used]->usage, msg );
-	return thread_info[thread_info_used++];
+	t = thread_info[thread_info_used];
+	init_usage( &t->usage, msg );
+	t->wrapped = *thread;
+	t->detached = detached;
+	thread_info_used++;
 }
 
 static void
-update_thread_info(
-	ldap_debug_thread_t *t,
-	const ldap_pvt_thread_t *thread,
-	int detached )
-{
-	if( !nodebug ) {
-		t->wrapped = *thread;
-		t->detached = detached;
-	}
-}
-
-static void
 remove_thread_info( ldap_debug_thread_t *t, const char *msg )
 {
-	if( !nodebug ) {
 		ldap_debug_thread_t *last;
 		int idx;
-		free_usage( &t->usage, msg );
+		check_usage( &t->usage, msg );
+		destroy_usage( &t->usage );
 		idx = t->idx;
 		assert( thread_info[idx] == t );
 		last = thread_info[--thread_info_used];
 		assert( last->idx == thread_info_used );
 		(thread_info[idx]              = last)->idx = idx;
 		(thread_info[thread_info_used] = t   )->idx = thread_info_used;
-	}
 }
 
 static ldap_debug_thread_t *
@@ -417,8 +594,6 @@
 {
 	unsigned int i;
 	ldap_debug_thread_t *t;
-	if( nodebug )
-		return NULL;
 	for( i = 0; i < thread_info_used; i++ ) {
 		if( ldap_pvt_thread_equal( thread, thread_info[i]->wrapped ) )
 			break;
@@ -429,24 +604,23 @@
 	return t;
 }
 
-static void
-exiting_thread( const char *msg )
+#endif /* LDAP_THREAD_DEBUG_THREAD_ID */
+
+
+static char *
+thread_name( char *buf, int bufsize, ldap_pvt_thread_t thread )
 {
-	if( !nodebug ) {
-		ldap_pvt_thread_t thread;
-		thread = ldap_pvt_thread_self();
-		exit_thread_message( thread );
-		with_threads_lock({
-			ldap_debug_thread_t *t = get_thread_info( thread, msg );
-			if( t->detached )
-				remove_thread_info( t, msg );
-		});
-	}
+	int i;
+	--bufsize;
+	if( bufsize > 2*sizeof(thread) )
+		bufsize = 2*sizeof(thread);
+	for( i = 0; i < bufsize; i += 2 )
+		snprintf( buf+i, 3, "%02x", ((unsigned char *)&thread)[i/2] );
+	return buf;
 }
 
-#endif /* LDAP_THREAD_DEBUG_WRAP */
 
-
+/* Add <adjust> (+/-1) to resource count <which> unless "nocount". */
 static void
 adjust_count( int which, int adjust )
 {
@@ -462,7 +636,7 @@
 		assert( rc == 0 );
 		break;
 	case Count_reported:
-		fputs( "...more ldap_debug_thread activity after exit...\n", stderr );
+		fputs( "== thr_debug: More thread activity after exit ==\n", stderr );
 		count = Count_reported_more;
 		/* FALL THROUGH */
 	case Count_reported_more:
@@ -490,8 +664,7 @@
 		ERROR( rc, "ldap_debug_thread_initialize:threads" );
 		threading_enabled = 0;
 	} else {
-		rc2 = ldap_int_thread_mutex_init( &thread_info_mutex );
-		assert( rc2 == 0 );
+		init_thread_info();
 		if( count != Count_no ) {
 			for( i = rc2 = 0; i < Idx_max; i++ )
 				rc2 |= ldap_int_thread_mutex_init( &resource_mutexes[i] );
@@ -549,6 +722,52 @@
 	return 0;
 }
 
+static void
+thread_exiting( const char *how, const char *msg )
+{
+	ldap_pvt_thread_t thread;
+#if 0 /* Detached threads may exit after ldap_debug_thread_destroy(). */
+	ERROR_IF( !threading_enabled, msg );
+#endif
+	thread = ldap_pvt_thread_self();
+	if( tracethreads ) {
+		char buf[40];
+		fprintf( stderr, "== thr_debug: %s thread %s ==\n",
+			how, thread_name( buf, sizeof(buf), thread ) );
+	}
+	if( threadID ) {
+		with_thread_info_lock({
+			ldap_debug_thread_t *t = get_thread_info( thread, msg );
+			if( thread_info_detached( t ) )
+				remove_thread_info( t, msg );
+		});
+	}
+	adjust_count( Idx_unexited_thread, -1 );
+}
+
+void
+ldap_pvt_thread_exit( void *retval )
+{
+	thread_exiting( "Exiting", "ldap_pvt_thread_exit" );
+	ldap_int_thread_exit( retval );
+}
+
+typedef struct {
+	void *(*start_routine)( void * );
+	void *arg;
+} ldap_debug_thread_call_t;
+
+static void *
+ldap_debug_thread_wrapper( void *arg )
+{
+	void *ret;
+	ldap_debug_thread_call_t call = *(ldap_debug_thread_call_t *)arg;
+	free( arg );
+	ret = call.start_routine( call.arg );
+	thread_exiting( "Returning from", "ldap_debug_thread_wrapper" );
+	return ret;
+}
+
 int
 ldap_pvt_thread_create(
 	ldap_pvt_thread_t *thread,
@@ -557,26 +776,39 @@
 	void *arg )
 {
 	int rc;
-	ERROR_IF( !threading_enabled, "ldap_pvt_thread_create" );
 	if( !options_done )
 		get_options();
-	with_threads_lock({
-		ldap_debug_thread_t *t;
-		t = get_new_thread_info( "ldap_pvt_thread_create" );
+	ERROR_IF( !threading_enabled, "ldap_pvt_thread_create" );
+	if( wrap_threads ) {
+		ldap_debug_thread_call_t *call = malloc(
+			sizeof( ldap_debug_thread_call_t ) );
+		assert( call != NULL );
+		call->start_routine = start_routine;
+		call->arg = arg;
+		start_routine = ldap_debug_thread_wrapper;
+		arg = call;
+	}
+	if( threadID ) {
+		with_thread_info_lock({
+			rc = ldap_int_thread_create( thread, detach, start_routine, arg );
+			if( rc == 0 )
+				add_thread_info( "ldap_pvt_thread_create", thread, detach );
+		});
+	} else {
 		rc = ldap_int_thread_create( thread, detach, start_routine, arg );
-		if( rc ) {
-			ERROR( rc, "ldap_pvt_thread_create" );
-			remove_thread_info( t, "ldap_pvt_thread_init" );
-		} else {
-			update_thread_info( t, thread, detach );
-		}
-	});
-	if( rc == 0 ) {
+	}
+	if( rc ) {
+		ERROR( rc, "ldap_pvt_thread_create" );
+		if( wrap_threads )
+			free( arg );
+	} else {
 		if( tracethreads ) {
-			char buf[40];
-			fprintf( stderr, "== Created thread %s%s ==\n",
+			char buf[40], buf2[40];
+			fprintf( stderr,
+				"== thr_debug: Created thread %s%s from thread %s ==\n",
 				thread_name( buf, sizeof(buf), *thread ),
-				detach ? " (detached)" : "" );
+				detach ? " (detached)" : "",
+				thread_name( buf2, sizeof(buf2), ldap_pvt_thread_self() ) );
 		}
 		adjust_count( Idx_unexited_thread, +1 );
 		if( !detach )
@@ -585,36 +817,30 @@
 	return rc;
 }
 
-void
-ldap_pvt_thread_exit( void *retval )
-{
-#if 0 /* Detached threads may exit after ldap_debug_thread_destroy(). */
-	ERROR_IF( !threading_enabled, "ldap_pvt_thread_exit" );
-#endif
-	adjust_count( Idx_unexited_thread, -1 );
-	exiting_thread( "ldap_pvt_thread_exit" );
-	ldap_int_thread_exit( retval );
-}
-
 int
 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
 {
 	int rc;
-	ldap_debug_thread_t *t;
+	ldap_debug_thread_t *t = NULL;
 	ERROR_IF( !threading_enabled, "ldap_pvt_thread_join" );
 	if( tracethreads ) {
-		char buf[40];
-		fprintf( stderr, "== Joining thread %s ==\n",
-			thread_name( buf, sizeof(buf), thread ) );
+		char buf[40], buf2[40];
+		fprintf( stderr, "== thr_debug: Joining thread %s in thread %s ==\n",
+			thread_name( buf, sizeof(buf), thread ),
+			thread_name( buf2, sizeof(buf2), ldap_pvt_thread_self() ) );
 	}
-	with_threads_lock(
-		t = get_thread_info( thread, "ldap_pvt_thread_join" ) );
+	if( threadID )
+		with_thread_info_lock( {
+			t = get_thread_info( thread, "ldap_pvt_thread_join" );
+			ERROR_IF( thread_info_detached( t ), "ldap_pvt_thread_join" );
+		} );
 	rc = ldap_int_thread_join( thread, thread_return );
 	if( rc ) {
 		ERROR( rc, "ldap_pvt_thread_join" );
 	} else {
-		with_threads_lock(
-			remove_thread_info( t, "ldap_pvt_thread_join" ) );
+		if( threadID )
+			with_thread_info_lock(
+				remove_thread_info( t, "ldap_pvt_thread_join" ) );
 		adjust_count( Idx_unjoined_thread, -1 );
 	}
 	return rc;
@@ -626,9 +852,11 @@
 	int rc;
 	ERROR_IF( !threading_enabled, "ldap_pvt_thread_kill" );
 	if( tracethreads ) {
-		char buf[40];
-		fprintf( stderr, "== Killing thread %s (sig %i) ==\n",
-			thread_name( buf, sizeof(buf), thread ), signo );
+		char buf[40], buf2[40];
+		fprintf( stderr,
+			"== thr_debug: Killing thread %s (sig %i) from thread %s ==\n",
+			thread_name( buf, sizeof(buf), thread ), signo,
+			thread_name( buf2, sizeof(buf2), ldap_pvt_thread_self() ) );
 	}
 	rc = ldap_int_thread_kill( thread, signo );
 	ERROR_IF( rc, "ldap_pvt_thread_kill" );
@@ -658,11 +886,11 @@
 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
 {
 	int rc;
-	alloc_usage( &cond->usage, "ldap_pvt_thread_cond_init" );
+	init_usage( &cond->usage, "ldap_pvt_thread_cond_init" );
 	rc = ldap_int_thread_cond_init( WRAPPED( cond ) );
 	if( rc ) {
 		ERROR( rc, "ldap_pvt_thread_cond_init" );
-		free_usage( &cond->usage, "ldap_pvt_thread_cond_init" );
+		destroy_usage( &cond->usage );
 	} else {
 		adjust_count( Idx_cond, +1 );
 	}
@@ -678,7 +906,7 @@
 	if( rc ) {
 		ERROR( rc, "ldap_pvt_thread_cond_destroy" );
 	} else {
-		free_usage( &cond->usage, "ldap_pvt_thread_cond_destroy" );
+		destroy_usage( &cond->usage );
 		adjust_count( Idx_cond, -1 );
 	}
 	return rc;
@@ -710,10 +938,16 @@
 	ldap_pvt_thread_mutex_t *mutex )
 {
 	int rc;
+	ldap_int_thread_t owner;
 	check_usage( &cond->usage, "ldap_pvt_thread_cond_wait:cond" );
 	check_usage( &mutex->usage, "ldap_pvt_thread_cond_wait:mutex" );
 	adjust_count( Idx_locked_mutex, -1 );
+	owner = GET_OWNER( mutex );
+	ASSERT_OWNER( mutex, "ldap_pvt_thread_cond_wait" );
+	RESET_OWNER( mutex );
 	rc = ldap_int_thread_cond_wait( WRAPPED( cond ), WRAPPED( mutex ) );
+	ASSERT_NO_OWNER( mutex, "ldap_pvt_thread_cond_wait" );
+	SET_OWNER( mutex, rc ? owner : ldap_int_thread_self() );
 	adjust_count( Idx_locked_mutex, +1 );
 	ERROR_IF( rc, "ldap_pvt_thread_cond_wait" );
 	return rc;
@@ -723,12 +957,13 @@
 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
 {
 	int rc;
-	alloc_usage( &mutex->usage, "ldap_pvt_thread_mutex_init" );
+	init_usage( &mutex->usage, "ldap_pvt_thread_mutex_init" );
 	rc = ldap_int_thread_mutex_init( WRAPPED( mutex ) );
 	if( rc ) {
 		ERROR( rc, "ldap_pvt_thread_mutex_init" );
-		free_usage( &mutex->usage, "ldap_pvt_thread_mutex_init" );
+		destroy_usage( &mutex->usage );
 	} else {
+		RESET_OWNER( mutex );
 		adjust_count( Idx_mutex, +1 );
 	}
 	return rc;
@@ -739,11 +974,13 @@
 {
 	int rc;
 	check_usage( &mutex->usage, "ldap_pvt_thread_mutex_destroy" );
+	ASSERT_NO_OWNER( mutex, "ldap_pvt_thread_mutex_destroy" );
 	rc = ldap_int_thread_mutex_destroy( WRAPPED( mutex ) );
 	if( rc ) {
 		ERROR( rc, "ldap_pvt_thread_mutex_destroy" );
 	} else {
-		free_usage( &mutex->usage, "ldap_pvt_thread_mutex_destroy" );
+		destroy_usage( &mutex->usage );
+		RESET_OWNER( mutex );
 		adjust_count( Idx_mutex, -1 );
 	}
 	return rc;
@@ -758,6 +995,8 @@
 	if( rc ) {
 		ERROR_IF( rc, "ldap_pvt_thread_mutex_lock" );
 	} else {
+		ASSERT_NO_OWNER( mutex, "ldap_pvt_thread_mutex_lock" );
+		SET_OWNER( mutex, ldap_int_thread_self() );
 		adjust_count( Idx_locked_mutex, +1 );
 	}
 	return rc;
@@ -769,8 +1008,11 @@
 	int rc;
 	check_usage( &mutex->usage, "ldap_pvt_thread_mutex_trylock" );
 	rc = ldap_int_thread_mutex_trylock( WRAPPED( mutex ) );
-	if( rc == 0 )
+	if( rc == 0 ) {
+		ASSERT_NO_OWNER( mutex, "ldap_pvt_thread_mutex_trylock" );
+		SET_OWNER( mutex, ldap_int_thread_self() );
 		adjust_count( Idx_locked_mutex, +1 );
+	}
 	return rc;
 }
 
@@ -779,6 +1021,8 @@
 {
 	int rc;
 	check_usage( &mutex->usage, "ldap_pvt_thread_mutex_unlock" );
+	ASSERT_OWNER( mutex, "ldap_pvt_thread_mutex_unlock" );
+	RESET_OWNER( mutex ); /* Breaks if this thread did not own the mutex */
 	rc = ldap_int_thread_mutex_unlock( WRAPPED( mutex ) );
 	if( rc ) {
 		ERROR_IF( rc, "ldap_pvt_thread_mutex_unlock" );
@@ -795,11 +1039,11 @@
 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rwlock )
 {
 	int rc;
-	alloc_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_init" );
+	init_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_init" );
 	rc = ldap_int_thread_rdwr_init( WRAPPED( rwlock ) );
 	if( rc ) {
 		ERROR( rc, "ldap_pvt_thread_rdwr_init" );
-		free_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_init" );
+		destroy_usage( &rwlock->usage );
 	} else {
 		adjust_count( Idx_rdwr, +1 );
 	}
@@ -815,7 +1059,7 @@
 	if( rc ) {
 		ERROR( rc, "ldap_pvt_thread_rdwr_destroy" );
 	} else {
-		free_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_destroy" );
+		destroy_usage( &rwlock->usage );
 		adjust_count( Idx_rdwr, -1 );
 	}
 	return rc;
@@ -875,7 +1119,7 @@
 	return rc;
 }
 
-#ifdef LDAP_RDWR_DEBUG
+#if defined(LDAP_RDWR_DEBUG) && !defined(LDAP_THREAD_HAVE_RDWR)
 
 int
 ldap_pvt_thread_rdwr_readers( ldap_pvt_thread_rdwr_t *rwlock )
@@ -898,7 +1142,7 @@
 	return ldap_int_thread_rdwr_active( WRAPPED( rwlock ) );
 }
 
-#endif /* LDAP_RDWR_DEBUG */
+#endif /* LDAP_RDWR_DEBUG && !LDAP_THREAD_HAVE_RDWR */
 
 
 /* Some wrappers for LDAP_THREAD_POOL_IMPLEMENTATION: */
@@ -911,6 +1155,8 @@
 	int max_pending )
 {
 	int rc;
+	if( !options_done )
+		get_options();
 	ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_init" );
 	rc = ldap_int_thread_pool_init( tpool, max_threads, max_pending );
 	if( rc ) {

Modified: openldap/trunk/libraries/libldap_r/thr_lwp.c
===================================================================
--- openldap/trunk/libraries/libldap_r/thr_lwp.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/thr_lwp.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* thr_lwp.c - wrappers around SunOS LWP threads */
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_lwp.c,v 1.17.2.4 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_lwp.c,v 1.20.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/libldap_r/thr_nt.c
===================================================================
--- openldap/trunk/libraries/libldap_r/thr_nt.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/thr_nt.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* thr_nt.c - wrapper around NT threads */
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_nt.c,v 1.29.2.4 2007/01/02 21:43:50 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_nt.c,v 1.32.2.4 2007/11/07 20:58:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -18,6 +18,10 @@
 
 #if defined( HAVE_NT_THREADS )
 
+#define _WIN32_WINNT 0x0400
+#include <windows.h>
+#include <process.h>
+
 #include "ldap_pvt_thread.h" /* Get the thread interface */
 #define LDAP_THREAD_IMPLEMENTATION
 #include "ldap_thr_debug.h"	 /* May rename the symbols defined below */
@@ -194,4 +198,37 @@
 	return GetCurrentThreadId();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *keyp )
+{
+	DWORD key = TlsAlloc();
+	if ( key != TLS_OUT_OF_INDEXES ) {
+		*keyp = key;
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+	/* TlsFree returns 0 on failure */
+	return( TlsFree( key ) == 0 );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+	return ( TlsSetValue( key, data ) == 0 );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+	void *ptr = TlsGetValue( key );
+	*data = ptr;
+	return( ptr ? GetLastError() : 0 );
+}
+
 #endif

Modified: openldap/trunk/libraries/libldap_r/thr_posix.c
===================================================================
--- openldap/trunk/libraries/libldap_r/thr_posix.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/thr_posix.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* thr_posix.c - wrapper around posix and posixish thread implementations.  */
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_posix.c,v 1.37.2.7 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_posix.c,v 1.46.2.3 2007/11/07 20:58:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -55,6 +55,12 @@
 #  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT &mutex_attr
 #endif
 
+#if HAVE_PTHREADS < 7
+#define ERRVAL(val)	((val) < 0 ? errno : 0)
+#else
+#define ERRVAL(val)	(val)
+#endif
+
 int
 ldap_int_thread_initialize( void )
 {
@@ -84,7 +90,7 @@
 {
 #ifdef HAVE_PTHREAD_SETCONCURRENCY
 	return pthread_setconcurrency( n );
-#elif HAVE_THR_SETCONCURRENCY
+#elif defined(HAVE_THR_SETCONCURRENCY)
 	return thr_setconcurrency( n );
 #else
 	return 0;
@@ -98,7 +104,7 @@
 {
 #ifdef HAVE_PTHREAD_GETCONCURRENCY
 	return pthread_getconcurrency();
-#elif HAVE_THR_GETCONCURRENCY
+#elif defined(HAVE_THR_GETCONCURRENCY)
 	return thr_getconcurrency();
 #else
 	return 0;
@@ -157,6 +163,7 @@
 #else
 	rtn = pthread_create( thread, &attr, start_routine, arg );
 #endif
+
 #if HAVE_PTHREADS > 5
 	pthread_attr_destroy(&attr);
 #else
@@ -183,26 +190,18 @@
 {
 #if HAVE_PTHREADS < 7
 	void *dummy;
-
 	if (thread_return==NULL)
 	  thread_return=&dummy;
-
-	if ( pthread_join( thread, thread_return ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_join( thread, thread_return );
 #endif
+	return ERRVAL( pthread_join( thread, thread_return ) );
 }
 
 int 
 ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
 {
-#if ( HAVE_PTHREAD_KILL && HAVE_PTHREADS > 6 )
+#if defined(HAVE_PTHREAD_KILL) && HAVE_PTHREADS > 4
 	/* MacOS 10.1 is detected as v10 but has no pthread_kill() */
-	return pthread_kill( thread, signo );
-#elif ( HAVE_PTHREAD_KILL && HAVE_PTHREADS > 4 )
-	if ( pthread_kill( thread, signo ) < 0 ) return errno;
-	return 0;
+	return ERRVAL( pthread_kill( thread, signo ) );
 #else
 	/* pthread package with DCE */
 	if (kill( getpid(), signo )<0)
@@ -223,7 +222,8 @@
 	select( 0, NULL, NULL, NULL, &tv );
 #endif
 	return 0;
-#elif HAVE_THR_YIELD
+
+#elif defined(HAVE_THR_YIELD)
 	thr_yield();
 	return 0;
 
@@ -237,6 +237,7 @@
 #elif HAVE_PTHREADS == 6
 	pthread_yield(NULL);
 	return 0;
+
 #else
 	pthread_yield();
 	return 0;
@@ -246,114 +247,64 @@
 int 
 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT ) < 0 )
-		return errno;
-	return 0;
-#else
-	return pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT );
-#endif
+	return ERRVAL( pthread_cond_init(
+		cond, LDAP_INT_THREAD_CONDATTR_DEFAULT ) );
 }
 
 int 
 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_cond_destroy( cond ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_cond_destroy( cond );
-#endif
+	return ERRVAL( pthread_cond_destroy( cond ) );
 }
 	
 int 
 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_cond_signal( cond ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_cond_signal( cond );
-#endif
+	return ERRVAL( pthread_cond_signal( cond ) );
 }
 
 int
 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_cond_broadcast( cond ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_cond_broadcast( cond );
-#endif
+	return ERRVAL( pthread_cond_broadcast( cond ) );
 }
 
 int 
 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
 		      ldap_pvt_thread_mutex_t *mutex )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_cond_wait( cond, mutex ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_cond_wait( cond, mutex );
-#endif
+	return ERRVAL( pthread_cond_wait( cond, mutex ) );
 }
 
 int 
 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT )<0)
-		return errno;
-	return 0;
-#else
-	return pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT );
-#endif
+	return ERRVAL( pthread_mutex_init(
+		mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT ) );
 }
 
 int 
 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_mutex_destroy( mutex ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_mutex_destroy( mutex );
-#endif
+	return ERRVAL( pthread_mutex_destroy( mutex ) );
 }
 
 int 
 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_mutex_lock( mutex ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_mutex_lock( mutex );
-#endif
+	return ERRVAL( pthread_mutex_lock( mutex ) );
 }
 
 int 
 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_mutex_trylock( mutex ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_mutex_trylock( mutex );
-#endif
+	return ERRVAL( pthread_mutex_trylock( mutex ) );
 }
 
 int 
 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_mutex_unlock( mutex ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_mutex_unlock( mutex );
-#endif
+	return ERRVAL( pthread_mutex_unlock( mutex ) );
 }
 
 ldap_pvt_thread_t ldap_pvt_thread_self( void )
@@ -361,88 +312,73 @@
 	return pthread_self();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+	return pthread_key_create( key, NULL );
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+	return pthread_key_delete( key );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+	return pthread_setspecific( key, data );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+	*data = pthread_getspecific( key );
+	return 0;
+}
+
 #ifdef LDAP_THREAD_HAVE_RDWR
 #ifdef HAVE_PTHREAD_RWLOCK_DESTROY
 int 
 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_rwlock_init( rw, NULL ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_rwlock_init( rw, NULL );
-#endif
+	return ERRVAL( pthread_rwlock_init( rw, NULL ) );
 }
 
 int 
 ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_rwlock_destroy( rw ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_rwlock_destroy( rw );
-#endif
+	return ERRVAL( pthread_rwlock_destroy( rw ) );
 }
 
 int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_rwlock_rdlock( rw ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_rwlock_rdlock( rw );
-#endif
+	return ERRVAL( pthread_rwlock_rdlock( rw ) );
 }
 
 int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_rwlock_tryrdlock( rw ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_rwlock_tryrdlock( rw );
-#endif
+	return ERRVAL( pthread_rwlock_tryrdlock( rw ) );
 }
 
 int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_rwlock_unlock( rw );
-#endif
+	return ERRVAL( pthread_rwlock_unlock( rw ) );
 }
 
 int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_rwlock_wrlock( rw ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_rwlock_wrlock( rw );
-#endif
+	return ERRVAL( pthread_rwlock_wrlock( rw ) );
 }
 
 int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_rwlock_trywrlock( rw ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_rwlock_trywrlock( rw );
-#endif
+	return ERRVAL( pthread_rwlock_trywrlock( rw ) );
 }
 
 int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
 {
-#if HAVE_PTHREADS < 7
-	if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
-	return 0;
-#else
-	return pthread_rwlock_unlock( rw );
-#endif
+	return ERRVAL( pthread_rwlock_unlock( rw ) );
 }
 
 #endif /* HAVE_PTHREAD_RWLOCK_DESTROY */

Modified: openldap/trunk/libraries/libldap_r/thr_pth.c
===================================================================
--- openldap/trunk/libraries/libldap_r/thr_pth.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/thr_pth.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* thr_pth.c - wrappers around GNU Pth */
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_pth.c,v 1.12.2.5 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_pth.c,v 1.16.2.3 2007/11/07 20:58:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -159,6 +159,31 @@
 	return pth_self();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+	return pth_key_create( key, NULL );
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+	return pth_key_delete( key );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+	return pth_key_setdata( key, data );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+	*data = pth_key_getdata( key );
+	return 0;
+}
+
 #ifdef LDAP_THREAD_HAVE_RDWR
 int 
 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )

Modified: openldap/trunk/libraries/libldap_r/thr_stub.c
===================================================================
--- openldap/trunk/libraries/libldap_r/thr_stub.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/thr_stub.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* thr_stub.c - stubs for the threads */
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_stub.c,v 1.22.2.5 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_stub.c,v 1.27.2.4 2007/11/07 20:58:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -173,6 +173,14 @@
 }
 
 int
+ldap_pvt_thread_pool_query( ldap_pvt_thread_pool_t *tpool,
+	ldap_pvt_thread_pool_param_t param, void *value )
+{
+	*(int *)value = -1;
+	return(-1);
+}
+
+int
 ldap_pvt_thread_pool_backload (
 	ldap_pvt_thread_pool_t *pool )
 {
@@ -229,4 +237,35 @@
 	return(0);
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+	return(0);
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+	return(0);
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+	return(0);
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+	return(0);
+}
+
+ldap_pvt_thread_t
+ldap_pvt_thread_pool_tid( void *vctx )
+{
+
+	return(0);
+}
+
 #endif /* NO_THREADS */

Modified: openldap/trunk/libraries/libldap_r/thr_thr.c
===================================================================
--- openldap/trunk/libraries/libldap_r/thr_thr.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/thr_thr.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* thr_thr.c - wrappers around solaris threads */
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_thr.c,v 1.15.2.4 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/thr_thr.c,v 1.18.2.3 2007/11/07 20:58:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -159,4 +159,28 @@
 	return thr_self();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+	return thr_keycreate( key, NULL );
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+	return( 0 );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+	return thr_setspecific( key, data );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+	return thr_getspecific( key, data );
+}
+
 #endif /* HAVE_THR */

Modified: openldap/trunk/libraries/libldap_r/threads.c
===================================================================
--- openldap/trunk/libraries/libldap_r/threads.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/threads.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/threads.c,v 1.15.2.4 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/threads.c,v 1.18.2.3 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -38,6 +38,8 @@
 {
 	int rc;
 	static int init = 0;
+	ldap_pvt_thread_rmutex_t rm;
+	ldap_pvt_thread_t tid;
 
 	/* we only get one shot at this */
 	if( init++ ) return -1;
@@ -50,6 +52,15 @@
 	if( rc ) return rc;
 #endif
 
+	/* kludge to pull symbol definitions in */
+	ldap_pvt_thread_rmutex_init( &rm );
+	tid = ldap_pvt_thread_self();
+	ldap_pvt_thread_rmutex_lock( &rm, tid );
+	ldap_pvt_thread_rmutex_trylock( &rm, tid );
+	ldap_pvt_thread_rmutex_unlock( &rm, tid );
+	ldap_pvt_thread_rmutex_unlock( &rm, tid );
+	ldap_pvt_thread_rmutex_destroy( &rm );
+
 	return 0;
 }
 

Modified: openldap/trunk/libraries/libldap_r/tpool.c
===================================================================
--- openldap/trunk/libraries/libldap_r/tpool.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/libldap_r/tpool.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/libldap_r/tpool.c,v 1.30.2.19 2007/04/01 09:53:06 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/libldap_r/tpool.c,v 1.52.2.8 2007/11/07 20:58:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -34,57 +34,90 @@
 typedef enum ldap_int_thread_pool_state_e {
 	LDAP_INT_THREAD_POOL_RUNNING,
 	LDAP_INT_THREAD_POOL_FINISHING,
-	LDAP_INT_THREAD_POOL_STOPPING,
-	LDAP_INT_THREAD_POOL_PAUSING
+	LDAP_INT_THREAD_POOL_STOPPING
 } ldap_int_thread_pool_state_t;
 
-typedef struct ldap_int_thread_key_s {
+/* Thread-specific key with data and optional free function */
+typedef struct ldap_int_tpool_key_s {
 	void *ltk_key;
 	void *ltk_data;
 	ldap_pvt_thread_pool_keyfree_t *ltk_free;
-} ldap_int_thread_key_t;
+} ldap_int_tpool_key_t;
 
 /* Max number of thread-specific keys we store per thread.
  * We don't expect to use many...
  */
 #define	MAXKEYS	32
+
+/* Max number of threads */
 #define	LDAP_MAXTHR	1024	/* must be a power of 2 */
 
-static ldap_pvt_thread_t tid_zero;
+/* Context: thread ID and thread-specific key/data pairs */
+typedef struct ldap_int_thread_userctx_s {
+	ldap_pvt_thread_t ltu_id;
+	ldap_int_tpool_key_t ltu_key[MAXKEYS];
+} ldap_int_thread_userctx_t;
 
+
+/* Simple {thread ID -> context} hash table; key=ctx->ltu_id.
+ * Protected by ldap_pvt_thread_pool_mutex except during pauses,
+ * when it is read-only (used by pool_purgekey and pool_context).
+ * Protected by tpool->ltp_mutex during pauses.
+ */
 static struct {
-	ldap_pvt_thread_t id;
-	ldap_int_thread_key_t *ctx;
+	ldap_int_thread_userctx_t *ctx;
+	/* ctx is valid when not NULL or DELETED_THREAD_CTX */
+#	define DELETED_THREAD_CTX (&ldap_int_main_thrctx + 1) /* dummy addr */
 } thread_keys[LDAP_MAXTHR];
-	
 
-typedef struct ldap_int_thread_ctx_s {
+#define	TID_HASH(tid, hash) do { \
+	unsigned const char *ptr_ = (unsigned const char *)&(tid); \
+	unsigned i_; \
+	for (i_ = 0, (hash) = ptr_[0]; ++i_ < sizeof(tid);) \
+		(hash) += ((hash) << 5) ^ ptr_[i_]; \
+} while(0)
+
+
+/* Task for a thread to perform */
+typedef struct ldap_int_thread_task_s {
 	union {
-	LDAP_STAILQ_ENTRY(ldap_int_thread_ctx_s) q;
-	LDAP_SLIST_ENTRY(ldap_int_thread_ctx_s) l;
-	LDAP_SLIST_ENTRY(ldap_int_thread_ctx_s) al;
-	} ltc_next;
-	ldap_pvt_thread_start_t *ltc_start_routine;
-	void *ltc_arg;
-} ldap_int_thread_ctx_t;
+		LDAP_STAILQ_ENTRY(ldap_int_thread_task_s) q;
+		LDAP_SLIST_ENTRY(ldap_int_thread_task_s) l;
+	} ltt_next;
+	ldap_pvt_thread_start_t *ltt_start_routine;
+	void *ltt_arg;
+} ldap_int_thread_task_t;
 
 struct ldap_int_thread_pool_s {
 	LDAP_STAILQ_ENTRY(ldap_int_thread_pool_s) ltp_next;
+
+	/* protect members below, and protect thread_keys[] during pauses */
 	ldap_pvt_thread_mutex_t ltp_mutex;
+
+	/* not paused and something to do for pool_<wrapper/pause/destroy>() */
 	ldap_pvt_thread_cond_t ltp_cond;
+
+	/* ltp_active_count <= 1 && ltp_pause */
 	ldap_pvt_thread_cond_t ltp_pcond;
-	LDAP_STAILQ_HEAD(tcq, ldap_int_thread_ctx_s) ltp_pending_list;
-	LDAP_SLIST_HEAD(tcl, ldap_int_thread_ctx_s) ltp_free_list;
-	LDAP_SLIST_HEAD(tclq, ldap_int_thread_ctx_s) ltp_active_list;
+
+	/* pending tasks, and unused task objects */
+	LDAP_STAILQ_HEAD(tcq, ldap_int_thread_task_s) ltp_pending_list;
+	LDAP_SLIST_HEAD(tcl, ldap_int_thread_task_s) ltp_free_list;
+
 	ldap_int_thread_pool_state_t ltp_state;
-	long ltp_max_count;
-	long ltp_max_pending;
-	long ltp_pending_count;
-	long ltp_active_count;
-	long ltp_open_count;
-	long ltp_starting;
+
+	/* some active request needs to be the sole active request */
+	int ltp_pause;
+
+	long ltp_max_count;			/* max number of threads in pool, or 0 */
+	long ltp_max_pending;		/* max pending or paused requests, or 0 */
+	long ltp_pending_count;		/* pending or paused requests */
+	long ltp_active_count;		/* active, not paused requests */
+	long ltp_open_count;		/* number of threads */
+	long ltp_starting;			/* currenlty starting threads */
 };
 
+static int ldap_int_has_thread_pool = 0;
 static LDAP_STAILQ_HEAD(tpq, ldap_int_thread_pool_s)
 	ldap_int_thread_pool_list =
 	LDAP_STAILQ_HEAD_INITIALIZER(ldap_int_thread_pool_list);
@@ -93,15 +126,16 @@
 
 static void *ldap_int_thread_pool_wrapper( void *pool );
 
-static ldap_pvt_thread_t ldap_int_main_tid;
+static ldap_pvt_thread_key_t	ldap_tpool_key;
 
-static ldap_int_thread_key_t ldap_int_main_thrctx[LDAP_MAXTHR];
+/* Context of the main thread */
+static ldap_int_thread_userctx_t ldap_int_main_thrctx;
 
 int
 ldap_int_thread_pool_startup ( void )
 {
-	ldap_int_main_tid = ldap_pvt_thread_self();
-
+	ldap_int_main_thrctx.ltu_id = ldap_pvt_thread_self();
+	ldap_pvt_thread_key_create( &ldap_tpool_key );
 	return ldap_pvt_thread_mutex_init(&ldap_pvt_thread_pool_mutex);
 }
 
@@ -114,9 +148,12 @@
 		(ldap_pvt_thread_pool_destroy)(&pool, 0); /* ignore thr_debug macro */
 	}
 	ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex);
+	ldap_pvt_thread_key_destroy( ldap_tpool_key );
 	return(0);
 }
 
+
+/* Create a thread pool */
 int
 ldap_pvt_thread_pool_init (
 	ldap_pvt_thread_pool_t *tpool,
@@ -126,6 +163,14 @@
 	ldap_pvt_thread_pool_t pool;
 	int rc;
 
+	/* multiple pools are currently not supported (ITS#4943) */
+	assert(!ldap_int_has_thread_pool);
+
+	if (! (0 <= max_threads && max_threads <= LDAP_MAXTHR))
+		max_threads = 0;
+	if (max_pending < 0)
+		max_pending = 0;
+
 	*tpool = NULL;
 	pool = (ldap_pvt_thread_pool_t) LDAP_CALLOC(1,
 		sizeof(struct ldap_int_thread_pool_s));
@@ -141,12 +186,13 @@
 	rc = ldap_pvt_thread_cond_init(&pool->ltp_pcond);
 	if (rc != 0)
 		return(rc);
+
+	ldap_int_has_thread_pool = 1;
 	pool->ltp_state = LDAP_INT_THREAD_POOL_RUNNING;
 	pool->ltp_max_count = max_threads;
 	pool->ltp_max_pending = max_pending;
 	LDAP_STAILQ_INIT(&pool->ltp_pending_list);
 	LDAP_SLIST_INIT(&pool->ltp_free_list);
-	LDAP_SLIST_INIT(&pool->ltp_active_list);
 	ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
 	LDAP_STAILQ_INSERT_TAIL(&ldap_int_thread_pool_list, pool, ltp_next);
 	ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
@@ -176,6 +222,7 @@
 		ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
 		LDAP_STAILQ_REMOVE(ldap_int_thread_pool_list, pool, 
 			ldap_int_thread_pool_s, ltp_next);
+		ldap_int_has_thread_pool = 0;
 		ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
 		ldap_pvt_thread_cond_destroy(&pool->ltp_pcond);
 		ldap_pvt_thread_cond_destroy(&pool->ltp_cond);
@@ -189,18 +236,15 @@
 	return(0);
 }
 
-#define	TID_HASH(tid, hash) do { unsigned i; \
-	unsigned char *ptr = (unsigned char *)&(tid); \
-	for (i=0, hash=0; i<sizeof(tid); i++) hash += ptr[i]; } while(0)
 
+/* Submit a task to be performed by the thread pool */
 int
 ldap_pvt_thread_pool_submit (
 	ldap_pvt_thread_pool_t *tpool,
 	ldap_pvt_thread_start_t *start_routine, void *arg )
 {
 	struct ldap_int_thread_pool_s *pool;
-	ldap_int_thread_ctx_t *ctx;
-	int need_thread = 0;
+	ldap_int_thread_task_t *task;
 	ldap_pvt_thread_t thr;
 
 	if (tpool == NULL)
@@ -212,108 +256,95 @@
 		return(-1);
 
 	ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
-	if ((pool->ltp_state != LDAP_INT_THREAD_POOL_RUNNING &&
-		pool->ltp_state != LDAP_INT_THREAD_POOL_PAUSING)
-		|| (pool->ltp_max_pending > 0
+	if (pool->ltp_state != LDAP_INT_THREAD_POOL_RUNNING
+		|| (pool->ltp_max_pending
 			&& pool->ltp_pending_count >= pool->ltp_max_pending))
 	{
 		ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 		return(-1);
 	}
-	ctx = LDAP_SLIST_FIRST(&pool->ltp_free_list);
-	if (ctx) {
-		LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltc_next.l);
+
+	task = LDAP_SLIST_FIRST(&pool->ltp_free_list);
+	if (task) {
+		LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltt_next.l);
 	} else {
-		ctx = (ldap_int_thread_ctx_t *) LDAP_MALLOC(
-			sizeof(ldap_int_thread_ctx_t));
-		if (ctx == NULL) {
+		task = (ldap_int_thread_task_t *) LDAP_MALLOC(sizeof(*task));
+		if (task == NULL) {
 			ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 			return(-1);
 		}
 	}
 
-	ctx->ltc_start_routine = start_routine;
-	ctx->ltc_arg = arg;
+	task->ltt_start_routine = start_routine;
+	task->ltt_arg = arg;
 
 	pool->ltp_pending_count++;
-	LDAP_STAILQ_INSERT_TAIL(&pool->ltp_pending_list, ctx, ltc_next.q);
-	if (pool->ltp_state == LDAP_INT_THREAD_POOL_PAUSING) {
+	LDAP_STAILQ_INSERT_TAIL(&pool->ltp_pending_list, task, ltt_next.q);
+	if (pool->ltp_pause) {
 		ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 		return(0);
 	}
 	ldap_pvt_thread_cond_signal(&pool->ltp_cond);
 	if (pool->ltp_open_count < pool->ltp_active_count + pool->ltp_pending_count
-		&& (pool->ltp_open_count < pool->ltp_max_count ||
-			pool->ltp_max_count <= 0 ))
+		&& (pool->ltp_open_count <
+			(pool->ltp_max_count ? pool->ltp_max_count : LDAP_MAXTHR)))
 	{
 		pool->ltp_open_count++;
 		pool->ltp_starting++;
-		need_thread = 1;
-	}
-	ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
-
-	if (need_thread) {
-		int rc;
-
-		ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
-
-		rc = ldap_pvt_thread_create( &thr, 1,
-			ldap_int_thread_pool_wrapper, pool );
-		if (rc == 0) {
-			int hash;
-			pool->ltp_starting--;
-
-			/* assign this thread ID to a key slot; start
-			 * at the thread ID itself (mod LDAP_MAXTHR) and
-			 * look for an empty slot.
-			 */
-			TID_HASH(thr, hash);
-			for (rc = hash & (LDAP_MAXTHR-1);
-				!ldap_pvt_thread_equal(thread_keys[rc].id, tid_zero);
-				rc = (rc+1) & (LDAP_MAXTHR-1));
-			thread_keys[rc].id = thr;
-		} else {
+		if (0 != ldap_pvt_thread_create(
+			&thr, 1, ldap_int_thread_pool_wrapper, pool))
+		{
 			/* couldn't create thread.  back out of
 			 * ltp_open_count and check for even worse things.
 			 */
+			pool->ltp_starting--;
 			pool->ltp_open_count--;
-			pool->ltp_starting--;
 			if (pool->ltp_open_count == 0) {
 				/* no open threads at all?!?
 				 */
-				ldap_int_thread_ctx_t *ptr;
-				LDAP_STAILQ_FOREACH(ptr, &pool->ltp_pending_list, ltc_next.q)
-					if (ptr == ctx) break;
-				if (ptr == ctx) {
-					/* no open threads, context not handled, so
-					 * back out of ltp_pending_count, free the context,
+				ldap_int_thread_task_t *ptr;
+
+				/* let pool_destroy know there are no more threads */
+				ldap_pvt_thread_cond_signal(&pool->ltp_cond);
+
+				LDAP_STAILQ_FOREACH(ptr, &pool->ltp_pending_list, ltt_next.q)
+					if (ptr == task) break;
+				if (ptr == task) {
+					/* no open threads, task not handled, so
+					 * back out of ltp_pending_count, free the task,
 					 * report the error.
 					 */
-					LDAP_STAILQ_REMOVE(&pool->ltp_pending_list, ctx, 
-						ldap_int_thread_ctx_s, ltc_next.q);
-					pool->ltp_pending_count++;
+					LDAP_STAILQ_REMOVE(&pool->ltp_pending_list, task,
+						ldap_int_thread_task_s, ltt_next.q);
+					pool->ltp_pending_count--;
 					ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
-					LDAP_FREE(ctx);
+					LDAP_FREE(task);
 					return(-1);
 				}
 			}
 			/* there is another open thread, so this
-			 * context will be handled eventually.
-			 * continue on and signal that the context
-			 * is waiting.
+			 * task will be handled eventually.
+			 * continue on, we have signalled that
+			 * the task is waiting.
 			 */
 		}
-		ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 	}
 
+	ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 	return(0);
 }
 
+/* Set max #threads.  value <= 0 means max supported #threads (LDAP_MAXTHR) */
 int
-ldap_pvt_thread_pool_maxthreads ( ldap_pvt_thread_pool_t *tpool, int max_threads )
+ldap_pvt_thread_pool_maxthreads(
+	ldap_pvt_thread_pool_t *tpool,
+	int max_threads )
 {
 	struct ldap_int_thread_pool_s *pool;
 
+	if (! (0 <= max_threads && max_threads <= LDAP_MAXTHR))
+		max_threads = 0;
+
 	if (tpool == NULL)
 		return(-1);
 
@@ -328,31 +359,133 @@
 	return(0);
 }
 
+/* Inspect the pool */
 int
-ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t *tpool )
+ldap_pvt_thread_pool_query(
+	ldap_pvt_thread_pool_t *tpool,
+	ldap_pvt_thread_pool_param_t param,
+	void *value )
 {
-	struct ldap_int_thread_pool_s *pool;
-	int count;
+	struct ldap_int_thread_pool_s	*pool;
+	int				count = -1;
 
-	if (tpool == NULL)
-		return(-1);
+	if ( tpool == NULL || value == NULL ) {
+		return -1;
+	}
 
 	pool = *tpool;
 
-	if (pool == NULL)
-		return(0);
+	if ( pool == NULL ) {
+		return 0;
+	}
 
 	ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
-	count = pool->ltp_pending_count + pool->ltp_active_count;
-	ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
-	return(count);
+	switch ( param ) {
+	case LDAP_PVT_THREAD_POOL_PARAM_MAX:
+		count = pool->ltp_max_count;
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_MAX_PENDING:
+		count = pool->ltp_max_pending;
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_OPEN:
+		count = pool->ltp_open_count;
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_STARTING:
+		count = pool->ltp_starting;
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_ACTIVE:
+		count = pool->ltp_active_count;
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_PAUSING:
+		count = pool->ltp_pause;
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_PENDING:
+		count = pool->ltp_pending_count;
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD:
+		count = pool->ltp_pending_count + pool->ltp_active_count;
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_ACTIVE_MAX:
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_PENDING_MAX:
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD_MAX:
+		break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_STATE: {
+		static struct {
+			char				*name;
+			ldap_int_thread_pool_state_t	state;
+		}		str2state[] = {
+			{ "running",	LDAP_INT_THREAD_POOL_RUNNING },
+			{ "finishing",	LDAP_INT_THREAD_POOL_FINISHING },
+			{ "stopping",	LDAP_INT_THREAD_POOL_STOPPING },
+			{ NULL }
+		};
+		int		i;
+
+		if ( pool->ltp_pause ) {
+			*((char **)value) = "pausing";
+		} else {
+			for ( i = 0; str2state[ i ].name != NULL; i++ ) {
+				if ( str2state[ i ].state == pool->ltp_state ) {
+					break;
+				}
+			}
+			*((char **)value) = str2state[ i ].name;
+		}
+		if ( *((char **)value) != NULL ) {
+			count = -2;
+		}
+		} break;
+
+	case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN:
+		break;
+	}
+	ldap_pvt_thread_mutex_unlock( &pool->ltp_mutex );
+
+	if ( count > -1 ) {
+		*((int *)value) = count;
+	}
+
+	return ( count == -1 ? -1 : 0 );
 }
 
+/*
+ * wrapper for ldap_pvt_thread_pool_query(), left around
+ * for backwards compatibility
+ */
 int
+ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t *tpool )
+{
+	int	rc, count;
+
+	rc = ldap_pvt_thread_pool_query( tpool,
+		LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD, (void *)&count );
+
+	if ( rc == 0 ) {
+		return count;
+	}
+
+	return rc;
+}
+
+/* Destroy the pool after making its threads finish */
+int
 ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending )
 {
 	struct ldap_int_thread_pool_s *pool, *pptr;
-	ldap_int_thread_ctx_t *ctx;
+	ldap_int_thread_task_t *task;
 
 	if (tpool == NULL)
 		return(-1);
@@ -376,69 +509,88 @@
 		? LDAP_INT_THREAD_POOL_FINISHING
 		: LDAP_INT_THREAD_POOL_STOPPING;
 
-	if ( pool->ltp_open_count ) {
-		ldap_pvt_thread_cond_broadcast(&pool->ltp_cond);
+	while (pool->ltp_open_count) {
+		if (!pool->ltp_pause)
+			ldap_pvt_thread_cond_broadcast(&pool->ltp_cond);
 		ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
 	}
 	ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 
-	while ((ctx = LDAP_STAILQ_FIRST(&pool->ltp_pending_list)) != NULL)
+	while ((task = LDAP_STAILQ_FIRST(&pool->ltp_pending_list)) != NULL)
 	{
-		LDAP_STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltc_next.q);
-		LDAP_FREE(ctx);
+		LDAP_STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltt_next.q);
+		LDAP_FREE(task);
 	}
 
-	while ((ctx = LDAP_SLIST_FIRST(&pool->ltp_free_list)) != NULL)
+	while ((task = LDAP_SLIST_FIRST(&pool->ltp_free_list)) != NULL)
 	{
-		LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltc_next.l);
-		LDAP_FREE(ctx);
+		LDAP_SLIST_REMOVE_HEAD(&pool->ltp_free_list, ltt_next.l);
+		LDAP_FREE(task);
 	}
 
 	ldap_pvt_thread_cond_destroy(&pool->ltp_pcond);
 	ldap_pvt_thread_cond_destroy(&pool->ltp_cond);
 	ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex);
 	LDAP_FREE(pool);
+	*tpool = NULL;
+	ldap_int_has_thread_pool = 0;
 	return(0);
 }
 
+/* Thread loop.  Accept and handle submitted tasks. */
 static void *
 ldap_int_thread_pool_wrapper ( 
 	void *xpool )
 {
 	struct ldap_int_thread_pool_s *pool = xpool;
-	ldap_int_thread_ctx_t *ctx;
-	ldap_int_thread_key_t ltc_key[MAXKEYS];
-	ldap_pvt_thread_t tid;
-	int i, keyslot, hash;
+	ldap_int_thread_task_t *task;
+	ldap_int_thread_userctx_t ctx, *kctx;
+	unsigned i, keyslot, hash;
 
-	if (pool == NULL)
-		return NULL;
+	assert(pool != NULL);
 
 	for ( i=0; i<MAXKEYS; i++ ) {
-		ltc_key[i].ltk_key = NULL;
+		ctx.ltu_key[i].ltk_key = NULL;
 	}
 
-	tid = ldap_pvt_thread_self();
+	ctx.ltu_id = ldap_pvt_thread_self();
+	TID_HASH(ctx.ltu_id, hash);
 
+	ldap_pvt_thread_key_setdata( ldap_tpool_key, &ctx );
+
 	ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
 
-	/* store pointer to our keys */
-	TID_HASH(tid, hash);
-	for (i = hash & (LDAP_MAXTHR-1);
-				!ldap_pvt_thread_equal(thread_keys[i].id, tid);
-				i = (i+1) & (LDAP_MAXTHR-1));
-	thread_keys[i].ctx = ltc_key;
-	keyslot = i;
+	/* thread_keys[] is read-only when paused */
+	while (pool->ltp_pause)
+		ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
 
-	while (pool->ltp_state != LDAP_INT_THREAD_POOL_STOPPING) {
-		ctx = LDAP_STAILQ_FIRST(&pool->ltp_pending_list);
-		if (ctx) {
-			LDAP_STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltc_next.q);
-		} else {
+	/* find a key slot to give this thread ID and store a
+	 * pointer to our keys there; start at the thread ID
+	 * itself (mod LDAP_MAXTHR) and look for an empty slot.
+	 */
+	ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
+	for (keyslot = hash & (LDAP_MAXTHR-1);
+		(kctx = thread_keys[keyslot].ctx) && kctx != DELETED_THREAD_CTX;
+		keyslot = (keyslot+1) & (LDAP_MAXTHR-1));
+	thread_keys[keyslot].ctx = &ctx;
+	ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
+
+	pool->ltp_starting--;
+
+	for (;;) {
+		while (pool->ltp_pause)
+			ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
+
+		if (pool->ltp_state == LDAP_INT_THREAD_POOL_STOPPING)
+			break;
+
+		task = LDAP_STAILQ_FIRST(&pool->ltp_pending_list);
+		if (task == NULL) {
 			if (pool->ltp_state == LDAP_INT_THREAD_POOL_FINISHING)
 				break;
-			if (pool->ltp_max_count > 0
-				&& pool->ltp_open_count > pool->ltp_max_count)
+
+			if (pool->ltp_open_count >
+				(pool->ltp_max_count ? pool->ltp_max_count : LDAP_MAXTHR))
 			{
 				/* too many threads running (can happen if the
 				 * maximum threads value is set during ongoing
@@ -454,50 +606,41 @@
 			 * always have at least one thread open).  the check
 			 * should be like this:
 			 *   if (pool->ltp_open_count > 1 && pool->ltp_starting == 0)
-			 *       check timer, leave thread (break;)
+			 *       check timer, wait if ltp_pause, leave thread (break;)
 			 *
 			 * Just use pthread_cond_timedwait if we want to
 			 * check idle time.
 			 */
 
-			if (pool->ltp_state == LDAP_INT_THREAD_POOL_RUNNING
-				|| pool->ltp_state == LDAP_INT_THREAD_POOL_PAUSING)
-			{
-				ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
-			}
-
+			assert(pool->ltp_state == LDAP_INT_THREAD_POOL_RUNNING);
+			ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
 			continue;
 		}
 
+		LDAP_STAILQ_REMOVE_HEAD(&pool->ltp_pending_list, ltt_next.q);
 		pool->ltp_pending_count--;
-
-		LDAP_SLIST_INSERT_HEAD(&pool->ltp_active_list, ctx, ltc_next.al);
 		pool->ltp_active_count++;
 		ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 
-		ctx->ltc_start_routine(ltc_key, ctx->ltc_arg);
+		task->ltt_start_routine(&ctx, task->ltt_arg);
 
 		ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
-		LDAP_SLIST_REMOVE(&pool->ltp_active_list, ctx,
-			ldap_int_thread_ctx_s, ltc_next.al);
-		LDAP_SLIST_INSERT_HEAD(&pool->ltp_free_list, ctx, ltc_next.l);
+		LDAP_SLIST_INSERT_HEAD(&pool->ltp_free_list, task, ltt_next.l);
 		pool->ltp_active_count--;
-
-		if (pool->ltp_state == LDAP_INT_THREAD_POOL_PAUSING) {
-			if (pool->ltp_active_count < 2) {
-				ldap_pvt_thread_cond_signal(&pool->ltp_pcond);
-			}
-			ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
-		}
+		/* let pool_pause know when it is the sole active thread */
+		if (pool->ltp_active_count < 2)
+			ldap_pvt_thread_cond_signal(&pool->ltp_pcond);
 	}
 
-	ldap_pvt_thread_pool_context_reset( ltc_key );
+	/* The ltp_mutex lock protects ctx->ltu_key from pool_purgekey()
+	 * during this call, since it prevents new pauses. */
+	ldap_pvt_thread_pool_context_reset(&ctx);
 
-	thread_keys[keyslot].ctx = NULL;
-	thread_keys[keyslot].id = tid_zero;
+	ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
+	thread_keys[keyslot].ctx = DELETED_THREAD_CTX;
+	ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
 
 	pool->ltp_open_count--;
-
 	/* let pool_destroy know we're all done */
 	if (pool->ltp_open_count < 1)
 		ldap_pvt_thread_cond_signal(&pool->ltp_cond);
@@ -508,6 +651,7 @@
 	return(NULL);
 }
 
+/* Pause the pool.  Return when all other threads are paused. */
 int
 ldap_pvt_thread_pool_pause ( 
 	ldap_pvt_thread_pool_t *tpool )
@@ -525,22 +669,30 @@
 	ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
 
 	/* If someone else has already requested a pause, we have to wait */
-	while (pool->ltp_state == LDAP_INT_THREAD_POOL_PAUSING) {
+	if (pool->ltp_pause) {
 		pool->ltp_pending_count++;
 		pool->ltp_active_count--;
-		ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
+		/* let the other pool_pause() know when it can proceed */
+		if (pool->ltp_active_count < 2)
+			ldap_pvt_thread_cond_signal(&pool->ltp_pcond);
+		do {
+			ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
+		} while (pool->ltp_pause);
 		pool->ltp_pending_count--;
 		pool->ltp_active_count++;
 	}
-	/* Wait for everyone else to finish */
-	pool->ltp_state = LDAP_INT_THREAD_POOL_PAUSING;
+
+	/* Wait for everyone else to pause or finish */
+	pool->ltp_pause = 1;
 	while (pool->ltp_active_count > 1) {
 		ldap_pvt_thread_cond_wait(&pool->ltp_pcond, &pool->ltp_mutex);
 	}
+
 	ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 	return(0);
 }
 
+/* End a pause */
 int
 ldap_pvt_thread_pool_resume ( 
 	ldap_pvt_thread_pool_t *tpool )
@@ -556,69 +708,85 @@
 		return(0);
 
 	ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
-
-	pool->ltp_state = LDAP_INT_THREAD_POOL_RUNNING;
-	ldap_pvt_thread_cond_broadcast(&pool->ltp_cond);
+	pool->ltp_pause = 0;
+	if (pool->ltp_state == LDAP_INT_THREAD_POOL_RUNNING)
+		ldap_pvt_thread_cond_broadcast(&pool->ltp_cond);
 	ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
 	return(0);
 }
 
+/*
+ * Get the key's data and optionally free function in the given context.
+ */
 int ldap_pvt_thread_pool_getkey(
 	void *xctx,
 	void *key,
 	void **data,
 	ldap_pvt_thread_pool_keyfree_t **kfree )
 {
-	ldap_int_thread_key_t *ctx = xctx;
+	ldap_int_thread_userctx_t *ctx = xctx;
 	int i;
 
-	if ( !ctx || !data ) return EINVAL;
+	if ( !ctx || !key || !data ) return EINVAL;
 
-	for ( i=0; i<MAXKEYS && ctx[i].ltk_key; i++ ) {
-		if ( ctx[i].ltk_key == key ) {
-			*data = ctx[i].ltk_data;
-			if ( kfree ) *kfree = ctx[i].ltk_free;
+	for ( i=0; i<MAXKEYS && ctx->ltu_key[i].ltk_key; i++ ) {
+		if ( ctx->ltu_key[i].ltk_key == key ) {
+			*data = ctx->ltu_key[i].ltk_data;
+			if ( kfree ) *kfree = ctx->ltu_key[i].ltk_free;
 			return 0;
 		}
 	}
 	return ENOENT;
 }
 
+static void
+clear_key_idx( ldap_int_thread_userctx_t *ctx, int i )
+{
+	for ( ; i < MAXKEYS-1 && ctx->ltu_key[i+1].ltk_key; i++ )
+		ctx->ltu_key[i] = ctx->ltu_key[i+1];
+	ctx->ltu_key[i].ltk_key = NULL;
+}
+
+/*
+ * Set or remove data for the key in the given context.
+ * key can be any unique pointer.
+ * kfree() is an optional function to free the data (but not the key):
+ *   pool_context_reset() and pool_purgekey() call kfree(key, data),
+ *   but pool_setkey() does not.  For pool_setkey() it is the caller's
+ *   responsibility to free any existing data with the same key.
+ *   kfree() must not call functions taking a tpool argument.
+ */
 int ldap_pvt_thread_pool_setkey(
 	void *xctx,
 	void *key,
 	void *data,
 	ldap_pvt_thread_pool_keyfree_t *kfree )
 {
-	ldap_int_thread_key_t *ctx = xctx;
-	int i;
+	ldap_int_thread_userctx_t *ctx = xctx;
+	int i, found;
 
 	if ( !ctx || !key ) return EINVAL;
 
-	for ( i=0; i<MAXKEYS; i++ ) {
-		if (( data && !ctx[i].ltk_key ) || ctx[i].ltk_key == key ) {
-			if ( data || kfree ) {
-				ctx[i].ltk_key = key;
-				ctx[i].ltk_data = data;
-				ctx[i].ltk_free = kfree;
-			} else {
-				int j;
-				for ( j=i+1; j<MAXKEYS; j++ )
-					if ( !ctx[j].ltk_key ) break;
-				j--;
-				if ( j != i ) {
-					ctx[i].ltk_key = ctx[j].ltk_key;
-					ctx[i].ltk_data = ctx[j].ltk_data;
-					ctx[i].ltk_free = ctx[j].ltk_free;
-				}
-				ctx[j].ltk_key = NULL;
-				ctx[j].ltk_data = NULL;
-				ctx[j].ltk_free = NULL;
-			}
-			return 0;
+	for ( i=found=0; i<MAXKEYS; i++ ) {
+		if ( ctx->ltu_key[i].ltk_key == key ) {
+			found = 1;
+			break;
+		} else if ( !ctx->ltu_key[i].ltk_key ) {
+			break;
 		}
 	}
-	return ENOMEM;
+
+	if ( data || kfree ) {
+		if ( i>=MAXKEYS )
+			return ENOMEM;
+		ctx->ltu_key[i].ltk_key = key;
+		ctx->ltu_key[i].ltk_data = data;
+		ctx->ltu_key[i].ltk_free = kfree;
+	} else if ( found ) {
+		clear_key_idx( ctx, i );
+	}
+
+	return 0;
 }
 
 /* Free all elements with this key, no matter which thread they're in.
@@ -627,17 +795,19 @@
 void ldap_pvt_thread_pool_purgekey( void *key )
 {
 	int i, j;
-	ldap_int_thread_key_t *ctx;
+	ldap_int_thread_userctx_t *ctx;
 
+	assert ( key != NULL );
+
 	for ( i=0; i<LDAP_MAXTHR; i++ ) {
-		if ( thread_keys[i].ctx ) {
-			ctx = thread_keys[i].ctx;
-			for ( j=0; j<MAXKEYS; j++ ) {
-				if ( ctx[j].ltk_key == key ) {
-					if (ctx[j].ltk_free)
-						ctx[j].ltk_free( ctx[j].ltk_key, ctx[j].ltk_data );
-					ctx[j].ltk_key = NULL;
-					ctx[j].ltk_free = NULL;
+		ctx = thread_keys[i].ctx;
+		if ( ctx && ctx != DELETED_THREAD_CTX ) {
+			for ( j=0; j<MAXKEYS && ctx->ltu_key[j].ltk_key; j++ ) {
+				if ( ctx->ltu_key[j].ltk_key == key ) {
+					if (ctx->ltu_key[j].ltk_free)
+						ctx->ltu_key[j].ltk_free( ctx->ltu_key[j].ltk_key,
+						ctx->ltu_key[j].ltk_data );
+					clear_key_idx( ctx, j );
 					break;
 				}
 			}
@@ -646,41 +816,45 @@
 }
 
 /*
+ * Find the context of the current thread.
  * This is necessary if the caller does not have access to the
  * thread context handle (for example, a slapd plugin calling
- * slapi_search_internal()). No doubt it is more efficient to
+ * slapi_search_internal()). No doubt it is more efficient
  * for the application to keep track of the thread context
  * handles itself.
  */
 void *ldap_pvt_thread_pool_context( )
 {
-	ldap_pvt_thread_t tid;
-	int i, hash;
+	void *ctx = NULL;
 
-	tid = ldap_pvt_thread_self();
-	if ( ldap_pvt_thread_equal( tid, ldap_int_main_tid ))
-		return ldap_int_main_thrctx;
-
-	TID_HASH( tid, hash );
-	for (i = hash & (LDAP_MAXTHR-1);
-		!ldap_pvt_thread_equal(thread_keys[i].id, tid_zero) &&
-		!ldap_pvt_thread_equal(thread_keys[i].id, tid);
-		i = (i+1) & (LDAP_MAXTHR-1));
-
-	return thread_keys[i].ctx;
+	ldap_pvt_thread_key_getdata( ldap_tpool_key, &ctx );
+	return ctx ? ctx : &ldap_int_main_thrctx;
 }
 
+/*
+ * Free the context's keys.
+ * Must not call functions taking a tpool argument (because this
+ * thread already holds ltp_mutex when called from pool_wrapper()).
+ */
 void ldap_pvt_thread_pool_context_reset( void *vctx )
 {
-	ldap_int_thread_key_t *ctx = vctx;
+	ldap_int_thread_userctx_t *ctx = vctx;
 	int i;
 
 	for ( i=MAXKEYS-1; i>=0; i--) {
-		if ( ctx[i].ltk_key == NULL )
+		if ( !ctx->ltu_key[i].ltk_key )
 			continue;
-		if ( ctx[i].ltk_free )
-			ctx[i].ltk_free( ctx[i].ltk_key, ctx[i].ltk_data );
-		ctx[i].ltk_key = NULL;
+		if ( ctx->ltu_key[i].ltk_free )
+			ctx->ltu_key[i].ltk_free( ctx->ltu_key[i].ltk_key,
+			ctx->ltu_key[i].ltk_data );
+		ctx->ltu_key[i].ltk_key = NULL;
 	}
 }
+
+ldap_pvt_thread_t ldap_pvt_thread_pool_tid( void *vctx )
+{
+	ldap_int_thread_userctx_t *ctx = vctx;
+
+	return ctx->ltu_id;
+}
 #endif /* LDAP_THREAD_HAVE_TPOOL */

Modified: openldap/trunk/libraries/liblunicode/Makefile.in
===================================================================
--- openldap/trunk/libraries/liblunicode/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for LDAP -llunicode
-# $OpenLDAP: pkg/ldap/libraries/liblunicode/Makefile.in,v 1.26.2.7 2007/01/02 21:43:51 kurt Exp $
+# $OpenLDAP: pkg/ldap/libraries/liblunicode/Makefile.in,v 1.31.2.4 2007/10/19 02:54:28 hyc Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -23,7 +23,7 @@
 OBJS	= ucdata.o ure.o urestubs.o ucstr.o
 
 XLIB = $(LIBRARY)
-XLIBS = $(LDAP_LIBLBER_LA) $(LDAP_LIBLUTIL_A)
+XLIBS = $(LDAP_LIBLUTIL_A) $(LDAP_LIBLBER_LA)
 #PROGRAMS = ucgendat
 
 LDAP_INCDIR= ../../include       

Modified: openldap/trunk/libraries/liblunicode/ucdata/ucdata.c
===================================================================
--- openldap/trunk/libraries/liblunicode/ucdata/ucdata.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/ucdata/ucdata.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucdata.c,v 1.30.2.4 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucdata.c,v 1.32.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -397,7 +397,7 @@
 _uccase_lookup(ac_uint4 code, long l, long r, int field)
 {
     long m;
-	ac_uint4 *tmp;
+	const ac_uint4 *tmp;
 
     /*
      * Do the binary search.

Modified: openldap/trunk/libraries/liblunicode/ucdata/ucdata.h
===================================================================
--- openldap/trunk/libraries/liblunicode/ucdata/ucdata.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/ucdata/ucdata.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucdata.h,v 1.17.2.3 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucdata.h,v 1.19.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/ucdata/ucgendat.c
===================================================================
--- openldap/trunk/libraries/liblunicode/ucdata/ucgendat.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/ucdata/ucgendat.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucgendat.c,v 1.36.2.4 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucgendat.c,v 1.39.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/ucdata/ucpgba.c
===================================================================
--- openldap/trunk/libraries/liblunicode/ucdata/ucpgba.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/ucdata/ucpgba.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucpgba.c,v 1.5.2.3 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucpgba.c,v 1.7.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/ucdata/ucpgba.h
===================================================================
--- openldap/trunk/libraries/liblunicode/ucdata/ucpgba.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/ucdata/ucpgba.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucpgba.h,v 1.6.2.3 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucpgba.h,v 1.8.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/ucstr.c
===================================================================
--- openldap/trunk/libraries/liblunicode/ucstr.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/ucstr.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucstr.c,v 1.34.2.4 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ucstr.c,v 1.37.2.2 2007/08/31 23:13:56 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/ure/ure.c
===================================================================
--- openldap/trunk/libraries/liblunicode/ure/ure.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/ure/ure.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ure/ure.c,v 1.15.2.3 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ure/ure.c,v 1.17.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/ure/ure.h
===================================================================
--- openldap/trunk/libraries/liblunicode/ure/ure.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/ure/ure.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ure/ure.h,v 1.11.2.3 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ure/ure.h,v 1.13.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/ure/urestubs.c
===================================================================
--- openldap/trunk/libraries/liblunicode/ure/urestubs.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/ure/urestubs.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ure/urestubs.c,v 1.12.2.3 2007/01/02 21:43:51 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/ure/urestubs.c,v 1.14.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/utbm/utbm.c
===================================================================
--- openldap/trunk/libraries/liblunicode/utbm/utbm.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/utbm/utbm.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/utbm/utbm.c,v 1.5.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/utbm/utbm.c,v 1.7.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/utbm/utbm.h
===================================================================
--- openldap/trunk/libraries/liblunicode/utbm/utbm.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/utbm/utbm.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/utbm/utbm.h,v 1.6.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/utbm/utbm.h,v 1.8.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblunicode/utbm/utbmstub.c
===================================================================
--- openldap/trunk/libraries/liblunicode/utbm/utbmstub.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblunicode/utbm/utbmstub.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblunicode/utbm/utbmstub.c,v 1.4.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblunicode/utbm/utbmstub.c,v 1.6.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/Makefile.in
===================================================================
--- openldap/trunk/libraries/liblutil/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile for -llutil
-# $OpenLDAP: pkg/ldap/libraries/liblutil/Makefile.in,v 1.33.2.5 2007/01/02 21:43:52 kurt Exp $
+# $OpenLDAP: pkg/ldap/libraries/liblutil/Makefile.in,v 1.38.2.2 2007/08/31 23:13:57 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ## 
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/avl.c
===================================================================
--- openldap/trunk/libraries/liblutil/avl.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/avl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* avl.c - routines to implement an avl tree */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/avl.c,v 1.3.2.5 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/avl.c,v 1.9.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/base64.c
===================================================================
--- openldap/trunk/libraries/liblutil/base64.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/base64.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* base64.c -- routines to encode/decode base64 data */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/base64.c,v 1.13.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/base64.c,v 1.15.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/csn.c
===================================================================
--- openldap/trunk/libraries/liblutil/csn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/csn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* csn.c - Change Sequence Number routines */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/csn.c,v 1.11.2.4 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/csn.c,v 1.14.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -35,8 +35,8 @@
  * where s is a counter of operations within a timeslice, r is
  * the replica id (normally zero), and c is a counter of
  * modifications within this operation.  s, r, and c are
- * represented in hex and zero padded to lengths of 6, 2, and
- * 6, respectively.
+ * represented in hex and zero padded to lengths of 6, 3, and
+ * 6, respectively. (In previous implementations r was only 2 digits.)
  *
  * Calls to this routine MUST be serialized with other calls
  * to gmtime().
@@ -48,36 +48,19 @@
 
 #include <lutil.h>
 
+/* Must be mutex-protected, because lutil_gettime needs mutex protection */
 size_t
 lutil_csnstr(char *buf, size_t len, unsigned int replica, unsigned int mod)
 {
-	static time_t csntime;
-	static unsigned int csnop;
-
-	time_t t;
-	unsigned int op;
-	struct tm *ltm;
-#ifdef HAVE_GMTIME_R
-	struct tm ltm_buf;
-#endif
+	struct lutil_tm tm;
 	int n;
 
-	time( &t );
-	if ( t > csntime ) {
-		csntime = t;
-		csnop = 0;
-	}
-	op = csnop++;
+	lutil_gettime( &tm );
 
-#ifdef HAVE_GMTIME_R
-	ltm = gmtime_r( &t, &ltm_buf );
-#else
-	ltm = gmtime( &t );
-#endif
 	n = snprintf( buf, len,
-		"%4d%02d%02d%02d%02d%02dZ#%06x#%02x#%06x",
-	    ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, ltm->tm_hour,
-	    ltm->tm_min, ltm->tm_sec, op, replica, mod );
+		"%4d%02d%02d%02d%02d%02d.%06dZ#%06x#%03x#%06x",
+	    tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
+	    tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_usub, replica, mod );
 
 	if( n < 0 ) return 0;
 	return ( (size_t) n < len ) ? n : 0;

Modified: openldap/trunk/libraries/liblutil/detach.c
===================================================================
--- openldap/trunk/libraries/liblutil/detach.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/detach.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* detach.c -- routines to daemonize a process */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/detach.c,v 1.16.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/detach.c,v 1.18.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -56,7 +56,7 @@
 
 #ifdef HAVE_SYSCONF
 	nbits = sysconf( _SC_OPEN_MAX );
-#elif HAVE_GETDTABLESIZE
+#elif defined(HAVE_GETDTABLESIZE)
 	nbits = getdtablesize();
 #else
 	nbits = FD_SETSIZE;
@@ -70,7 +70,7 @@
 
 	if ( debug == 0 ) {
 		for ( i = 0; i < 5; i++ ) {
-#if HAVE_THR
+#ifdef HAVE_THR
 			switch ( fork1() )
 #else
 			switch ( fork() )

Modified: openldap/trunk/libraries/liblutil/entropy.c
===================================================================
--- openldap/trunk/libraries/liblutil/entropy.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/entropy.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* entropy.c -- routines for providing pseudo-random data */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/entropy.c,v 1.27.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/entropy.c,v 1.29.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/fetch.c
===================================================================
--- openldap/trunk/libraries/liblutil/fetch.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/fetch.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* fetch.c - routines for fetching data at URLs */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/fetch.c,v 1.2.2.8 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/fetch.c,v 1.10.2.4 2007/12/02 01:54:33 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -43,32 +43,40 @@
 	LDAP_CONST char *urlstr )
 {
 	FILE *url;
-	char *p = NULL;
-#ifdef HAVE_FETCH
-	url = fetchGetURL( (char*) urlstr, "" );
 
-#else
 	if( strncasecmp( "file:", urlstr, sizeof("file:")-1 ) == 0 ) {
-		p = urlstr + sizeof("file:")-1;
+		char *p;
+		urlstr += sizeof("file:")-1;
 
 		/* we don't check for LDAP_DIRSEP since URLs should contain '/' */
-		if ( p[0] == '/' && p[1] == '/' ) {
-			p += 2;
+		if ( urlstr[0] == '/' && urlstr[1] == '/' ) {
+			urlstr += 2;
 			/* path must be absolute if authority is present */
-			if ( p[0] != '/' )
+			if ( urlstr[0] != '/' )
 				return NULL;
 		}
 
-		p = ber_strdup( p );
+		p = ber_strdup( urlstr );
+
+		/* But we should convert to LDAP_DIRSEP before use */
+		if ( LDAP_DIRSEP[0] != '/' ) {
+			char *s = p;
+			while (( s = strchr( s, '/' )))
+				*s++ = LDAP_DIRSEP[0];
+		}
+
 		ldap_pvt_hex_unescape( p );
 
 		url = fopen( p, "rb" );
 
 		ber_memfree( p );
 	} else {
-		return NULL;
+#ifdef HAVE_FETCH
+		url = fetchGetURL( (char*) urlstr, "" );
+#else
+		url = NULL;
+#endif
 	}
-#endif
 	return url;
 }
 

Modified: openldap/trunk/libraries/liblutil/getopt.c
===================================================================
--- openldap/trunk/libraries/liblutil/getopt.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/getopt.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* getopt.c -- replacement getopt(3) routines */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/getopt.c,v 1.14.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/getopt.c,v 1.16.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/getpass.c
===================================================================
--- openldap/trunk/libraries/liblutil/getpass.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/getpass.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* getpass.c -- get password from user */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/getpass.c,v 1.15.2.4 2007/09/22 23:09:11 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/getpass.c,v 1.17.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/getpeereid.c
===================================================================
--- openldap/trunk/libraries/liblutil/getpeereid.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/getpeereid.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* getpeereid.c */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/getpeereid.c,v 1.13.2.10 2007/06/10 18:39:53 hallvard Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/getpeereid.c,v 1.24.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -24,31 +24,43 @@
 #include <ac/socket.h>
 #include <ac/errno.h>
 
-#if HAVE_SYS_UCRED_H
-#if HAVE_GRP_H
-#include <grp.h>	/* for NGROUPS on Tru64 5.1 */
+#ifdef HAVE_GETPEERUCRED
+#include <ucred.h>
 #endif
-#include <sys/ucred.h>
-#endif
 
-/* Disabled due to ITS#4893, will revisit in release 2.4 */
-#if 0 /* !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && \
-	defined(HAVE_SENDMSG) && (defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTSLEN) || \
-		defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)) */
-#define DO_SENDMSG
+#ifdef LDAP_PF_LOCAL_SENDMSG
+#include <lber.h>
 #ifdef HAVE_SYS_UIO_H
 #include <sys/uio.h>
 #endif
 #include <sys/stat.h>
 #endif
 
+#ifdef HAVE_SYS_UCRED_H
+#ifdef HAVE_GRP_H
+#include <grp.h>	/* for NGROUPS on Tru64 5.1 */
+#endif
+#include <sys/ucred.h>
+#endif
+
 #include <stdlib.h>
 
-
-int getpeereid( int s, uid_t *euid, gid_t *egid )
+int lutil_getpeereid( int s, uid_t *euid, gid_t *egid
+#ifdef LDAP_PF_LOCAL_SENDMSG
+	, struct berval *peerbv
+#endif
+	)
 {
 #ifdef LDAP_PF_LOCAL
-#if defined( SO_PEERCRED )
+#if defined( HAVE_GETPEERUCRED )
+	ucred_t *uc = NULL;
+	if( getpeerucred( s, &uc ) == 0 )  {
+		*euid = ucred_geteuid( uc );
+		*egid = ucred_getegid( uc );
+		ucred_free( uc );
+	}
+
+#elif defined( SO_PEERCRED )
 	struct ucred peercred;
 	ber_socklen_t peercredlen = sizeof peercred;
 
@@ -73,9 +85,8 @@
 		*egid = peercred.cr_gid;
 		return 0;
 	}
-#elif defined( DO_SENDMSG )
-	char dummy[8];
-	int err, fd[2];
+#elif defined( LDAP_PF_LOCAL_SENDMSG ) && defined( MSG_WAITALL )
+	int err, fd;
 	struct iovec iov;
 	struct msghdr msg = {0};
 # ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
@@ -85,52 +96,68 @@
 # ifndef CMSG_LEN
 # define CMSG_LEN(len)		(_CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
 # endif
-	union {
+	struct {
 		struct cmsghdr cm;
-		unsigned char control[CMSG_SPACE(sizeof(int))];
-	} control_un;
+		int fd;
+	} control_st;
 	struct cmsghdr *cmsg;
 # endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
 	struct stat st;
+	struct sockaddr_un lname, rname;
+	ber_socklen_t llen, rlen;
 
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
+	rlen = sizeof(rname);
+	llen = sizeof(lname);
+	memset( &lname, 0, sizeof( lname ));
+	getsockname(s, (struct sockaddr *)&lname, &llen);
 
-	iov.iov_base = dummy;
-	iov.iov_len = sizeof dummy;
+	iov.iov_base = peerbv->bv_val;
+	iov.iov_len = peerbv->bv_len;
 	msg.msg_iov = &iov;
 	msg.msg_iovlen = 1;
+	peerbv->bv_len = 0;
+
 # ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
-	msg.msg_control = control_un.control;
-	msg.msg_controllen = sizeof( control_un.control );
+	msg.msg_control = &control_st;
+	msg.msg_controllen = sizeof( struct cmsghdr ) + sizeof( int );	/* no padding! */
 
 	cmsg = CMSG_FIRSTHDR( &msg );
+# else
+	msg.msg_accrights = (char *)&fd;
+	msg.msg_accrightslen = sizeof(fd);
+# endif
 
 	/*
 	 * AIX returns a bogus file descriptor if recvmsg() is
 	 * called with MSG_PEEK (is this a bug?). Hence we need
 	 * to receive the Abandon PDU.
 	 */
-	if( recvmsg( s, &msg, MSG_WAITALL ) >= 0 &&
+	err = recvmsg( s, &msg, MSG_WAITALL );
+	if( err >= 0 &&
+# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
 	    cmsg->cmsg_len == CMSG_LEN( sizeof(int) ) &&
 	    cmsg->cmsg_level == SOL_SOCKET &&
-	    cmsg->cmsg_type == SCM_RIGHTS )
+	    cmsg->cmsg_type == SCM_RIGHTS
 # else
-	msg.msg_accrights = (char *)fd;
-	msg.msg_accrightslen = sizeof(fd);
-	if( recvmsg( s, &msg, MSG_PEEK) >= 0 && msg.msg_accrightslen == sizeof(int) )
+		msg.msg_accrightslen == sizeof(int)
 # endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL*/
-	{
+	) {
+		int mode = S_IFIFO|S_ISUID|S_IRWXU;
+
 		/* We must receive a valid descriptor, it must be a pipe,
-		 * and it must only be accessible by its owner.
+		 * it must only be accessible by its owner, and it must
+		 * have the name of our socket written on it.
 		 */
+		peerbv->bv_len = err;
 # ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
-		fd[0] = (*(int *)CMSG_DATA( cmsg ));
+		fd = (*(int *)CMSG_DATA( cmsg ));
 # endif
-		err = fstat( fd[0], &st );
-		close(fd[0]);
-		if( err == 0 && S_ISFIFO(st.st_mode) &&
-			((st.st_mode & (S_IRWXG|S_IRWXO)) == 0))
+		err = fstat( fd, &st );
+		if ( err == 0 )
+			rlen = read(fd, &rname, rlen);
+		close(fd);
+		if( err == 0 && st.st_mode == mode &&
+			llen == rlen && !memcmp(&lname, &rname, llen))
 		{
 			*euid = st.st_uid;
 			*egid = st.st_gid;

Modified: openldap/trunk/libraries/liblutil/hash.c
===================================================================
--- openldap/trunk/libraries/liblutil/hash.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/hash.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/hash.c,v 1.6.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/hash.c,v 1.8.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/ldif.c
===================================================================
--- openldap/trunk/libraries/liblutil/ldif.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/ldif.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldif.c - routines for dealing with LDIF files */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/ldif.c,v 1.2.2.11 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/ldif.c,v 1.15.2.5 2007/09/03 21:53:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -778,6 +778,7 @@
 }
 
 #define	LDIF_MAXLINE	4096
+
 /*
  * ldif_read_record - read an ldif record.  Return 1 for success, 0 for EOF.
  */
@@ -864,6 +865,10 @@
 						fp2 = ldif_open_url( ptr );
 						if ( fp2 ) {
 							LDIFFP *lnew = ber_memalloc( sizeof( LDIFFP ));
+							if ( lnew == NULL ) {
+								fclose( fp2 );
+								return 0;
+							}
 							lnew->prev = lfp->prev;
 							lnew->fp = lfp->fp;
 							lfp->prev = lnew;
@@ -875,7 +880,9 @@
 							/* We failed to open the file, this should
 							 * be reported as an error somehow.
 							 */
-							break;
+							ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
+								_("ldif_read_record: include %s failed\n"), ptr );
+							return 0;
 						}
 					}
 				}

Modified: openldap/trunk/libraries/liblutil/lockf.c
===================================================================
--- openldap/trunk/libraries/liblutil/lockf.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/lockf.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/lockf.c,v 1.13.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/lockf.c,v 1.15.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -33,12 +33,12 @@
 
 #undef LOCK_API
 
-#if HAVE_LOCKF && defined(F_LOCK)
+#if defined(HAVE_LOCKF) && defined(F_LOCK)
 #	define USE_LOCKF 1
 #	define LOCK_API	"lockf"
 #endif
 
-#if !defined(LOCK_API) && HAVE_FCNTL
+#if !defined(LOCK_API) && defined(HAVE_FCNTL)
 #	ifdef HAVE_FCNTL_H
 #		include <fcntl.h>
 #	endif
@@ -48,8 +48,8 @@
 #	endif
 #endif
 
-#if !defined(LOCK_API) && HAVE_FLOCK
-#	if HAVE_SYS_FILE_H
+#if !defined(LOCK_API) && defined(HAVE_FLOCK)
+#	ifdef HAVE_SYS_FILE_H
 #		include <sys/file.h>
 #	endif
 #	define USE_FLOCK 1

Modified: openldap/trunk/libraries/liblutil/md5.c
===================================================================
--- openldap/trunk/libraries/liblutil/md5.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/md5.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* md5.c -- MD5 message-digest algorithm */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/md5.c,v 1.17.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/md5.c,v 1.19.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/memcmp.c
===================================================================
--- openldap/trunk/libraries/liblutil/memcmp.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/memcmp.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/memcmp.c,v 1.6.2.4 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/memcmp.c,v 1.9.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/ntservice.c
===================================================================
--- openldap/trunk/libraries/liblutil/ntservice.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/ntservice.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/ntservice.c,v 1.29.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/ntservice.c,v 1.31.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/passfile.c
===================================================================
--- openldap/trunk/libraries/liblutil/passfile.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/passfile.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/passfile.c,v 1.6.2.4 2007/06/08 07:59:05 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/passfile.c,v 1.8.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/passwd.c
===================================================================
--- openldap/trunk/libraries/liblutil/passwd.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/passwd.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/passwd.c,v 1.92.2.11 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/passwd.c,v 1.104.2.3 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/ptest.c
===================================================================
--- openldap/trunk/libraries/liblutil/ptest.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/ptest.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/ptest.c,v 1.10.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/ptest.c,v 1.12.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/sasl.c
===================================================================
--- openldap/trunk/libraries/liblutil/sasl.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/sasl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/sasl.c,v 1.20.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/sasl.c,v 1.22.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -49,6 +49,8 @@
 	void *defaults )
 {
 	lutilSASLdefaults *defs = defaults;
+
+	assert( defs != NULL );
 	
 	if (defs->mech) ber_memfree(defs->mech);
 	if (defs->realm) ber_memfree(defs->realm);

Modified: openldap/trunk/libraries/liblutil/setproctitle.c
===================================================================
--- openldap/trunk/libraries/liblutil/setproctitle.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/setproctitle.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/setproctitle.c,v 1.13.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/setproctitle.c,v 1.15.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/sha1.c
===================================================================
--- openldap/trunk/libraries/liblutil/sha1.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/sha1.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/sha1.c,v 1.24.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/sha1.c,v 1.26.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/signal.c
===================================================================
--- openldap/trunk/libraries/liblutil/signal.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/signal.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/signal.c,v 1.8.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/signal.c,v 1.10.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/sockpair.c
===================================================================
--- openldap/trunk/libraries/liblutil/sockpair.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/sockpair.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/sockpair.c,v 1.15.2.4 2007/06/10 18:39:53 hallvard Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/sockpair.c,v 1.17.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/liblutil/tavl.c
===================================================================
--- openldap/trunk/libraries/liblutil/tavl.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/tavl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* avl.c - routines to implement an avl tree */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/tavl.c,v 1.10.2.4 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/tavl.c,v 1.12.2.3 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2005-2007 The OpenLDAP Foundation.
@@ -284,6 +284,13 @@
 
 	ber_memfree( p );
 
+	/* Update child thread */
+	if ( q ) {
+		for ( ; q->avl_bits[nside] == AVL_CHILD && q->avl_link[nside];
+			q = q->avl_link[nside] ) ;
+		q->avl_link[nside] = r;
+	}
+	
 	if ( !depth ) {
 		*root = q;
 		return data;
@@ -295,12 +302,7 @@
 	side = pdir[depth];
 	p->avl_link[side] = q;
 
-	/* Update child thread */
-	if ( q ) {
-		for ( ; q->avl_bits[nside] == AVL_CHILD && q->avl_link[nside];
-			q = q->avl_link[nside] ) ;
-		q->avl_link[nside] = r;
-	} else {
+	if ( !q ) {
 		p->avl_bits[side] = AVL_THREAD;
 		p->avl_link[side] = r;
 	}
@@ -443,7 +445,27 @@
  * < 0 if arg1 is less than arg2 and > 0 if arg1 is greater than arg2.
  */
 
+/*
+ * tavl_find2 - returns Avlnode instead of data pointer.
+ * tavl_find3 - as above, but returns Avlnode even if no match is found.
+ *				also return the last comparison result in ret.
+ */
 Avlnode *
+tavl_find3( Avlnode *root, const void *data, AVL_CMP fcmp, int *ret )
+{
+	int	cmp, dir;
+	Avlnode *prev;
+
+	while ( root != 0 && (cmp = (*fcmp)( data, root->avl_data )) != 0 ) {
+		prev = root;
+		dir = cmp > 0;
+		root = avl_child( root, dir );
+	}
+	*ret = cmp;
+	return root ? root : prev;
+}
+
+Avlnode *
 tavl_find2( Avlnode *root, const void *data, AVL_CMP fcmp )
 {
 	int	cmp;

Modified: openldap/trunk/libraries/liblutil/testavl.c
===================================================================
--- openldap/trunk/libraries/liblutil/testavl.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/testavl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* testavl.c - Test Tim Howes AVL code */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/testavl.c,v 1.2.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/testavl.c,v 1.4.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Copied: openldap/trunk/libraries/liblutil/testtavl.c (from rev 891, openldap/vendor/openldap-2.4.7/libraries/liblutil/testtavl.c)
===================================================================
--- openldap/trunk/libraries/liblutil/testtavl.c	                        (rev 0)
+++ openldap/trunk/libraries/liblutil/testtavl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,158 @@
+/* testavl.c - Test Tim Howes AVL code */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/testtavl.c,v 1.2.2.2 2007/08/31 23:13:57 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* Portions Copyright (c) 1993 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of Michigan at Ann Arbor. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was originally developed by the University of Michigan
+ * (as part of U-MICH LDAP). Additional contributors include
+ *   Howard Chu
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+#include <ac/string.h>
+
+#define AVL_INTERNAL
+#include "avl.h"
+
+static void ravl_print LDAP_P(( Avlnode *root, int depth, int thread ));
+static void myprint LDAP_P(( Avlnode *root ));
+static int avl_strcmp LDAP_P(( const void *s, const void *t ));
+
+int
+main( int argc, char **argv )
+{
+	Avlnode	*tree = NULL, *n;
+	char	command[ 10 ];
+	char	name[ 80 ];
+	char	*p;
+
+	printf( "> " );
+	while ( fgets( command, sizeof( command ), stdin ) != NULL ) {
+		switch( *command ) {
+		case 'n':	/* new tree */
+			( void ) tavl_free( tree, free );
+			tree = NULL;
+			break;
+		case 'p':	/* print */
+			( void ) myprint( tree );
+			break;
+		case 't':	/* traverse with first, next */
+			printf( "***\n" );
+			for ( n = tavl_end( tree, TAVL_DIR_LEFT );
+			    n != NULL;
+				n = tavl_next( n, TAVL_DIR_RIGHT ))
+				printf( "%s\n", n->avl_data );
+			printf( "***\n" );
+			break;
+		case 'f':	/* find */
+			printf( "data? " );
+			if ( fgets( name, sizeof( name ), stdin ) == NULL )
+				exit( EXIT_SUCCESS );
+			name[ strlen( name ) - 1 ] = '\0';
+			if ( (p = (char *) tavl_find( tree, name, avl_strcmp ))
+			    == NULL )
+				printf( "Not found.\n\n" );
+			else
+				printf( "%s\n\n", p );
+			break;
+		case 'i':	/* insert */
+			printf( "data? " );
+			if ( fgets( name, sizeof( name ), stdin ) == NULL )
+				exit( EXIT_SUCCESS );
+			name[ strlen( name ) - 1 ] = '\0';
+			if ( tavl_insert( &tree, strdup( name ), avl_strcmp, 
+			    avl_dup_error ) != 0 )
+				printf( "\nNot inserted!\n" );
+			break;
+		case 'd':	/* delete */
+			printf( "data? " );
+			if ( fgets( name, sizeof( name ), stdin ) == NULL )
+				exit( EXIT_SUCCESS );
+			name[ strlen( name ) - 1 ] = '\0';
+			if ( tavl_delete( &tree, name, avl_strcmp ) == NULL )
+				printf( "\nNot found!\n" );
+			break;
+		case 'q':	/* quit */
+			exit( EXIT_SUCCESS );
+			break;
+		case '\n':
+			break;
+		default:
+			printf("Commands: insert, delete, print, new, quit\n");
+		}
+
+		printf( "> " );
+	}
+
+	return( 0 );
+}
+
+static const char bfc_array[] = "\\-/";
+static const char *bfcs = bfc_array+1;
+
+static void ravl_print( Avlnode *root, int depth, int thread )
+{
+	int	i;
+
+	if ( root && !thread )
+	ravl_print( root->avl_link[1], depth+1, root->avl_bits[1] == AVL_THREAD );
+
+	for ( i = 0; i < depth; i++ )
+		printf( "   " );
+	if ( thread )
+		printf( "~" );
+	else if ( root )
+		printf( "%c", bfcs[root->avl_bf] );
+	else
+		printf( " " );
+	if ( !root) {
+		printf( ".\n" );
+		return;
+	}
+	printf( "%s\n", (char *) root->avl_data );
+
+	if ( !thread )
+	ravl_print( root->avl_link[0], depth+1, root->avl_bits[0] == AVL_THREAD );
+}
+
+static void myprint( Avlnode *root )
+{
+	printf( "********\n" );
+
+	if ( root == 0 )
+		printf( "\tNULL\n" );
+	else
+		ravl_print( root, 0, 0 );
+
+	printf( "********\n" );
+}
+
+static int avl_strcmp( const void *s, const void *t )
+{
+	return strcmp( s, t );
+}

Modified: openldap/trunk/libraries/liblutil/utils.c
===================================================================
--- openldap/trunk/libraries/liblutil/utils.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/utils.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/utils.c,v 1.24.2.9 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/utils.c,v 1.33.2.15 2007/12/10 18:00:18 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -21,15 +21,21 @@
 #include <ac/ctype.h>
 #include <ac/unistd.h>
 #include <ac/time.h>
+#include <ac/errno.h>
 #ifdef HAVE_IO_H
 #include <io.h>
 #endif
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
 
-#include <lutil.h>
-#include <ldap_defaults.h>
+#include "lutil.h"
+#include "ldap_defaults.h"
+#include "ldap_pvt.h"
+#include "lber_pvt.h"
 
 #ifdef HAVE_EBCDIC
 int _trans_argv = 1;
@@ -268,6 +274,117 @@
 	return -1;
 }
 
+/* return a broken out time, with microseconds
+ * Must be mutex-protected.
+ */
+#ifdef _WIN32
+/* Windows SYSTEMTIME only has 10 millisecond resolution, so we
+ * also need to use a high resolution timer to get microseconds.
+ * This is pretty clunky.
+ */
+void
+lutil_gettime( struct lutil_tm *tm )
+{
+	static LARGE_INTEGER cFreq;
+	static LARGE_INTEGER prevCount;
+	static int subs;
+	static int offset;
+	LARGE_INTEGER count;
+	SYSTEMTIME st;
+
+	GetSystemTime( &st );
+	QueryPerformanceCounter( &count );
+
+	/* We assume Windows has at least a vague idea of
+	 * when a second begins. So we align our microsecond count
+	 * with the Windows millisecond count using this offset.
+	 * We retain the submillisecond portion of our own count.
+	 */
+	if ( !cFreq.QuadPart ) {
+		long long t;
+		int usec;
+		QueryPerformanceFrequency( &cFreq );
+
+		t = count.QuadPart * 1000000;
+		t /= cFreq.QuadPart;
+		usec = t % 10000000;
+		usec /= 1000;
+		offset = ( usec - st.wMilliseconds ) * 1000;
+	}
+
+	/* It shouldn't ever go backwards, but multiple CPUs might
+	 * be able to hit in the same tick.
+	 */
+	if ( count.QuadPart <= prevCount.QuadPart ) {
+		subs++;
+	} else {
+		subs = 0;
+		prevCount = count;
+	}
+
+	tm->tm_usub = subs;
+
+	/* convert to microseconds */
+	count.QuadPart *= 1000000;
+	count.QuadPart /= cFreq.QuadPart;
+	count.QuadPart -= offset;
+
+	tm->tm_usec = count.QuadPart % 1000000;
+
+	/* any difference larger than microseconds is
+	 * already reflected in st
+	 */
+
+	tm->tm_sec = st.wSecond;
+	tm->tm_min = st.wMinute;
+	tm->tm_hour = st.wHour;
+	tm->tm_mday = st.wDay;
+	tm->tm_mon = st.wMonth - 1;
+	tm->tm_year = st.wYear - 1900;
+}
+#else
+void
+lutil_gettime( struct lutil_tm *ltm )
+{
+	struct timeval tv;
+	static struct timeval prevTv;
+	static int subs;
+
+#ifdef HAVE_GMTIME_R
+	struct tm tm_buf;
+#endif
+	struct tm *tm;
+	time_t t;
+
+	gettimeofday( &tv, NULL );
+	t = tv.tv_sec;
+
+	if ( tv.tv_sec < prevTv.tv_sec
+		|| ( tv.tv_sec == prevTv.tv_sec && tv.tv_usec == prevTv.tv_usec )) {
+		subs++;
+	} else {
+		subs = 0;
+		prevTv = tv;
+	}
+
+	ltm->tm_usub = subs;
+
+#ifdef HAVE_GMTIME_R
+	tm = gmtime_r( &t, &tm_buf );
+#else
+	tm = gmtime( &t );
+#endif
+
+	ltm->tm_sec = tm->tm_sec;
+	ltm->tm_min = tm->tm_min;
+	ltm->tm_hour = tm->tm_hour;
+	ltm->tm_mday = tm->tm_mday;
+	ltm->tm_mon = tm->tm_mon;
+	ltm->tm_year = tm->tm_year;
+	ltm->tm_usec = tv.tv_usec;
+}
+#endif
+
 /* strcopy is like strcpy except it returns a pointer to the trailing NUL of
  * the result string. This allows fast construction of catenated strings
  * without the overhead of strlen/strcat.
@@ -314,6 +431,66 @@
 }
 #endif
 
+#ifdef _MSC_VER
+struct dirent {
+	char *d_name;
+};
+typedef struct DIR {
+	HANDLE dir;
+	struct dirent data;
+	int first;
+	char buf[MAX_PATH+1];
+} DIR;
+DIR *opendir( char *path )
+{
+	char tmp[32768];
+	int len = strlen(path);
+	DIR *d;
+	HANDLE h;
+	WIN32_FIND_DATA data;
+	
+	if (len+3 >= sizeof(tmp))
+		return NULL;
+
+	strcpy(tmp, path);
+	tmp[len++] = '\\';
+	tmp[len++] = '*';
+	tmp[len] = '\0';
+
+	h = FindFirstFile( tmp, &data );
+	
+	if ( h == INVALID_HANDLE_VALUE )
+		return NULL;
+
+	d = ber_memalloc( sizeof(DIR) );
+	if ( !d )
+		return NULL;
+	d->dir = h;
+	d->data.d_name = d->buf;
+	d->first = 1;
+	strcpy(d->data.d_name, data.cFileName);
+	return d;
+}
+struct dirent *readdir(DIR *dir)
+{
+	WIN32_FIND_DATA data;
+
+	if (dir->first) {
+		dir->first = 0;
+	} else {
+		if (!FindNextFile(dir->dir, &data))
+			return NULL;
+		strcpy(dir->data.d_name, data.cFileName);
+	}
+	return &dir->data;
+}
+void closedir(DIR *dir)
+{
+	FindClose(dir->dir);
+	ber_memfree(dir);
+}
+#endif
+
 /*
  * Memory Reverse Search
  */
@@ -427,8 +604,206 @@
 	return 0;
 }
 
+/* Multiply an integer by 100000000 and add new */
+typedef struct lutil_int_decnum {
+	unsigned char *buf;
+	int bufsiz;
+	int beg;
+	int len;
+} lutil_int_decnum;
+
+#define	FACTOR1	(100000000&0xffff)
+#define FACTOR2 (100000000>>16)
+
+static void
+scale( int new, lutil_int_decnum *prev, unsigned char *tmp )
+{
+	int i, j;
+	unsigned char *in = prev->buf+prev->beg;
+	unsigned int part;
+	unsigned char *out = tmp + prev->bufsiz - prev->len;
+
+	memset( tmp, 0, prev->bufsiz );
+	if ( prev->len ) {
+		for ( i = prev->len-1; i>=0; i-- ) {
+			part = in[i] * FACTOR1;
+			for ( j = i; part; j-- ) {
+				part += out[j];
+				out[j] = part & 0xff;
+				part >>= 8;
+			}
+			part = in[i] * FACTOR2;
+			for ( j = i-2; part; j-- ) {
+				part += out[j];
+				out[j] = part & 0xff;
+				part >>= 8;
+			}
+		}
+		j++;
+		prev->beg += j;
+		prev->len -= j;
+	}
+
+	out = tmp + prev->bufsiz;
+	i = 0;
+	do {
+		i--;
+		new += out[i];
+		out[i] = new & 0xff;
+		new >>= 8;
+	} while ( new );
+	i = -i;
+	if ( prev->len < i ) {
+		prev->beg = prev->bufsiz - i;
+		prev->len = i;
+	}
+	AC_MEMCPY( prev->buf+prev->beg, tmp+prev->beg, prev->len );
+}
+
+/* Convert unlimited length decimal or hex string to binary.
+ * Output buffer must be provided, bv_len must indicate buffer size
+ * Hex input can be "0x1234" or "'1234'H"
+ *
+ * Temporarily modifies the input string.
+ *
+ * Note: High bit of binary form is always the sign bit. If the number
+ * is supposed to be positive but has the high bit set, a zero byte
+ * is prepended. It is assumed that this has already been handled on
+ * any hex input.
+ */
+int
+lutil_str2bin( struct berval *in, struct berval *out, void *ctx )
+{
+	char *pin, *pout, ctmp;
+	char *end;
+	long l;
+	int i, chunk, len, rc = 0, hex = 0;
+	if ( !out || !out->bv_val || out->bv_len < in->bv_len )
+		return -1;
+
+	pout = out->bv_val;
+	/* Leading "0x" for hex input */
+	if ( in->bv_len > 2 && in->bv_val[0] == '0' &&
+		( in->bv_val[1] == 'x' || in->bv_val[1] == 'X' ) )
+	{
+		len = in->bv_len - 2;
+		pin = in->bv_val + 2;
+		hex = 1;
+	} else if ( in->bv_len > 3 && in->bv_val[0] == '\'' &&
+		in->bv_val[in->bv_len-2] == '\'' &&
+		in->bv_val[in->bv_len-1] == 'H' )
+	{
+		len = in->bv_len - 3;
+		pin = in->bv_val + 1;
+		hex = 1;
+	}
+	if ( hex ) {
+#define HEXMAX	(2 * sizeof(long))
+		/* Convert a longword at a time, but handle leading
+		 * odd bytes first
+		 */
+		chunk = len & (HEXMAX-1);
+		if ( !chunk )
+			chunk = HEXMAX;
+
+		while ( len ) {
+			ctmp = pin[chunk];
+			pin[chunk] = '\0';
+			errno = 0;
+			l = strtol( pin, &end, 16 );
+			pin[chunk] = ctmp;
+			if ( errno )
+				return -1;
+			chunk++;
+			chunk >>= 1;
+			for ( i = chunk; i>=0; i-- ) {
+				pout[i] = l & 0xff;
+				l >>= 8;
+			}
+			pin += chunk;
+			pout += sizeof(long);
+			len -= chunk;
+			chunk = HEXMAX;
+		}
+		out->bv_len = pout + len - out->bv_val;
+	} else {
+	/* Decimal */
+		char tmpbuf[64], *tmp;
+		lutil_int_decnum num;
+		int neg = 0;
+
+		len = in->bv_len;
+		pin = in->bv_val;
+		num.buf = (unsigned char *)out->bv_val;
+		num.bufsiz = out->bv_len;
+		num.beg = num.bufsiz-1;
+		num.len = 0;
+		if ( pin[0] == '-' ) {
+			neg = 0xff;
+			len--;
+			pin++;
+		}
+
+#define	DECMAX	8	/* 8 digits at a time */
+
+		/* tmp must be at least as large as outbuf */
+		if ( out->bv_len > sizeof(tmpbuf)) {
+			tmp = ber_memalloc_x( out->bv_len, ctx );
+		} else {
+			tmp = tmpbuf;
+		}
+		chunk = len & (DECMAX-1);
+		if ( !chunk )
+			chunk = DECMAX;
+
+		while ( len ) {
+			ctmp = pin[chunk];
+			pin[chunk] = '\0';
+			errno = 0;
+			l = strtol( pin, &end, 10 );
+			pin[chunk] = ctmp;
+			if ( errno ) {
+				rc = -1;
+				goto decfail;
+			}
+			scale( l, &num, (unsigned char *)tmp );
+			pin += chunk;
+			len -= chunk;
+			chunk = DECMAX;
+		}
+		/* Negate the result */
+		if ( neg ) {
+			unsigned char *ptr;
+
+			ptr = num.buf+num.beg;
+
+			/* flip all bits */
+			for ( i=0; i<num.len; i++ )
+				ptr[i] ^= 0xff;
+
+			/* add 1, with carry - overflow handled below */
+			while ( i-- && ! (ptr[i] = (ptr[i] + 1) & 0xff )) ;
+		}
+		/* Prepend sign byte if wrong sign bit */
+		if (( num.buf[num.beg] ^ neg ) & 0x80 ) {
+			num.beg--;
+			num.len++;
+			num.buf[num.beg] = neg;
+		}
+		if ( num.beg )
+			AC_MEMCPY( num.buf, num.buf+num.beg, num.len );
+		out->bv_len = num.len;
+decfail:
+		if ( tmp != tmpbuf ) {
+			ber_memfree_x( tmp, ctx );
+		}
+	}
+	return rc;
+}
+
 static	char		time_unit[] = "dhms";
 
+/* Used to parse and unparse time intervals, not timestamps */
 int
 lutil_parse_time(
 	const char	*in,
@@ -489,6 +864,7 @@
 {
 	int		len, i;
 	unsigned long	v[ 4 ];
+	char		*ptr = buf;
 
 	v[ 0 ] = t/86400;
 	v[ 1 ] = (t%86400)/3600;
@@ -496,13 +872,13 @@
 	v[ 3 ] = t%60;
 
 	for ( i = 0; i < 4; i++ ) {
-		if ( v[i] > 0 || i == 3 ) {
-			len = snprintf( buf, buflen, "%lu%c", v[ i ], time_unit[ i ] );
+		if ( v[i] > 0 || ( i == 3 && ptr == buf ) ) {
+			len = snprintf( ptr, buflen, "%lu%c", v[ i ], time_unit[ i ] );
 			if ( len < 0 || (unsigned)len >= buflen ) {
 				return -1;
 			}
 			buflen -= len;
-			buf += len;
+			ptr += len;
 		}
 	}
 

Modified: openldap/trunk/libraries/liblutil/uuid.c
===================================================================
--- openldap/trunk/libraries/liblutil/uuid.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/liblutil/uuid.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* uuid.c -- Universally Unique Identifier routines */
-/* $OpenLDAP: pkg/ldap/libraries/liblutil/uuid.c,v 1.25.2.5 2007/10/04 20:02:09 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/liblutil/uuid.c,v 1.28.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -41,6 +41,8 @@
 
 #ifdef HAVE_UUID_TO_STR
 #  include <sys/uuid.h>
+#elif defined( HAVE_UUID_GENERATE )
+#  include <uuid/uuid.h>
 #elif defined( _WIN32 )
 #  include <rpc.h>
 #else
@@ -56,7 +58,7 @@
 #include <lutil.h>
 
 /* not needed for Windows */
-#if !defined(HAVE_UUID_TO_STR) && !defined(_WIN32)
+#if !defined(HAVE_UUID_TO_STR) && !defined(HAVE_UUID_GENERATE) && !defined(_WIN32)
 static unsigned char *
 lutil_eaddr( void )
 {
@@ -251,7 +253,7 @@
 
 #endif /* ULONG_MAX >= 64 bits || HAVE_LONG_LONG */
 
-#endif /* !HAVE_UUID_TO_STR && !_WIN32 */
+#endif /* !HAVE_UUID_TO_STR && !HAVE_UUID_GENERATE && !_WIN32 */
 
 /*
 ** All we really care about is an ISO UUID string.  The format of a UUID is:
@@ -298,6 +300,13 @@
 
 	return l;
 
+#elif defined( HAVE_UUID_GENERATE )
+	uuid_t uu;
+
+	uuid_generate( uu );
+	uuid_unparse_lower( uu, buf );
+	return strlen( buf );
+	
 #elif defined( _WIN32 )
 	UUID uuid;
 	unsigned char *uuidstr;

Modified: openldap/trunk/libraries/librewrite/Makefile.in
===================================================================
--- openldap/trunk/libraries/librewrite/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # LIBREWRITE
-# $OpenLDAP: pkg/ldap/libraries/librewrite/Makefile.in,v 1.10.2.5 2007/01/02 21:43:52 kurt Exp $
+# $OpenLDAP: pkg/ldap/libraries/librewrite/Makefile.in,v 1.14.2.2 2007/08/31 23:13:57 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/config.c
===================================================================
--- openldap/trunk/libraries/librewrite/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/config.c,v 1.10.2.5 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/config.c,v 1.14.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -413,8 +413,8 @@
 	/*
 	 * Built-in ldap map
 	 */
-	if ( strcasecmp( argv[ MAP_TYPE ], "ldap" ) == 0 ) {
-		map->lb_type = REWRITE_BUILTIN_MAP_LDAP;
+	if (( map->lb_mapper = rewrite_mapper_find( argv[ MAP_TYPE ] ))) {
+		map->lb_type = REWRITE_BUILTIN_MAP;
 
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
 		if ( ldap_pvt_thread_mutex_init( & map->lb_mutex ) ) {
@@ -424,7 +424,7 @@
 		}
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
 		
-		map->lb_private = map_ldap_parse( info, fname, lineno,
+		map->lb_private = map->lb_mapper->rm_config( fname, lineno,
 				argc - 3, argv + 3 );
 		
 	/* 

Modified: openldap/trunk/libraries/librewrite/context.c
===================================================================
--- openldap/trunk/libraries/librewrite/context.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/context.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/context.c,v 1.11.2.4 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/context.c,v 1.15.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/info.c
===================================================================
--- openldap/trunk/libraries/librewrite/info.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/info.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/info.c,v 1.11.2.4 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/info.c,v 1.15.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/ldapmap.c
===================================================================
--- openldap/trunk/libraries/librewrite/ldapmap.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/ldapmap.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/ldapmap.c,v 1.9.2.5 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/ldapmap.c,v 1.12.2.3 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -23,23 +23,30 @@
 #include "rewrite-int.h"
 #include "rewrite-map.h"
 
+typedef enum {
+	MAP_LDAP_UNKNOWN,
+	MAP_LDAP_EVERYTIME,
+	MAP_LDAP_NOW,
+	MAP_LDAP_LATER
+} bindwhen_t;
+
 /*
  * LDAP map data structure
  */
 struct ldap_map_data {
 	char                           *lm_url;
 	LDAPURLDesc                    *lm_lud;
-	int                             lm_attrsonly;
+	int				lm_version;
 	char                           *lm_binddn;
-	char                           *lm_bindpw;
+	struct berval			lm_cred;
 
-#define MAP_LDAP_EVERYTIME		0x00
-#define MAP_LDAP_NOW			0x01
-#define MAP_LDAP_LATER			0x02
-	int                             lm_when;
+	bindwhen_t			lm_when;
 
 	LDAP                           *lm_ld;
 
+	int                             lm_wantdn;
+	char				*lm_attrs[ 2 ];
+
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
 	ldap_pvt_thread_mutex_t         lm_mutex;
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
@@ -64,20 +71,22 @@
 		free( data->lm_binddn );
 	}
 
-	if ( data->lm_bindpw != NULL ) {
-		free( data->lm_bindpw );
+	if ( data->lm_cred.bv_val != NULL ) {
+		memset( data->lm_cred.bv_val, 0, data->lm_cred.bv_len );
+		free( data->lm_cred.bv_val );
+		data->lm_cred.bv_val = NULL;
+		data->lm_cred.bv_len = 0;
 	}
 
 	if ( data->lm_when != MAP_LDAP_EVERYTIME && data->lm_ld != NULL ) {
-		ldap_unbind_s( data->lm_ld );
+		ldap_unbind_ext( data->lm_ld, NULL, NULL );
 	}
 
 	free( data );
 }
 
-void *
+static void *
 map_ldap_parse(
-		struct rewrite_info *info,
 		const char *fname,
 		int lineno,
 		int argc,
@@ -85,9 +94,8 @@
 )
 {
 	struct ldap_map_data *data;
-	char *p;
+	char *p, *uri;
 
-	assert( info != NULL );
 	assert( fname != NULL );
 	assert( argv != NULL );
 
@@ -104,13 +112,18 @@
 		return NULL;
 	}
 
-	data->lm_url = strdup( argv[ 0 ] );
+	uri = argv[ 0 ];
+	if ( strncasecmp( uri, "uri=", STRLENOF( "uri=" ) ) == 0 ) {
+		uri += STRLENOF( "uri=" );
+	}
+
+	data->lm_url = strdup( uri );
 	if ( data->lm_url == NULL ) {
 		map_ldap_free( data );
 		return NULL;
 	}
 	
-	if ( ldap_url_parse( argv[ 0 ], &data->lm_lud ) != REWRITE_SUCCESS ) {
+	if ( ldap_url_parse( uri, &data->lm_lud ) != REWRITE_SUCCESS ) {
 		Debug( LDAP_DEBUG_ANY,
 				"[%s:%d] illegal URI '%s'\n",
 				fname, lineno, argv[ 0 ] );
@@ -118,19 +131,48 @@
 		return NULL;
 	}
 
+	/* trim everything after [host][:port] */
 	p = strchr( data->lm_url, '/' );
 	assert( p[ 1 ] == '/' );
 	if ( ( p = strchr( p + 2, '/' ) ) != NULL ) {
 		p[ 0 ] = '\0';
 	}
 
-	if ( strcasecmp( data->lm_lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
-		data->lm_attrsonly = 1;
+	if ( data->lm_lud->lud_attrs == NULL ) {
+		data->lm_attrs[ 0 ] = LDAP_NO_ATTRS;
+		data->lm_wantdn = 1;
+
+	} else {
+		if ( data->lm_lud->lud_attrs[ 1 ] != NULL ) {
+			Debug( LDAP_DEBUG_ANY,
+				"[%s:%d] only one attribute allowed in URI\n",
+				fname, lineno, 0 );
+			map_ldap_free( data );
+			return NULL;
+		}
+
+		if ( strcasecmp( data->lm_lud->lud_attrs[ 0 ], "dn" ) == 0
+			|| strcasecmp( data->lm_lud->lud_attrs[ 0 ], "entryDN" ) == 0 )
+		{
+			ldap_memfree( data->lm_lud->lud_attrs[ 0 ] );
+			ldap_memfree( data->lm_lud->lud_attrs );
+			data->lm_lud->lud_attrs = NULL;
+			data->lm_attrs[ 0 ] = LDAP_NO_ATTRS;
+			data->lm_wantdn = 1;
+
+		} else {
+			data->lm_attrs[ 0 ] = data->lm_lud->lud_attrs[ 0 ];
+		}
 	}
-	      
+
+	data->lm_attrs[ 1 ] = NULL;
+
+	/* safe defaults */
+	data->lm_version = LDAP_VERSION3;
+
 	for ( argc--, argv++; argc > 0; argc--, argv++ ) {
-		if ( strncasecmp( argv[ 0 ], "binddn=", 7 ) == 0 ) {
-			char *p = argv[ 0 ] + 7;
+		if ( strncasecmp( argv[ 0 ], "binddn=", STRLENOF( "binddn=" ) ) == 0 ) {
+			char *p = argv[ 0 ] + STRLENOF( "binddn=" );
 			int l;
 
 			if ( p[ 0 ] == '\"' || p [ 0 ] == '\'' ) {
@@ -154,15 +196,25 @@
 					|| data->lm_binddn[ l ] == '\'' ) {
 				data->lm_binddn[ l ] = '\0';
 			}
-		} else if ( strncasecmp( argv[ 0 ], "bindpw=", 7 ) == 0 ) {
-			data->lm_bindpw = strdup( argv[ 0 ] + 7 );
-			if ( data->lm_bindpw == NULL ) {
+
+			/* deprecated */
+		} else if ( strncasecmp( argv[ 0 ], "bindpw=", STRLENOF( "bindpw=" ) ) == 0 ) {
+			ber_str2bv( argv[ 0 ] + STRLENOF( "bindpw=" ), 0, 1, &data->lm_cred );
+			if ( data->lm_cred.bv_val == NULL ) {
 				map_ldap_free( data );
 				return NULL;
 			}
-		} else if ( strncasecmp( argv[ 0 ], "bindwhen=", 9 ) == 0 ) {
-			char *p = argv[ 0 ] + 9;
 
+		} else if ( strncasecmp( argv[ 0 ], "credentials=", STRLENOF( "credentials=" ) ) == 0 ) {
+			ber_str2bv( argv[ 0 ] + STRLENOF( "credentials=" ), 0, 1, &data->lm_cred );
+			if ( data->lm_cred.bv_val == NULL ) {
+				map_ldap_free( data );
+				return NULL;
+			}
+
+		} else if ( strncasecmp( argv[ 0 ], "bindwhen=", STRLENOF( "bindwhen=" ) ) == 0 ) {
+			char *p = argv[ 0 ] + STRLENOF( "bindwhen=" );
+
 			if ( strcasecmp( p, "now" ) == 0 ) {
 				int rc;
 				
@@ -177,6 +229,10 @@
 					return NULL;
 				}
 
+				ldap_set_option( data->lm_ld,
+					LDAP_OPT_PROTOCOL_VERSION,
+					(void *)&data->lm_version );
+
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
 				ldap_pvt_thread_mutex_init( &data->lm_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
@@ -193,15 +249,43 @@
 			} else {
 				/* ignore ... */
 			}
+
+		} else if ( strncasecmp( argv[ 0 ], "version=", STRLENOF( "version=" ) ) == 0 ) {
+			if ( lutil_atoi( &data->lm_version, argv[ 0 ] + STRLENOF( "version=" ) ) ) {
+				map_ldap_free( data );
+				return NULL;
+			}
+
+			switch ( data->lm_version ) {
+			case LDAP_VERSION2:
+			case LDAP_VERSION3:
+				break;
+
+			default:
+				Debug( LDAP_DEBUG_ANY,
+					"[%s:%d] unknown version %s\n",
+					fname, lineno, p );
+				map_ldap_free( data );
+				return NULL;
+			}
+
+		} else {
+			Debug( LDAP_DEBUG_ANY,
+				"[%s:%d] unknown option %s (ignored)\n",
+				fname, lineno, argv[0] );
 		}
 	}
 
+	if ( data->lm_when == MAP_LDAP_UNKNOWN ) {
+		data->lm_when = MAP_LDAP_EVERYTIME;
+	}
+
 	return ( void * )data;
 }
 
-int
+static int
 map_ldap_apply(
-		struct rewrite_builtin_map *map,
+		void *private,
 		const char *filter,
 		struct berval *val
 
@@ -209,16 +293,13 @@
 {
 	LDAP *ld;
 	LDAPMessage *res = NULL, *entry;
-	char **values;
 	int rc;
-	struct ldap_map_data *data = ( struct ldap_map_data * )map->lb_private;
+	struct ldap_map_data *data = private;
 	LDAPURLDesc *lud = data->lm_lud;
 	
-	int first_try = 1;
+	int first_try = 1, set_version = 0;
 
-	assert( map != NULL );
-	assert( map->lb_type == REWRITE_BUILTIN_MAP_LDAP );
-	assert( map->lb_private != NULL );
+	assert( private != NULL );
 	assert( filter != NULL );
 	assert( val != NULL );
 
@@ -227,6 +308,7 @@
 
 	if ( data->lm_when == MAP_LDAP_EVERYTIME ) {
 		rc = ldap_initialize( &ld, data->lm_url );
+		set_version = 1;
 
 	} else {
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
@@ -237,6 +319,7 @@
 
 		if ( data->lm_when == MAP_LDAP_LATER && data->lm_ld == NULL ) {
 			rc = ldap_initialize( &data->lm_ld, data->lm_url );
+			set_version = 1;
 		}
 		
 		ld = data->lm_ld;
@@ -248,14 +331,23 @@
 	}
 
 do_bind:;
+	if ( set_version ) {
+		ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
+			(void *)&data->lm_version );
+		set_version = 0;
+	}
+
 	if ( data->lm_binddn != NULL ) {
-		rc = ldap_simple_bind_s( ld, data->lm_binddn, data->lm_bindpw );
+		rc = ldap_sasl_bind_s( ld, data->lm_binddn,
+			LDAP_SASL_SIMPLE, &data->lm_cred,
+			NULL, NULL, NULL );
 		if ( rc == LDAP_SERVER_DOWN && first_try ) {
 			first_try = 0;
 			if ( ldap_initialize( &ld, data->lm_url ) != LDAP_SUCCESS ) {
 				rc = REWRITE_ERR;
 				goto rc_return;
 			}
+			set_version = 1;
 			goto do_bind;
 
 		} else if ( rc != REWRITE_SUCCESS ) {
@@ -264,17 +356,18 @@
 		}
 	}
 
-	rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope, ( char * )filter,
-			lud->lud_attrs, data->lm_attrsonly, &res );
+	rc = ldap_search_ext_s( ld, lud->lud_dn, lud->lud_scope, ( char * )filter,
+			data->lm_attrs, 0, NULL, NULL, NULL, 1, &res );
 	if ( rc == LDAP_SERVER_DOWN && first_try ) {
 		first_try = 0;
                 if ( ldap_initialize( &ld, data->lm_url ) != LDAP_SUCCESS ) {
 			rc = REWRITE_ERR;
 			goto rc_return;
 		}
+		set_version = 1;
 		goto do_bind;
 
-	} else if ( rc != REWRITE_SUCCESS ) {
+	} else if ( rc != LDAP_SUCCESS ) {
 		rc = REWRITE_ERR;
 		goto rc_return;
 	}
@@ -288,24 +381,31 @@
 	entry = ldap_first_entry( ld, res );
 	assert( entry != NULL );
 
-	if ( data->lm_attrsonly == 1 ) {
+	if ( data->lm_wantdn == 1 ) {
 		/*
 		 * dn is newly allocated, so there's no need to strdup it
 		 */
 		val->bv_val = ldap_get_dn( ld, entry );
+		val->bv_len = strlen( val->bv_val );
 
 	} else {
-		values = ldap_get_values( ld, entry, lud->lud_attrs[ 0 ] );
-		if ( values == NULL || values[ 0 ] == NULL ) {
-			if ( values != NULL ) {
-				ldap_value_free( values );
+		struct berval **values;
+
+		values = ldap_get_values_len( ld, entry, data->lm_attrs[ 0 ] );
+		if ( values != NULL ) {
+			if ( values[ 0 ] != NULL && values[ 0 ]->bv_val != NULL ) {
+#if 0
+				/* NOTE: in principle, multiple values
+				 * should not be acceptable according
+				 * to the current API; ignore by now */
+				if ( values[ 1 ] != NULL ) {
+					/* error */				
+				}
+#endif
+				ber_dupbv( val, values[ 0 ] );
 			}
-			ldap_msgfree( res );
-			rc = REWRITE_ERR;
-			goto rc_return;
+			ldap_value_free_len( values );
 		}
-		val->bv_val = strdup( values[ 0 ] );
-		ldap_value_free( values );
 	}
 	
 	ldap_msgfree( res );
@@ -314,12 +414,11 @@
 		rc = REWRITE_ERR;
 		goto rc_return;
 	}
-	val->bv_len = strlen( val->bv_val );
 
 rc_return:;
 	if ( data->lm_when == MAP_LDAP_EVERYTIME ) {
 		if ( ld != NULL ) {
-			ldap_unbind_s( ld );
+			ldap_unbind_ext( ld, NULL, NULL );
 		}
 
 	} else {
@@ -332,47 +431,24 @@
 	return rc;
 }
 
-int
+static int
 map_ldap_destroy(
-		struct rewrite_builtin_map **pmap
+		void *private
 )
 {
-	struct ldap_map_data *data;
+	struct ldap_map_data *data = private;
 
-	assert( pmap != NULL );
-	assert( *pmap != NULL );
+	assert( private != NULL );
 	
-	data = ( struct ldap_map_data * )(*pmap)->lb_private;
+	map_ldap_free( data );
 
-	if ( data->lm_when != MAP_LDAP_EVERYTIME && data->lm_ld != NULL ) {
-		ldap_unbind_s( data->lm_ld );
-		data->lm_ld = NULL;
-	}
-
-	if ( data->lm_lud ) {
-		ldap_free_urldesc( data->lm_lud );
-		data->lm_lud = NULL;
-	}
-
-	if ( data->lm_url ) {
-		free( data->lm_url );
-		data->lm_url = NULL;
-	}
-
-	if ( data->lm_binddn ) {
-		free( data->lm_binddn );
-		data->lm_binddn = NULL;
-	}
-
-	if (data->lm_bindpw ) {
-		memset( data->lm_bindpw, 0, strlen( data->lm_bindpw ) );
-		free( data->lm_bindpw );
-		data->lm_bindpw = NULL;
-	}
-	
-	free( data );
-	(*pmap)->lb_private = NULL;
-
 	return 0;
 }
 
+const rewrite_mapper rewrite_ldap_mapper = {
+	"ldap",
+	map_ldap_parse,
+	map_ldap_apply,
+	map_ldap_destroy
+};
+

Modified: openldap/trunk/libraries/librewrite/map.c
===================================================================
--- openldap/trunk/libraries/librewrite/map.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/map.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/map.c,v 1.18.2.5 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/map.c,v 1.21.2.3 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -28,6 +28,10 @@
 #include "rewrite-int.h"
 #include "rewrite-map.h"
 
+static int num_mappers;
+static const rewrite_mapper **mappers;
+#define	MAPPER_ALLOC	8
+
 struct rewrite_map *
 rewrite_map_parse(
 		struct rewrite_info *info,
@@ -417,14 +421,12 @@
 	case REWRITE_MAP_BUILTIN: {
 		struct rewrite_builtin_map *bmap = map->lm_data;
 
-		switch ( bmap->lb_type ) {
-		case REWRITE_BUILTIN_MAP_LDAP:
-			rc = map_ldap_apply( bmap, key->bv_val, val );
-			break;
-		default:
+		if ( bmap->lb_mapper && bmap->lb_mapper->rm_apply )
+			rc = bmap->lb_mapper->rm_apply( bmap->lb_private, key->bv_val,
+				val );
+		else
 			rc = REWRITE_ERR;
 			break;
-		}
 		break;
 	}
 
@@ -445,16 +447,9 @@
 
 	assert( map != NULL );
 
-	switch ( map->lb_type ) {
-	case REWRITE_BUILTIN_MAP_LDAP:
-		map_ldap_destroy( &map );
-		break;
+	if ( map->lb_mapper && map->lb_mapper->rm_destroy )
+		map->lb_mapper->rm_destroy( map->lb_private );
 
-	default:
-		assert(0);
-		break;
-	}
-
 	free( map->lb_name );
 	free( map );
 }
@@ -495,3 +490,58 @@
 	return 0;
 }
 
+/* ldapmap.c */
+extern const rewrite_mapper rewrite_ldap_mapper;
+
+const rewrite_mapper *
+rewrite_mapper_find(
+	const char *name
+)
+{
+	int i;
+
+	if ( !strcasecmp( name, "ldap" ))
+		return &rewrite_ldap_mapper;
+
+	for (i=0; i<num_mappers; i++)
+		if ( !strcasecmp( name, mappers[i]->rm_name ))
+			return mappers[i];
+	return NULL;
+}
+
+int
+rewrite_mapper_register(
+	const rewrite_mapper *map
+)
+{
+	if ( num_mappers % MAPPER_ALLOC == 0 ) {
+		const rewrite_mapper **mnew;
+		mnew = realloc( mappers, (num_mappers + MAPPER_ALLOC) *
+			sizeof( rewrite_mapper * ));
+		if ( mnew )
+			mappers = mnew;
+		else
+			return -1;
+	}
+	mappers[num_mappers++] = map;
+	return 0;
+}
+
+int
+rewrite_mapper_unregister(
+	const rewrite_mapper *map
+)
+{
+	int i;
+
+	for (i = 0; i<num_mappers; i++) {
+		if ( mappers[i] == map ) {
+			num_mappers--;
+			mappers[i] = mappers[num_mappers];
+			mappers[num_mappers] = NULL;
+			return 0;
+		}
+	}
+	/* not found */
+	return -1;
+}

Modified: openldap/trunk/libraries/librewrite/params.c
===================================================================
--- openldap/trunk/libraries/librewrite/params.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/params.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/params.c,v 1.7.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/params.c,v 1.9.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/parse.c
===================================================================
--- openldap/trunk/libraries/librewrite/parse.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/parse.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/parse.c,v 1.7.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/parse.c,v 1.9.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/rewrite-int.h
===================================================================
--- openldap/trunk/libraries/librewrite/rewrite-int.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/rewrite-int.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/rewrite-int.h,v 1.15.2.6 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/rewrite-int.h,v 1.20.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -157,10 +157,11 @@
  * Builtin maps
  */
 struct rewrite_builtin_map {
-#define REWRITE_BUILTIN_MAP_LDAP	0x0201
+#define REWRITE_BUILTIN_MAP	0x0200
 	int                             lb_type;
 	char                           *lb_name;
 	void                           *lb_private;
+	const rewrite_mapper		   *lb_mapper;
 
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
 	ldap_pvt_thread_mutex_t         lb_mutex;

Modified: openldap/trunk/libraries/librewrite/rewrite-map.h
===================================================================
--- openldap/trunk/libraries/librewrite/rewrite-map.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/rewrite-map.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/rewrite-map.h,v 1.5.2.3 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/rewrite-map.h,v 1.7.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -29,26 +29,4 @@
                 const char *name
 );
 
-
-/*
- * LDAP map
- */
-LDAP_REWRITE_F (void  *)
-map_ldap_parse(
-		struct rewrite_info *info,
-		const char *fname,
-		int lineno,
-	       	int argc,
-	       	char **argv
-);
-
-LDAP_REWRITE_F (int)
-map_ldap_apply( struct rewrite_builtin_map *map,
-		const char *filter,
-		struct berval *val
-);
-
-LDAP_REWRITE_F (int)
-map_ldap_destroy( struct rewrite_builtin_map **map );
-
 #endif /* MAP_H */

Modified: openldap/trunk/libraries/librewrite/rewrite.c
===================================================================
--- openldap/trunk/libraries/librewrite/rewrite.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/rewrite.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/rewrite.c,v 1.12.2.4 2007/01/02 21:43:52 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/rewrite.c,v 1.16.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/rule.c
===================================================================
--- openldap/trunk/libraries/librewrite/rule.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/rule.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/rule.c,v 1.14.2.8 2007/01/02 21:43:53 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/rule.c,v 1.23.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/session.c
===================================================================
--- openldap/trunk/libraries/librewrite/session.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/session.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/session.c,v 1.11.2.7 2007/01/02 21:43:53 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/session.c,v 1.19.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/subst.c
===================================================================
--- openldap/trunk/libraries/librewrite/subst.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/subst.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/subst.c,v 1.19.2.4 2007/01/02 21:43:53 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/subst.c,v 1.22.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/var.c
===================================================================
--- openldap/trunk/libraries/librewrite/var.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/var.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/var.c,v 1.11.2.3 2007/01/02 21:43:53 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/var.c,v 1.13.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/libraries/librewrite/xmap.c
===================================================================
--- openldap/trunk/libraries/librewrite/xmap.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/libraries/librewrite/xmap.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/libraries/librewrite/xmap.c,v 1.6.2.7 2007/01/02 21:43:53 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/libraries/librewrite/xmap.c,v 1.12.2.2 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/Makefile.in
===================================================================
--- openldap/trunk/servers/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # servers Makefile.in for OpenLDAP
-# $OpenLDAP: pkg/ldap/servers/Makefile.in,v 1.9.2.4 2007/01/02 21:43:53 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/Makefile.in,v 1.12.2.2 2007/08/31 23:13:57 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -13,5 +13,5 @@
 ## top-level directory of the distribution or, alternatively, at
 ## <http://www.OpenLDAP.org/license.html>.
 
-SUBDIRS= slapd slurpd
+SUBDIRS= slapd
 

Modified: openldap/trunk/servers/slapd/DB_CONFIG
===================================================================
--- openldap/trunk/servers/slapd/DB_CONFIG	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/DB_CONFIG	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/servers/slapd/DB_CONFIG,v 1.1.2.3 2006/08/17 17:36:19 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/DB_CONFIG,v 1.3.2.3 2007/08/31 23:13:57 quanah Exp $
 # Example DB_CONFIG file for use with slapd(8) BDB/HDB databases.
 #
 # See Sleepycat Berkeley DB documentation

Modified: openldap/trunk/servers/slapd/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 ## Makefile.in for slapd
-# $OpenLDAP: pkg/ldap/servers/slapd/Makefile.in,v 1.163.2.13 2007/02/14 15:59:43 hyc Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/Makefile.in,v 1.186.2.5 2007/11/20 18:54:55 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -29,7 +29,7 @@
 		dn.c compare.c modify.c delete.c modrdn.c ch_malloc.c \
 		value.c ava.c bind.c unbind.c abandon.c filterentry.c \
 		phonetic.c acl.c str2filter.c aclparse.c init.c user.c \
-		repl.c lock.c controls.c extended.c kerberos.c passwd.c \
+		lock.c controls.c extended.c passwd.c \
 		schema.c schema_check.c schema_init.c schema_prep.c \
 		schemaparse.c ad.c at.c mr.c syntax.c oc.c saslauthz.c \
 		oidm.c starttls.c index.c sets.c referral.c root_dse.c \
@@ -38,7 +38,7 @@
 		backglue.c backover.c ctxcsn.c ldapsync.c frontend.c \
 		slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \
 		slappasswd.c slaptest.c slapauth.c slapacl.c component.c \
-		aci.c alock.c \
+		aci.c alock.c txn.c \
 		$(@PLAT at _SRCS)
 
 OBJS	= main.o globals.o bconfig.o config.o daemon.o \
@@ -47,7 +47,7 @@
 		dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
 		value.o ava.o bind.o unbind.o abandon.o filterentry.o \
 		phonetic.o acl.o str2filter.o aclparse.o init.o user.o \
-		repl.o lock.o controls.o extended.o kerberos.o passwd.o \
+		lock.o controls.o extended.o passwd.o \
 		schema.o schema_check.o schema_init.o schema_prep.o \
 		schemaparse.o ad.o at.o mr.o syntax.o oc.o saslauthz.o \
 		oidm.o starttls.o index.o sets.o referral.o root_dse.o \
@@ -56,7 +56,7 @@
 		backglue.o backover.o ctxcsn.o ldapsync.o frontend.o \
 		slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \
 		slappasswd.o slaptest.o slapauth.o slapacl.o component.o \
-		aci.o alock.o \
+		aci.o alock.o txn.o \
 		$(@PLAT at _OBJS)
 
 LDAP_INCDIR= ../../include -I$(srcdir) -I$(srcdir)/slapi -I.
@@ -72,7 +72,7 @@
 XDEFS = $(MODULES_CPPFLAGS)
 XLDFLAGS = $(MODULES_LDFLAGS)
 
-XLIBS = $(SLAPD_STATIC_DEPENDS) $(SLAPD_L) $(MODULES_LIBS) 
+XLIBS = $(SLAPD_STATIC_DEPENDS) $(SLAPD_L) $(MODULES_LIBS)
 XXLIBS = $(SLAPD_LIBS) $(SECURITY_LIBS) $(LUTIL_LIBS)
 XXXLIBS = $(LTHREAD_LIBS) $(SLAPI_LIBS)
 
@@ -103,7 +103,7 @@
 # we want to export EVERY global symbol that it knows about (NOT including
 # symbols that are imported from other DLLs). The set of symbols to
 # export INCLUDES symbols from all static libraries that slapd gets
-# linked with, e.g. avl, ldbm, lunicode, lutil, etc. This list
+# linked with, e.g. avl, lunicode, lutil, etc. This list
 # will also include liblber and libldap_r if they were built as static
 # libraries. ALSO included will be symbols from other STATIC libraries
 # outside the domain of the OpenLDAP source tree, e.g. regex, ltdl,
@@ -138,7 +138,7 @@
 # for functions, but it is required for variables.
 #
 # The symdummy.c file basically references EVERY symbol available to slapd.exe,
-# including symbols that slapd.exe never actually refereneced. The file
+# including symbols that slapd.exe never actually referenced. The file
 # is compiled and included at link time. Without this object file, slapd.exe
 # would NOT export symbols that it never referenced. The reason that these
 # symbols must still be exported is because a dynamic module may want to
@@ -155,7 +155,7 @@
 # on its own very long list of dependencies.
 #
 slapd.def: libbackends.a liboverlays.a version.o
-	@for i in $(LDFLAGS) ; do \
+	@for i in XX $(LDFLAGS) ; do \
 	    path=`expr "$$i" : "-L\(.*\)"`; \
 	    if test $$? != 0; then continue; fi; \
 	    paths="$$paths $$path"; \
@@ -167,7 +167,7 @@
 		-l*) \
 		    done="" ;\
 		    base=`expr "$$i" : "-l\(.*\)"`; \
-		    for p in $$paths ; do \
+		    for p in . $$paths ; do \
 			for ext in la dll dll.a a ; do \
 			    path=$$p/lib$$base.$$ext; \
 			    test ! -f $$path && continue; \

Modified: openldap/trunk/servers/slapd/abandon.c
===================================================================
--- openldap/trunk/servers/slapd/abandon.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/abandon.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* abandon.c - decode and handle an ldap abandon operation */
-/* $OpenLDAP: pkg/ldap/servers/slapd/abandon.c,v 1.45.2.8 2007/01/02 21:43:53 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/abandon.c,v 1.52.2.3 2007/11/07 20:58:38 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -37,7 +37,8 @@
 	ber_int_t	id;
 	Operation	*o;
 
-	Debug( LDAP_DEBUG_TRACE, "do_abandon\n", 0, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE, "%s do_abandon\n",
+		op->o_log_prefix, 0, 0 );
 
 	/*
 	 * Parse the abandon request.  It looks like this:
@@ -46,7 +47,8 @@
 	 */
 
 	if ( ber_scanf( op->o_ber, "i", &id ) == LBER_ERROR ) {
-		Debug( LDAP_DEBUG_ANY, "do_abandon: ber_scanf failed\n", 0, 0 ,0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_abandon: ber_scanf failed\n",
+			op->o_log_prefix, 0, 0 );
 		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
 		return SLAPD_DISCONNECT;
 	}
@@ -55,15 +57,17 @@
 		op->o_log_prefix, (long) id, 0, 0, 0 );
 
 	if( get_ctrls( op, rs, 0 ) != LDAP_SUCCESS ) {
-		Debug( LDAP_DEBUG_ANY, "do_abandon: get_ctrls failed\n", 0, 0 ,0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_abandon: get_ctrls failed\n",
+			op->o_log_prefix, 0, 0 );
 		return rs->sr_err;
 	} 
 
-	Debug( LDAP_DEBUG_ARGS, "do_abandon: id=%ld\n", (long) id, 0 ,0 );
+	Debug( LDAP_DEBUG_ARGS, "%s do_abandon: id=%ld\n",
+		op->o_log_prefix, (long) id, 0 );
 
 	if( id <= 0 ) {
-		Debug( LDAP_DEBUG_ANY,
-			"do_abandon: bad msgid %ld\n", (long) id, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_abandon: bad msgid %ld\n",
+			op->o_log_prefix, (long) id, 0 );
 		return LDAP_SUCCESS;
 	}
 
@@ -91,10 +95,10 @@
 		LDAP_STAILQ_FOREACH( o, &op->o_conn->c_pending_ops, o_next ) {
 			if ( o->o_msgid == id ) {
 				LDAP_STAILQ_REMOVE( &op->o_conn->c_pending_ops,
-					o, slap_op, o_next );
+					o, Operation, o_next );
 				LDAP_STAILQ_NEXT(o, o_next) = NULL;
 				op->o_conn->c_n_ops_pending--;
-				slap_op_free( o );
+				slap_op_free( o, NULL );
 				break;
 			}
 		}
@@ -102,8 +106,9 @@
 
 	ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
-	Debug( LDAP_DEBUG_TRACE, "do_abandon: op=%ld %sfound\n",
-		(long) id, o ? "" : "not ", 0 );
+	Debug( LDAP_DEBUG_TRACE, "%s do_abandon: op=%ld %sfound\n",
+		op->o_log_prefix,
+		(long) id, o ? "" : "not " );
 	return rs->sr_err;
 }
 

Modified: openldap/trunk/servers/slapd/aci.c
===================================================================
--- openldap/trunk/servers/slapd/aci.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/aci.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* aci.c - routines to parse and check acl's */
-/* $OpenLDAP: pkg/ldap/servers/slapd/aci.c,v 1.1.2.9 2007/02/13 22:41:20 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/aci.c,v 1.14.2.5 2007/09/29 09:55:21 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -40,8 +40,21 @@
 #include "lber_pvt.h"
 #include "lutil.h"
 
-#define ACI_BUF_SIZE 	1024	/* use most appropriate size */
+/* use most appropriate size */
+#define ACI_BUF_SIZE 			1024
 
+/* move to "stable" when no longer experimental */
+#define SLAPD_ACI_SYNTAX		"1.3.6.1.4.1.4203.666.2.1"
+
+/* change this to "OpenLDAPset" */
+#define SLAPD_ACI_SET_ATTR		"template"
+
+typedef enum slap_aci_scope_t {
+	SLAP_ACI_SCOPE_ENTRY		= 0x1,
+	SLAP_ACI_SCOPE_CHILDREN		= 0x2,
+	SLAP_ACI_SCOPE_SUBTREE		= ( SLAP_ACI_SCOPE_ENTRY | SLAP_ACI_SCOPE_CHILDREN )
+} slap_aci_scope_t;
+
 enum {
 	ACI_BV_ENTRY,
 	ACI_BV_CHILDREN,
@@ -49,6 +62,7 @@
 	ACI_BV_SUBTREE,
 
 	ACI_BV_BR_ENTRY,
+	ACI_BV_BR_CHILDREN,
 	ACI_BV_BR_ALL,
 
 	ACI_BV_ACCESS_ID,
@@ -83,6 +97,7 @@
 
 	/* */
 	BER_BVC("[entry]"),
+	BER_BVC("[children]"),
 	BER_BVC("[all]"),
 
 	/* type */
@@ -111,10 +126,7 @@
 	BER_BVNULL
 };
 
-#ifdef SLAP_DYNACL
-static
-#endif /* SLAP_DYNACL */
-AttributeDescription *slap_ad_aci;
+static AttributeDescription	*slap_ad_aci;
 
 static int
 OpenLDAPaciValidate(
@@ -266,14 +278,31 @@
 	ACL_INIT(mask);
 	for ( i = 1; acl_get_part( list, i + 1, ';', &bv ) >= 0; i += 2 ) {
 		if ( aci_list_has_attr( &bv, attr, val ) == 0 ) {
+			Debug( LDAP_DEBUG_ACL,
+				"        <= aci_list_get_attr_rights "
+				"test %s for %s -> failed\n",
+				bv.bv_val, attr->bv_val, 0 );
 			continue;
 		}
 
+		Debug( LDAP_DEBUG_ACL,
+			"        <= aci_list_get_attr_rights "
+			"test %s for %s -> ok\n",
+			bv.bv_val, attr->bv_val, 0 );
+
 		if ( acl_get_part( list, i, ';', &bv ) < 0 ) {
+			Debug( LDAP_DEBUG_ACL,
+				"        <= aci_list_get_attr_rights "
+				"test no rights\n",
+				0, 0, 0 );
 			continue;
 		}
 
 		mask |= aci_list_map_rights( &bv );
+		Debug( LDAP_DEBUG_ACL,
+			"        <= aci_list_get_attr_rights "
+			"rights %s to mask 0x%x\n",
+			bv.bv_val, mask, 0 );
 	}
 
 	return mask;
@@ -281,20 +310,22 @@
 
 static int
 aci_list_get_rights(
-	struct berval		*list,
-	const struct berval	*attr,
-	struct berval		*val,
-	slap_access_t		*grant,
-	slap_access_t		*deny )
+	struct berval	*list,
+	struct berval	*attr,
+	struct berval	*val,
+	slap_access_t	*grant,
+	slap_access_t	*deny )
 {
-	struct berval	perm, actn;
+	struct berval	perm, actn, baseattr;
 	slap_access_t	*mask;
 	int		i, found;
 
 	if ( attr == NULL || BER_BVISEMPTY( attr ) ) {
-		attr = &aci_bv[ ACI_BV_ENTRY ];
+		attr = (struct berval *)&aci_bv[ ACI_BV_ENTRY ];
+
+	} else if ( acl_get_part( attr, 0, ';', &baseattr ) > 0 ) {
+		attr = &baseattr;
 	}
-
 	found = 0;
 	ACL_INIT(*grant);
 	ACL_INIT(*deny);
@@ -388,7 +419,7 @@
 	return rc;
 }
 
-int
+static int
 aci_mask(
 	Operation		*op,
 	Entry			*e,
@@ -561,11 +592,10 @@
 				at != NULL;
 				at = attrs_find( at->a_next, ad ) )
 		{
-			if ( value_find_ex( ad,
+			if ( attr_valfind( at, 
 				SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
 					SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-				at->a_nvals,
-				&op->o_ndn, op->o_tmpmemctx ) == 0 )
+				&op->o_ndn, NULL, op->o_tmpmemctx ) == 0 )
 			{
 				rc = 1;
 				break;
@@ -638,13 +668,14 @@
 	return 0;
 }
 
-int
+static int
 aci_init( void )
 {
 	/* OpenLDAP eXperimental Syntax */
 	static slap_syntax_defs_rec aci_syntax_def = {
 		"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
 			SLAP_SYNTAX_HIDE,
+			NULL,
 			OpenLDAPaciValidate,
 			OpenLDAPaciPretty
 	};
@@ -672,10 +703,7 @@
 		&slap_ad_aci
 	};
 
-	LDAPAttributeType	*at;
-	AttributeType		*sat;
 	int			rc;
-	const char		*text;
 
 	/* ACI syntax */
 	rc = register_syntax( &aci_syntax_def );
@@ -690,42 +718,19 @@
 	}
 
 	/* ACI attribute */
-	at = ldap_str2attributetype( aci_at.desc,
-		&rc, &text, LDAP_SCHEMA_ALLOW_ALL );
-	if ( !at ) {
-		Debug( LDAP_DEBUG_ANY,
-			"aci_init: AttributeType \"%s\" parse failed: %s %s\n",
-			aci_at.name, ldap_scherr2str( rc ), text );
-		return rc;
-	}
-
-	rc = at_add( at, 0, &sat, &text );
+	rc = register_at( aci_at.desc, aci_at.ad, 0 );
 	if ( rc != LDAP_SUCCESS ) {
-		ldap_attributetype_free( at );
 		Debug( LDAP_DEBUG_ANY,
-			"aci_init: AttributeType \"%s\" load failed: %s %s\n",
-			aci_at.name, scherr2str( rc ), text );
+			"aci_init: at_register failed\n", 0, 0, 0 );
 		return rc;
 	}
-	ldap_memfree( at );
 
-	rc = slap_str2ad( aci_at.name,
-			aci_at.ad, &text );
-	if ( rc != LDAP_SUCCESS ) {
-		Debug( LDAP_DEBUG_ANY,
-			"aci_init: unable to find AttributeDescription "
-			"\"%s\": %d (%s)\n",
-			aci_at.name, rc, text );
-		return 1;
-	}
-
 	/* install flags */
-	sat->sat_flags |= aci_at.flags;
+	(*aci_at.ad)->ad_type->sat_flags |= aci_at.flags;
 
 	return rc;
 }
 
-#ifdef SLAP_DYNACL
 static int
 dynacl_aci_parse(
 	const char *fname,
@@ -968,7 +973,6 @@
 	return rc;
 }
 
-#endif /* SLAP_DYNACL */
 
 /* ACI syntax validation */
 
@@ -1018,16 +1022,17 @@
  * aci is accepted in following form:
  *    oid#scope#rights#type#subject
  * Where:
- *    oid       := numeric OID
- *    scope     := entry|children
+ *    oid       := numeric OID (currently ignored)
+ *    scope     := entry|children|subtree
  *    rights    := right[[$right]...]
  *    right     := (grant|deny);action
- *    action    := perms;attr[[;perms;attr]...]
+ *    action    := perms;attrs[[;perms;attrs]...]
  *    perms     := perm[[,perm]...]
  *    perm      := c|s|r|w|x
- *    attr      := attributeType|"[all]"
- *    type      :=  public|users|self|dnattr|group|role|set|set-ref|
- *                  access_id|subtree|onelevel|children
+ *    attrs     := attribute[[,attribute]..]|"[all]"
+ *    attribute := attributeType|attributeType=attributeValue|attributeType=attributeValuePrefix*
+ *    type      := public|users|self|dnattr|group|role|set|set-ref|
+ *                 access_id|subtree|onelevel|children
  */
 static int 
 OpenLDAPaciValidatePerms(
@@ -1046,6 +1051,7 @@
 			break;
 
 		default:
+		        Debug( LDAP_DEBUG_ACL, "aciValidatePerms: perms needs to be one of x,d,c,s,r,w in '%s'\n", perms->bv_val, 0, 0 );
 			return LDAP_INVALID_SYNTAX;
 		}
 
@@ -1059,6 +1065,7 @@
 		assert( i != perms->bv_len );
 
 		if ( perms->bv_val[ i ] != ',' ) {
+		        Debug( LDAP_DEBUG_ACL, "aciValidatePerms: missing comma in '%s'\n", perms->bv_val, 0, 0 );
 			return LDAP_INVALID_SYNTAX;
 		}
 
@@ -1087,6 +1094,7 @@
 	if ( acl_get_part( action, 0, ';', &bv ) < 0 ||
 		bv_getcaseidx( &bv, ACIgrantdeny ) == -1 )
 	{
+		Debug( LDAP_DEBUG_ACL, "aciValidateRight: '%s' must be either 'grant' or 'deny'\n", bv.bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
@@ -1100,21 +1108,36 @@
 
 		} else {
 			/* attr */
-			AttributeDescription	*ad = NULL;
-			const char		*text = NULL;
+			AttributeDescription	*ad;
+			const char		*text;
+			struct berval		attr, left, right;
+			int			j;
 
 			/* could be "[all]" or an attribute description */
 			if ( ber_bvstrcasecmp( &bv, &aci_bv[ ACI_BV_BR_ALL ] ) == 0 ) {
 				continue;
 			}
 
-			/* "[entry]" is tolerated for backward compatibility */
-			if ( ber_bvstrcasecmp( &bv, &aci_bv[ ACI_BV_BR_ENTRY ] ) == 0 ) {
-				continue;
-			}
 
-			if ( slap_bv2ad( &bv, &ad, &text ) != LDAP_SUCCESS ) {
-				return LDAP_INVALID_SYNTAX;
+			for ( j = 0; acl_get_part( &bv, j, ',', &attr ) >= 0; j++ ) 
+			{
+				ad = NULL;
+				text = NULL;
+				if ( acl_get_part( &attr, 0, '=', &left ) < 0
+					|| acl_get_part( &attr, 1, '=', &right ) < 0 ) 
+				{
+					if ( slap_bv2ad( &attr, &ad, &text ) != LDAP_SUCCESS ) 
+					{
+						Debug( LDAP_DEBUG_ACL, "aciValidateRight: unknown attribute: '%s'\n", attr.bv_val, 0, 0 );
+						return LDAP_INVALID_SYNTAX;
+					}
+				} else {
+					if ( slap_bv2ad( &left, &ad, &text ) != LDAP_SUCCESS ) 
+					{
+						Debug( LDAP_DEBUG_ACL, "aciValidateRight: unknown attribute: '%s'\n", left.bv_val, 0, 0 );
+						return LDAP_INVALID_SYNTAX;
+					}
+				}
 			}
 		}
 	}
@@ -1124,6 +1147,7 @@
 		return LDAP_SUCCESS;
 
 	} else {
+		Debug( LDAP_DEBUG_ACL, "aciValidateRight: perms:attr need to be pairs in '%s'\n", action->bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
@@ -1144,16 +1168,20 @@
 
 	/* grant|deny */
 	if ( acl_get_part( action, 0, ';', &grantdeny ) < 0 ) {
+	        Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: missing ';' in '%s'\n", action->bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 	idx = bv_getcaseidx( &grantdeny, ACIgrantdeny );
 	if ( idx == -1 ) {
+	        Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: '%s' must be grant or deny\n", grantdeny.bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
 	ber_dupbv_x( naction, (struct berval *)ACIgrantdeny[ idx ], ctx );
 
 	for ( i = 1; acl_get_part( action, i, ';', &bv ) >= 0; i++ ) {
+		struct berval	nattrs = BER_BVNULL;
+		int		freenattrs = 1;
 		if ( i & 1 ) {
 			/* perms */
 			if ( OpenLDAPaciValidatePerms( &bv ) != LDAP_SUCCESS )
@@ -1168,29 +1196,76 @@
 
 			/* could be "[all]" or an attribute description */
 			if ( ber_bvstrcasecmp( &bv, &aci_bv[ ACI_BV_BR_ALL ] ) == 0 ) {
-				bv = aci_bv[ ACI_BV_BR_ALL ];
+				nattrs = aci_bv[ ACI_BV_BR_ALL ];
+				freenattrs = 0;
 
-			/* "[entry]" is tolerated for backward compatibility */
-			} else if ( ber_bvstrcasecmp( &bv, &aci_bv[ ACI_BV_BR_ENTRY ] ) == 0 ) {
-				bv = aci_bv[ ACI_BV_ENTRY ];
-
 			} else {
 				AttributeDescription	*ad = NULL;
+				AttributeDescription	adstatic= { 0 };
 				const char		*text = NULL;
-				int			rc;
+				struct berval		attr, left, right;
+				int			j;
+				int			len;
 
-				rc = slap_bv2ad( &bv, &ad, &text );
-				if ( rc != LDAP_SUCCESS ) {
-					return LDAP_INVALID_SYNTAX;
+				for ( j = 0; acl_get_part( &bv, j, ',', &attr ) >= 0; j++ ) 
+				{
+					ad = NULL;
+					text = NULL;
+					/* openldap 2.1 aci compabitibility [entry] -> entry */
+					if ( ber_bvstrcasecmp( &attr, &aci_bv[ ACI_BV_BR_ENTRY ] ) == 0 ) {
+						ad = &adstatic;
+						adstatic.ad_cname = aci_bv[ ACI_BV_ENTRY ];
+
+					/* openldap 2.1 aci compabitibility [children] -> children */
+					} else if ( ber_bvstrcasecmp( &attr, &aci_bv[ ACI_BV_BR_CHILDREN ] ) == 0 ) {
+						ad = &adstatic;
+						adstatic.ad_cname = aci_bv[ ACI_BV_CHILDREN ];
+
+					/* openldap 2.1 aci compabitibility [all] -> only [all] */
+					} else if ( ber_bvstrcasecmp( &attr, &aci_bv[ ACI_BV_BR_ALL ] ) == 0 ) {
+						ber_memfree_x( nattrs.bv_val, ctx );
+						nattrs = aci_bv[ ACI_BV_BR_ALL ];
+						freenattrs = 0;
+						break;
+
+					} else if ( acl_get_part( &attr, 0, '=', &left ) < 0
+				     		|| acl_get_part( &attr, 1, '=', &right ) < 0 ) 
+					{
+						if ( slap_bv2ad( &attr, &ad, &text ) != LDAP_SUCCESS ) 
+						{
+							ber_memfree_x( nattrs.bv_val, ctx );
+							Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: unknown attribute: '%s'\n", attr.bv_val, 0, 0 );
+							return LDAP_INVALID_SYNTAX;
+						}
+
+					} else {
+						if ( slap_bv2ad( &left, &ad, &text ) != LDAP_SUCCESS ) 
+						{
+							ber_memfree_x( nattrs.bv_val, ctx );
+							Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: unknown attribute: '%s'\n", left.bv_val, 0, 0 );
+							return LDAP_INVALID_SYNTAX;
+						}
+					}
+					
+				
+					len = nattrs.bv_len + ( !BER_BVISEMPTY( &nattrs ) ? STRLENOF( "," ) : 0 )
+				      		+ ad->ad_cname.bv_len;
+					nattrs.bv_val = ber_memrealloc_x( nattrs.bv_val, len + 1, ctx );
+	                        	ptr = &nattrs.bv_val[ nattrs.bv_len ];
+					if ( !BER_BVISEMPTY( &nattrs ) ) {
+						*ptr++ = ',';
+					}
+					ptr = lutil_strncopy( ptr, ad->ad_cname.bv_val, ad->ad_cname.bv_len );
+                                	ptr[ 0 ] = '\0';
+                                	nattrs.bv_len = len;
 				}
 
-				bv = ad->ad_cname;
 			}
 
 			naction->bv_val = ber_memrealloc_x( naction->bv_val,
 				naction->bv_len + STRLENOF( ";" )
 				+ perms.bv_len + STRLENOF( ";" )
-				+ bv.bv_len + 1,
+				+ nattrs.bv_len + 1,
 				ctx );
 
 			ptr = &naction->bv_val[ naction->bv_len ];
@@ -1199,10 +1274,13 @@
 			ptr = lutil_strncopy( ptr, perms.bv_val, perms.bv_len );
 			ptr[ 0 ] = ';';
 			ptr++;
-			ptr = lutil_strncopy( ptr, bv.bv_val, bv.bv_len );
+			ptr = lutil_strncopy( ptr, nattrs.bv_val, nattrs.bv_len );
 			ptr[ 0 ] = '\0';
 			naction->bv_len += STRLENOF( ";" ) + perms.bv_len
-				+ STRLENOF( ";" ) + bv.bv_len;
+				+ STRLENOF( ";" ) + nattrs.bv_len;
+			if ( freenattrs ) {
+				ber_memfree_x( nattrs.bv_val, ctx );
+			}
 		}
 	}
 	
@@ -1211,6 +1289,7 @@
 		return LDAP_SUCCESS;
 
 	} else {
+		Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: perms:attr need to be pairs in '%s'\n", action->bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 }
@@ -1320,8 +1399,10 @@
 			type = BER_BVNULL,
 			subject = BER_BVNULL;
 	int		idx;
-
+	int		rc;
+	
 	if ( BER_BVISEMPTY( val ) ) {
+		Debug( LDAP_DEBUG_ACL, "aciValidatet: value is empty\n", 0, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
@@ -1333,6 +1414,7 @@
 		 * I'd replace it with X-ORDERED VALUES so that
 		 * it's guaranteed values are maintained and used
 		 * in the desired order */
+		Debug( LDAP_DEBUG_ACL, "aciValidate: invalid oid '%s'\n", oid.bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
@@ -1340,6 +1422,7 @@
 	if ( acl_get_part( val, 1, '#', &scope ) < 0 || 
 		bv_getcaseidx( &scope, OpenLDAPaciscopes ) == -1 )
 	{
+		Debug( LDAP_DEBUG_ACL, "aciValidate: invalid scope '%s'\n", scope.bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
@@ -1352,6 +1435,7 @@
 
 	/* type */
 	if ( acl_get_part( val, 3, '#', &type ) < 0 ) {
+		Debug( LDAP_DEBUG_ACL, "aciValidate: missing type in '%s'\n", val->bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 	idx = bv_getcaseidx( &type, OpenLDAPacitypes );
@@ -1359,11 +1443,13 @@
 		struct berval	isgr;
 
 		if ( acl_get_part( &type, 0, '/', &isgr ) < 0 ) {
+			Debug( LDAP_DEBUG_ACL, "aciValidate: invalid type '%s'\n", type.bv_val, 0, 0 );
 			return LDAP_INVALID_SYNTAX;
 		}
 
 		idx = bv_getcaseidx( &isgr, OpenLDAPacitypes );
 		if ( idx == -1 || idx >= LAST_OPTIONAL ) {
+			Debug( LDAP_DEBUG_ACL, "aciValidate: invalid type '%s'\n", isgr.bv_val, 0, 0 );
 			return LDAP_INVALID_SYNTAX;
 		}
 	}
@@ -1371,6 +1457,7 @@
 	/* subject */
 	bv_get_tail( val, &type, &subject );
 	if ( subject.bv_val[ 0 ] != '#' ) {
+		Debug( LDAP_DEBUG_ACL, "aciValidate: missing subject in '%s'\n", val->bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
@@ -1378,15 +1465,16 @@
 		if ( OpenLDAPacitypes[ idx ] == &aci_bv[ ACI_BV_DNATTR ] ) {
 			AttributeDescription	*ad = NULL;
 			const char		*text = NULL;
-			int			rc;
 
 			rc = slap_bv2ad( &subject, &ad, &text );
 			if ( rc != LDAP_SUCCESS ) {
+				Debug( LDAP_DEBUG_ACL, "aciValidate: unknown dn attribute '%s'\n", subject.bv_val, 0, 0 );
 				return LDAP_INVALID_SYNTAX;
 			}
 
 			if ( ad->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
 				/* FIXME: allow nameAndOptionalUID? */
+				Debug( LDAP_DEBUG_ACL, "aciValidate: wrong syntax for dn attribute '%s'\n", subject.bv_val, 0, 0 );
 				return LDAP_INVALID_SYNTAX;
 			}
 		}
@@ -1420,11 +1508,13 @@
 
 				rc = slap_bv2ad( &atbv, &ad, &text );
 				if ( rc != LDAP_SUCCESS ) {
+				        Debug( LDAP_DEBUG_ACL, "aciValidate: unknown group attribute '%s'\n", atbv.bv_val, 0, 0 );
 					return LDAP_INVALID_SYNTAX;
 				}
 			}
 
 			if ( oc_bvfind( &ocbv ) == NULL ) {
+			        Debug( LDAP_DEBUG_ACL, "aciValidate: unknown group '%s'\n", ocbv.bv_val, 0, 0 );
 				return LDAP_INVALID_SYNTAX;
 			}
 		}
@@ -1432,6 +1522,7 @@
 
 	if ( BER_BVISEMPTY( &subject ) ) {
 		/* empty DN invalid */
+	        Debug( LDAP_DEBUG_ACL, "aciValidate: missing dn in '%s'\n", val->bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
@@ -1439,7 +1530,11 @@
 	subject.bv_len--;
 
 	/* FIXME: pass DN syntax? */
-	return dnValidate( NULL, &subject );
+	rc = dnValidate( NULL, &subject );
+	if ( rc != LDAP_SUCCESS ) {
+	        Debug( LDAP_DEBUG_ACL, "aciValidate: invalid dn '%s'\n", subject.bv_val, 0, 0 );
+	}
+	return rc;
 }
 
 static int
@@ -1466,6 +1561,7 @@
 	BER_BVZERO( out );
 
 	if ( BER_BVISEMPTY( val ) ) {
+		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: value is empty\n", 0, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
@@ -1473,21 +1569,25 @@
 	if ( acl_get_part( val, 0, '#', &oid ) < 0 || 
 		numericoidValidate( NULL, &oid ) != LDAP_SUCCESS )
 	{
+		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid oid '%s'\n", oid.bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 
 	/* scope: normalize by replacing with OpenLDAPaciscopes */
 	if ( acl_get_part( val, 1, '#', &scope ) < 0 ) {
+		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing scope in '%s'\n", val->bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 	idx = bv_getcaseidx( &scope, OpenLDAPaciscopes );
 	if ( idx == -1 ) {
+		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid scope '%s'\n", scope.bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 	scope = *OpenLDAPaciscopes[ idx ];
 
 	/* rights */
 	if ( acl_get_part( val, 2, '#', &rights ) < 0 ) {
+		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing rights in '%s'\n", val->bv_val, 0, 0 );
 		return LDAP_INVALID_SYNTAX;
 	}
 	if ( OpenLDAPaciNormalizeRights( &rights, &nrights, ctx )
@@ -1498,6 +1598,7 @@
 
 	/* type */
 	if ( acl_get_part( val, 3, '#', &type ) < 0 ) {
+		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing type in '%s'\n", val->bv_val, 0, 0 );
 		rc = LDAP_INVALID_SYNTAX;
 		goto cleanup;
 	}
@@ -1506,12 +1607,14 @@
 		struct berval	isgr;
 
 		if ( acl_get_part( &type, 0, '/', &isgr ) < 0 ) {
+		        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid type '%s'\n", type.bv_val, 0, 0 );
 			rc = LDAP_INVALID_SYNTAX;
 			goto cleanup;
 		}
 
 		idx = bv_getcaseidx( &isgr, OpenLDAPacitypes );
 		if ( idx == -1 || idx >= LAST_OPTIONAL ) {
+		        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid type '%s'\n", isgr.bv_val, 0, 0 );
 			rc = LDAP_INVALID_SYNTAX;
 			goto cleanup;
 		}
@@ -1522,6 +1625,7 @@
 	bv_get_tail( val, &type, &subject );
 
 	if ( BER_BVISEMPTY( &subject ) || subject.bv_val[ 0 ] != '#' ) {
+	        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing subject in '%s'\n", val->bv_val, 0, 0 );
 		rc = LDAP_INVALID_SYNTAX;
 		goto cleanup;
 	}
@@ -1542,6 +1646,7 @@
 			freesubject = 1;
 
 		} else {
+	                Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid subject dn '%s'\n", subject.bv_val, 0, 0 );
 			goto cleanup;
 		}
 
@@ -1574,6 +1679,7 @@
 	
 					rc = slap_bv2ad( &atbv, &ad, &text );
 					if ( rc != LDAP_SUCCESS ) {
+	                                        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: unknown group attribute '%s'\n", atbv.bv_val, 0, 0 );
 						rc = LDAP_INVALID_SYNTAX;
 						goto cleanup;
 					}
@@ -1583,6 +1689,7 @@
 
 				oc = oc_bvfind( &ocbv );
 				if ( oc == NULL ) {
+                                        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid group '%s'\n", ocbv.bv_val, 0, 0 );
 					rc = LDAP_INVALID_SYNTAX;
 					goto cleanup;
 				}
@@ -1618,12 +1725,14 @@
 
 		rc = slap_bv2ad( &subject, &ad, &text );
 		if ( rc != LDAP_SUCCESS ) {
+                        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: unknown dn attribute '%s'\n", subject.bv_val, 0, 0 );
 			rc = LDAP_INVALID_SYNTAX;
 			goto cleanup;
 		}
 
 		if ( ad->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
 			/* FIXME: allow nameAndOptionalUID? */
+                        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: wrong syntax for dn attribute '%s'\n", subject.bv_val, 0, 0 );
 			rc = LDAP_INVALID_SYNTAX;
 			goto cleanup;
 		}
@@ -1703,7 +1812,7 @@
 int
 init_module( int argc, char *argv[] )
 {
-	return slap_dynacl_register();
+	return dynacl_aci_init();
 }
 #endif /* SLAPD_ACI_ENABLED == SLAPD_MOD_DYNAMIC */
 

Modified: openldap/trunk/servers/slapd/acl.c
===================================================================
--- openldap/trunk/servers/slapd/acl.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/acl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* acl.c - routines to parse and check acl's */
-/* $OpenLDAP: pkg/ldap/servers/slapd/acl.c,v 1.250.2.28 2007/04/01 21:31:25 quanah Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/acl.c,v 1.303.2.11 2007/11/27 18:25:33 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -40,6 +40,9 @@
 #define ACL_BUF_SIZE 	1024	/* use most appropriate size */
 
 static const struct berval	acl_bv_ip_eq = BER_BVC( "IP=" );
+#ifdef LDAP_PF_INET6
+static const struct berval	acl_bv_ipv6_eq = BER_BVC( "IP=[" );
+#endif /* LDAP_PF_INET6 */
 #ifdef LDAP_PF_LOCAL
 static const struct berval	acl_bv_path_eq = BER_BVC("PATH=");
 #endif /* LDAP_PF_LOCAL */
@@ -94,7 +97,6 @@
  * - can be legally called with op->o_bd == NULL
  */
 
-#ifdef SLAP_OVERLAY_ACCESS
 int
 slap_access_always_allowed(
 	Operation		*op,
@@ -135,7 +137,6 @@
 	slap_access_t			access_level;
 	const char			*attr;
 	regmatch_t			matches[MAXREMATCHES];
-	int				st_same_attr = 0;
 
 	assert( op != NULL );
 	assert( e != NULL );
@@ -199,24 +200,17 @@
 	ret = 0;
 	control = ACL_BREAK;
 
-	if ( st_same_attr ) {
-		assert( state->as_vd_acl != NULL );
-
+	if ( state && state->as_vd_ad == desc ) {
 		a = state->as_vd_acl;
 		count = state->as_vd_acl_count;
-		if ( !ACL_IS_INVALID( state->as_vd_acl_mask ) ) {
-			mask = state->as_vd_acl_mask;
-			AC_MEMCPY( matches, state->as_vd_acl_matches, sizeof(matches) );
-			goto vd_access;
-		}
 
 	} else {
 		if ( state ) state->as_vi_acl = NULL;
 		a = NULL;
-		ACL_PRIV_ASSIGN( mask, *maskp );
 		count = 0;
-		memset( matches, '\0', sizeof( matches ) );
 	}
+	ACL_PRIV_ASSIGN( mask, *maskp );
+	memset( matches, '\0', sizeof( matches ) );
 
 	while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
 		MAXREMATCHES, matches, state ) ) != NULL )
@@ -240,18 +234,17 @@
 				( state->as_recorded & ACL_STATE_RECORDED_NV ) )
 			{
 				Debug( LDAP_DEBUG_ACL,
-					"=> slap_access_allowed: result from state (%s)\n",
+					"=> slap_access_allowed: result was in cache (%s)\n",
 					attr, 0, 0 );
 				ret = state->as_result;
 				goto done;
 			} else {
 				Debug( LDAP_DEBUG_ACL,
-					"=> slap_access_allowed: no res from state (%s)\n",
+					"=> slap_access_allowed: result not in cache (%s)\n",
 					attr, 0, 0 );
 			}
 		}
 
-vd_access:
 		control = slap_acl_mask( a, &mask, op,
 			e, desc, val, MAXREMATCHES, matches, count, state );
 
@@ -311,7 +304,7 @@
 	be_orig = op->o_bd;
 
 	if ( op->o_bd == NULL ) {
-		op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
+		op->o_bd = select_backend( &op->o_req_ndn, 0 );
 		if ( op->o_bd == NULL )
 			op->o_bd = frontendDB;
 	}
@@ -341,7 +334,6 @@
 	slap_mask_t			mask;
 	slap_access_t			access_level;
 	const char			*attr;
-	int				st_same_attr = 0;
 	static AccessControlState	state_init = ACL_STATE_INIT;
 
 	assert( e != NULL );
@@ -359,12 +351,15 @@
 	assert( attr != NULL );
 
 	if ( op ) {
-		if ( op->o_is_auth_check &&
+		if ( op->o_acl_priv != ACL_NONE ) {
+			access = op->o_acl_priv;
+
+		} else if ( op->o_is_auth_check &&
 			( access_level == ACL_SEARCH || access_level == ACL_READ ) )
 		{
 			access = ACL_AUTH;
 
-		} else if ( get_manageDIT( op ) && access_level == ACL_WRITE &&
+		} else if ( get_relax( op ) && access_level == ACL_WRITE &&
 			desc == slap_schema.si_ad_entry )
 		{
 			access = ACL_MANAGE;
@@ -373,24 +368,15 @@
 
 	if ( state ) {
 		if ( state->as_vd_ad == desc ) {
-			if ( state->as_recorded ) {
-				if ( ( state->as_recorded & ACL_STATE_RECORDED_NV ) &&
-					val == NULL )
-				{
-					return state->as_result;
+			if ( ( state->as_recorded & ACL_STATE_RECORDED_NV ) &&
+				val == NULL )
+			{
+				return state->as_result;
 
-				} else if ( ( state->as_recorded & ACL_STATE_RECORDED_VD ) &&
-					val != NULL && state->as_vd_acl == NULL )
-				{
-					return state->as_result;
-				}
 			}
-			st_same_attr = 1;
 		} else {
 			*state = state_init;
 		}
-
-		state->as_vd_ad = desc;
 	}
 
 	Debug( LDAP_DEBUG_ACL,
@@ -406,14 +392,12 @@
 		op->o_bd = LDAP_STAILQ_FIRST( &backendDB );
 		be_null = 1;
 
-#ifdef LDAP_DEVEL
-		/*
-		 * FIXME: experimental; use first backend rules
-		 * iff there is no global_acl (ITS#3100) */
+		/* FIXME: experimental; use first backend rules
+		 * iff there is no global_acl (ITS#3100)
+		 */
 		if ( frontendDB->be_acl != NULL ) {
 			op->o_bd = frontendDB;
 		}
-#endif /* LDAP_DEVEL */
 	}
 	assert( op->o_bd != NULL );
 
@@ -458,290 +442,14 @@
 			state->as_result = ret;
 		}
 		state->as_recorded |= ACL_STATE_RECORDED;
+		state->as_vd_ad = desc;
 	}
 	if ( be_null ) op->o_bd = NULL;
 	if ( maskp ) ACL_PRIV_ASSIGN( *maskp, mask );
 	return ret;
 }
 
-#else /* !SLAP_OVERLAY_ACCESS */
 
-int
-access_allowed_mask(
-	Operation		*op,
-	Entry			*e,
-	AttributeDescription	*desc,
-	struct berval		*val,
-	slap_access_t		access,
-	AccessControlState	*state,
-	slap_mask_t		*maskp )
-{
-	int				ret = 1;
-	int				count;
-	AccessControl			*a = NULL;
-	Backend				*be;
-	int				be_null = 0;
-
-#ifdef LDAP_DEBUG
-	char				accessmaskbuf[ACCESSMASK_MAXLEN];
-#endif
-	slap_mask_t			mask;
-	slap_control_t			control;
-	slap_access_t			access_level;
-	const char			*attr;
-	regmatch_t			matches[MAXREMATCHES];
-	int				st_same_attr = 0;
-	static AccessControlState	state_init = ACL_STATE_INIT;
-
-	assert( e != NULL );
-	assert( desc != NULL );
-
-	access_level = ACL_LEVEL( access );
-
-	assert( access_level > ACL_NONE );
-	if ( maskp ) ACL_INVALIDATE( *maskp );
-
-	attr = desc->ad_cname.bv_val;
-
-	assert( attr != NULL );
-
-	if ( op ) {
-		if ( op->o_is_auth_check &&
-			( access_level == ACL_SEARCH || access_level == ACL_READ ) )
-		{
-			access = ACL_AUTH;
-
-		} else if ( get_manageDIT( op ) && access_level == ACL_WRITE &&
-			desc == slap_schema.si_ad_entry )
-		{
-			access = ACL_MANAGE;
-		}
-	}
-
-	if ( state ) {
-		if ( state->as_vd_ad == desc ) {
-			if ( state->as_recorded ) {
-				if ( ( state->as_recorded & ACL_STATE_RECORDED_NV ) &&
-					val == NULL )
-				{
-					return state->as_result;
-
-				} else if ( ( state->as_recorded & ACL_STATE_RECORDED_VD ) &&
-					val != NULL && state->as_vd_acl == NULL )
-				{
-					return state->as_result;
-				}
-			}
-			st_same_attr = 1;
-		} else {
-			*state = state_init;
-		}
-
-		state->as_vd_ad=desc;
-	}
-
-	Debug( LDAP_DEBUG_ACL,
-		"=> access_allowed: %s access to \"%s\" \"%s\" requested\n",
-		access2str( access ), e->e_dn, attr );
-
-	if ( op == NULL ) {
-		/* no-op call */
-		goto done;
-	}
-
-	be = op->o_bd;
-	if ( be == NULL ) {
-		be = LDAP_STAILQ_FIRST(&backendDB);
-		be_null = 1;
-#ifdef LDAP_DEVEL
-		/*
-		 * FIXME: experimental; use first backend rules
-		 * iff there is no global_acl (ITS#3100) */
-		if ( frontendDB->be_acl == NULL ) 
-#endif
-		{
-			op->o_bd = be;
-		}
-	}
-	assert( be != NULL );
-
-	/* grant database root access */
-	if ( be_isroot( op ) ) {
-		Debug( LDAP_DEBUG_ACL, "<= root access granted\n", 0, 0, 0 );
-		if ( maskp ) {
-			mask = ACL_LVL_MANAGE;
-		}
-
-		goto done;
-	}
-
-	/*
-	 * no-user-modification operational attributes are ignored
-	 * by ACL_WRITE checking as any found here are not provided
-	 * by the user
-	 *
-	 * NOTE: but they are not ignored for ACL_MANAGE, because
-	 * if we get here it means a non-root user is trying to 
-	 * manage data, so we need to check its privileges.
-	 */
-	if ( access_level == ACL_WRITE && is_at_no_user_mod( desc->ad_type )
-		&& desc != slap_schema.si_ad_entry
-		&& desc != slap_schema.si_ad_children )
-	{
-		Debug( LDAP_DEBUG_ACL, "NoUserMod Operational attribute:"
-			" %s access granted\n",
-			attr, 0, 0 );
-		goto done;
-	}
-
-	/* use backend default access if no backend acls */
-	if ( be->be_acl == NULL ) {
-		Debug( LDAP_DEBUG_ACL,
-			"=> access_allowed: backend default %s "
-			"access %s to \"%s\"\n",
-			access2str( access ),
-			be->be_dfltaccess >= access_level ? "granted" : "denied",
-			op->o_dn.bv_val ? op->o_dn.bv_val : "(anonymous)" );
-		ret = be->be_dfltaccess >= access_level;
-
-		if ( maskp ) {
-			int	i;
-
-			mask = ACL_PRIV_LEVEL;
-			for ( i = ACL_NONE; i <= be->be_dfltaccess; i++ ) {
-				mask |= ACL_ACCESS2PRIV( i );
-			}
-		}
-
-		goto done;
-
-#ifdef notdef
-	/* be is always non-NULL */
-	/* use global default access if no global acls */
-	} else if ( be == NULL && frontendDB->be_acl == NULL ) {
-		Debug( LDAP_DEBUG_ACL,
-			"=> access_allowed: global default %s access %s to \"%s\"\n",
-			access2str( access ),
-			frontendDB->be_dfltaccess >= access_level ?
-				"granted" : "denied", op->o_dn.bv_val );
-		ret = frontendDB->be_dfltaccess >= access_level;
-
-		if ( maskp ) {
-			int	i;
-
-			mask = ACL_PRIV_LEVEL;
-			for ( i = ACL_NONE; i <= global_default_access; i++ ) {
-				mask |= ACL_ACCESS2PRIV( i );
-			}
-		}
-
-		goto done;
-#endif
-	}
-
-	ret = 0;
-	control = ACL_BREAK;
-
-	if ( st_same_attr ) {
-		assert( state->as_vd_acl != NULL );
-
-		a = state->as_vd_acl;
-		count = state->as_vd_acl_count;
-		if ( !ACL_IS_INVALID( state->as_vd_acl_mask ) ) {
-			mask = state->as_vd_acl_mask;
-			AC_MEMCPY( matches, state->as_vd_acl_matches, sizeof(matches) );
-			goto vd_access;
-		}
-
-	} else {
-		if ( state ) state->as_vi_acl = NULL;
-		a = NULL;
-		ACL_INIT(mask);
-		count = 0;
-		memset( matches, '\0', sizeof(matches) );
-	}
-
-	while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
-		MAXREMATCHES, matches, state ) ) != NULL )
-	{
-		int i;
-
-		for ( i = 0; i < MAXREMATCHES && matches[i].rm_so > 0; i++ ) {
-			Debug( LDAP_DEBUG_ACL, "=> match[%d]: %d %d ", i,
-				(int)matches[i].rm_so, (int)matches[i].rm_eo );
-			if ( matches[i].rm_so <= matches[0].rm_eo ) {
-				int n;
-				for ( n = matches[i].rm_so; n < matches[i].rm_eo; n++ ) {
-					Debug( LDAP_DEBUG_ACL, "%c", e->e_ndn[n], 0, 0 );
-				}
-			}
-			Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );
-		}
-
-		if ( state ) {
-			if ( state->as_vi_acl == a &&
-				( state->as_recorded & ACL_STATE_RECORDED_NV ) )
-			{
-				Debug( LDAP_DEBUG_ACL,
-					"access_allowed: result from state (%s)\n",
-					attr, 0, 0 );
-				ret = state->as_result;
-				goto done;
-			} else {
-				Debug( LDAP_DEBUG_ACL,
-					"access_allowed: no res from state (%s)\n",
-					attr, 0, 0 );
-			}
-		}
-
-vd_access:
-		control = slap_acl_mask( a, &mask, op,
-			e, desc, val, MAXREMATCHES, matches, count, state );
-
-		if ( control != ACL_BREAK ) {
-			break;
-		}
-
-		memset( matches, '\0', sizeof(matches) );
-	}
-
-	if ( ACL_IS_INVALID( mask ) ) {
-		Debug( LDAP_DEBUG_ACL,
-			"=> access_allowed: \"%s\" (%s) invalid!\n",
-			e->e_dn, attr, 0 );
-		ACL_INIT(mask);
-
-	} else if ( control == ACL_BREAK ) {
-		Debug( LDAP_DEBUG_ACL,
-			"=> access_allowed: no more rules\n", 0, 0, 0 );
-
-		goto done;
-	}
-
-	Debug( LDAP_DEBUG_ACL,
-		"=> access_allowed: %s access %s by %s\n",
-		access2str( access ),
-		ACL_GRANT(mask, access) ? "granted" : "denied",
-		accessmask2str( mask, accessmaskbuf, 1 ) );
-
-	ret = ACL_GRANT(mask, access);
-
-done:
-	if ( state != NULL ) {
-		/* If not value-dependent, save ACL in case of more attrs */
-		if ( !( state->as_recorded & ACL_STATE_RECORDED_VD ) ) {
-			state->as_vi_acl = a;
-			state->as_result = ret;
-		}
-		state->as_recorded |= ACL_STATE_RECORDED;
-	}
-	if ( be_null ) op->o_bd = NULL;
-	if ( maskp ) *maskp = mask;
-	return ret;
-}
-
-#endif /* SLAP_OVERLAY_ACCESS */
-
 /*
  * slap_acl_get - return the acl applicable to entry e, attribute
  * attr.  the acl returned is suitable for use in subsequent calls to
@@ -789,7 +497,7 @@
 
 	dnlen = e->e_nname.bv_len;
 
-	for ( ; a != NULL; a = a->acl_next ) {
+	for ( ; a != NULL; prev = a, a = a->acl_next ) {
 		(*count) ++;
 
 		if ( a->acl_dn_pat.bv_len || ( a->acl_dn_style != ACL_STYLE_REGEX )) {
@@ -860,11 +568,8 @@
 
 			if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) {
 				state->as_recorded |= ACL_STATE_RECORDED_VD;
-				state->as_vd_acl = a;
-				state->as_vd_acl_count = *count;
-				state->as_vd_access = a->acl_access;
-				state->as_vd_access_count = 1;
-				ACL_INVALIDATE( state->as_vd_acl_mask );
+				state->as_vd_acl = prev;
+				state->as_vd_acl_count = *count - 1;
 			}
 
 			if ( a->acl_attrval_style == ACL_STYLE_REGEX ) {
@@ -949,17 +654,13 @@
 
 /*
  * Record value-dependent access control state
-*/
- #define ACL_RECORD_VALUE_STATE do { \
-			if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { \
-				state->as_recorded |= ACL_STATE_RECORDED_VD; \
-				state->as_vd_acl = a; \
-				AC_MEMCPY( state->as_vd_acl_matches, matches, \
-					sizeof( state->as_vd_acl_matches )) ; \
-				state->as_vd_acl_count = count; \
-				state->as_vd_access = b; \
-				state->as_vd_access_count = i; \
-			}\
+ */
+#define ACL_RECORD_VALUE_STATE do { \
+		if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { \
+			state->as_recorded |= ACL_STATE_RECORDED_VD; \
+			state->as_vd_acl = a; \
+			state->as_vd_acl_count = count; \
+		} \
 	} while( 0 )
 
 static int
@@ -1273,11 +974,10 @@
 		at != NULL;
 		at = attrs_find( at->a_next, bdn->a_at ) )
 	{
-		if ( value_find_ex( bdn->a_at,
+		if ( attr_valfind( at,
 			SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
 				SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-			at->a_nvals,
-			&bv, op->o_tmpmemctx ) == 0 )
+			&bv, NULL, op->o_tmpmemctx ) == 0 )
 		{
 			/* found it */
 			match = 1;
@@ -1310,7 +1010,7 @@
 			return 1;
 
 		ACL_RECORD_VALUE_STATE;
-		
+
 		/* this is a self clause, check if the target is an
 		 * attribute.
 		 */
@@ -1382,17 +1082,9 @@
 		accessmask2str( *mask, accessmaskbuf, 1 ) );
 
 
-	if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD )
-		&& state->as_vd_acl == a )
-	{
-		b = state->as_vd_access;
-		i = state->as_vd_access_count;
+	b = a->acl_access;
+	i = 1;
 
-	} else {
-		b = a->acl_access;
-		i = 1;
-	}
-
 	for ( ; b != NULL; b = b->a_next, i++ ) {
 		slap_mask_t oldmask, modmask;
 
@@ -1415,7 +1107,7 @@
 			 */
 
 			if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches,
-					&b->a_dn, &op->o_ndn ) )
+				&b->a_dn, &op->o_ndn ) )
 			{
 				continue;
 			}
@@ -1446,7 +1138,7 @@
 			}
 
 			if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches,
-					&b->a_realdn, &ndn ) )
+				&b->a_realdn, &ndn ) )
 			{
 				continue;
 			}
@@ -1629,6 +1321,50 @@
 						if ( (addr & b->a_peername_mask) != b->a_peername_addr )
 							continue;
 
+#ifdef LDAP_PF_INET6
+					/* extract IPv6 and try exact match */
+					} else if ( b->a_peername_style == ACL_STYLE_IPV6 ) {
+						char		*port;
+						char		buf[] = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+						struct berval	ip;
+						struct in6_addr	addr;
+						int		port_number = -1;
+						
+						if ( strncasecmp( op->o_conn->c_peer_name.bv_val, 
+									acl_bv_ipv6_eq.bv_val,
+									acl_bv_ipv6_eq.bv_len ) != 0 ) 
+							continue;
+
+						ip.bv_val = op->o_conn->c_peer_name.bv_val + acl_bv_ipv6_eq.bv_len;
+						ip.bv_len = op->o_conn->c_peer_name.bv_len - acl_bv_ipv6_eq.bv_len;
+
+						port = strrchr( ip.bv_val, ']' );
+						if ( port ) {
+							ip.bv_len = port - ip.bv_val;
+							++port;
+							if ( port[0] == ':' && lutil_atoi( &port_number, ++port ) != 0 )
+								continue;
+						}
+						
+						/* the port check can be anticipated here */
+						if ( b->a_peername_port != -1 && port_number != b->a_peername_port )
+							continue;
+						
+						/* address longer than expected? */
+						if ( ip.bv_len >= sizeof(buf) )
+							continue;
+
+						AC_MEMCPY( buf, ip.bv_val, ip.bv_len );
+						buf[ ip.bv_len ] = '\0';
+
+						if ( inet_pton( AF_INET6, buf, &addr ) != 1 )
+							continue;
+
+						/* check mask */
+						if ( !slap_addr6_mask( &addr, &b->a_peername_mask6, &b->a_peername_addr6 ) )
+							continue;
+#endif /* LDAP_PF_INET6 */
+
 #ifdef LDAP_PF_LOCAL
 					/* extract path and try exact match */
 					} else if ( b->a_peername_style == ACL_STYLE_PATH ) {
@@ -1930,7 +1666,7 @@
 
 			/* must have DN syntax */
 			if ( desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName &&
-					!is_at_syntax( desc->ad_type, SLAPD_NAMEUID_SYNTAX )) continue;
+				!is_at_syntax( desc->ad_type, SLAPD_NAMEUID_SYNTAX )) continue;
 
 			/* check if the target is an attribute. */
 			if ( val == NULL ) continue;
@@ -1944,12 +1680,13 @@
 			 * is the op dn.
 			 */
 			rc = value_match( &match, desc,
-					desc->ad_type->sat_equality, 0,
-					val, &op->o_ndn, &dummy );
+				desc->ad_type->sat_equality, 0,
+				val, &op->o_ndn, &dummy );
 			/* on match error or no match, fail the ACL clause */
 			if ( rc != LDAP_SUCCESS || match != 0 )
 				continue;
 		}
+
 #ifdef SLAP_DYNACL
 		if ( b->a_dynacl ) {
 			slap_dynacl_t	*da;
@@ -1983,7 +1720,8 @@
 				Debug( LDAP_DEBUG_ACL, "    <= check a_dynacl: %s\n",
 					da->da_name, 0, 0 );
 
-				(void)( *da->da_mask )( da->da_private, op, e, desc, val, nmatch, matches, &grant, &deny );
+				(void)da->da_mask( da->da_private, op, e, desc,
+					val, nmatch, matches, &grant, &deny );
 
 				tgrant |= grant;
 				tdeny |= deny;
@@ -2017,169 +1755,7 @@
 			}
 
 		} else
-#else /* !SLAP_DYNACL */
-
-		/* NOTE: this entire block can be eliminated when SLAP_DYNACL
-		 * moves outside of LDAP_DEVEL */
-#ifdef SLAPD_ACI_ENABLED
-		if ( b->a_aci_at != NULL ) {
-			Attribute	*at;
-			slap_access_t	grant, deny, tgrant, tdeny;
-			struct berval	parent_ndn;
-			BerVarray	bvals = NULL;
-			int		ret, stop;
-#ifdef LDAP_DEBUG
-			char		accessmaskbuf1[ACCESSMASK_MAXLEN];
-#endif /* DEBUG */
-
-			Debug( LDAP_DEBUG_ACL, "    <= check a_aci_at: %s\n",
-				b->a_aci_at->ad_cname.bv_val, 0, 0 );
-
-			/* this case works different from the others above.
-			 * since aci's themselves give permissions, we need
-			 * to first check b->a_access_mask, the ACL's access level.
-			 */
-
-			if ( BER_BVISEMPTY( &e->e_nname ) ) {
-				/* no ACIs in the root DSE */
-				continue;
-			}
-
-			/* first check if the right being requested
-			 * is allowed by the ACL clause.
-			 */
-			if ( ! ACL_GRANT( b->a_access_mask, *mask ) ) {
-				continue;
-			}
-			/* start out with nothing granted, nothing denied */
-			ACL_INIT(tgrant);
-			ACL_INIT(tdeny);
-
-			/* get the aci attribute */
-			at = attr_find( e->e_attrs, b->a_aci_at );
-			if ( at != NULL ) {
-#if 0
-				/* FIXME: this breaks acl caching;
-				 * see also ACL_RECORD_VALUE_STATE below */
-				ACL_RECORD_VALUE_STATE;
-#endif
-				/* the aci is an multi-valued attribute.  The
-				* rights are determined by OR'ing the individual
-				* rights given by the acis.
-				*/
-				for ( i = 0; !BER_BVISNULL( &at->a_nvals[i] ); i++ ) {
-					if ( aci_mask( op,
-						e, desc, val,
-						&at->a_nvals[i],
-						nmatch, matches,
-						&grant, &deny, SLAP_ACI_SCOPE_ENTRY ) != 0 )
-					{
-						tgrant |= grant;
-						tdeny |= deny;
-					}
-				}
-				Debug(LDAP_DEBUG_ACL, "<= aci_mask grant %s deny %s\n",
-					  accessmask2str(tgrant, accessmaskbuf, 1), 
-					  accessmask2str(tdeny, accessmaskbuf1, 1), 0);
-
-			}
-			/* If the entry level aci didn't contain anything valid for the 
-			 * current operation, climb up the tree and evaluate the
-			 * acis with scope set to subtree
-			 */
-			if ( (tgrant == ACL_PRIV_NONE) && (tdeny == ACL_PRIV_NONE) ) {
-				dnParent( &e->e_nname, &parent_ndn );
-				while ( !BER_BVISEMPTY( &parent_ndn ) ) {
-					Debug(LDAP_DEBUG_ACL, "checking ACI of %s\n", parent_ndn.bv_val, 0, 0);
-					ret = backend_attribute(op, NULL, &parent_ndn, b->a_aci_at, &bvals, ACL_AUTH);
-					switch(ret){
-					case LDAP_SUCCESS :
-						stop = 0;
-						if (!bvals){
-							break;
-						}
-
-						for ( i = 0; !BER_BVISNULL( &bvals[i] ); i++ ) {
-#if 0
-							/* FIXME: this breaks acl caching;
-							 * see also ACL_RECORD_VALUE_STATE above */
-							ACL_RECORD_VALUE_STATE;
-#endif
-							if ( aci_mask( op, e, desc, val, &bvals[i],
-									nmatch, matches,
-									&grant, &deny, SLAP_ACI_SCOPE_CHILDREN ) != 0 )
-							{
-								tgrant |= grant;
-								tdeny |= deny;
-								/* evaluation stops as soon as either a "deny" or a 
-								 * "grant" directive matches.
-								 */
-								if( (tgrant != ACL_PRIV_NONE) || (tdeny != ACL_PRIV_NONE) ){
-									stop = 1;
-								}
-							}
-							Debug(LDAP_DEBUG_ACL, "<= aci_mask grant %s deny %s\n", 
-								accessmask2str(tgrant, accessmaskbuf, 1),
-								accessmask2str(tdeny, accessmaskbuf1, 1), 0);
-						}
-						break;
-
-					case LDAP_NO_SUCH_ATTRIBUTE:
-						/* just go on if the aci-Attribute is not present in
-						 * the current entry 
-						 */
-						Debug(LDAP_DEBUG_ACL, "no such attribute\n", 0, 0, 0);
-						stop = 0;
-						break;
-
-					case LDAP_NO_SUCH_OBJECT:
-						/* We have reached the base object */
-						Debug(LDAP_DEBUG_ACL, "no such object\n", 0, 0, 0);
-						stop = 1;
-						break;
-
-					default:
-						stop = 1;
-						break;
-					}
-					if (stop){
-						break;
-					}
-					dnParent( &parent_ndn, &parent_ndn );
-				}
-			}
-
-
-			/* remove anything that the ACL clause does not allow */
-			tgrant &= b->a_access_mask & ACL_PRIV_MASK;
-			tdeny &= ACL_PRIV_MASK;
-
-			/* see if we have anything to contribute */
-			if( ACL_IS_INVALID(tgrant) && ACL_IS_INVALID(tdeny) ) { 
-				continue;
-			}
-
-			/* this could be improved by changing slap_acl_mask so that it can deal with
-			 * by clauses that return grant/deny pairs.  Right now, it does either
-			 * additive or subtractive rights, but not both at the same time.  So,
-			 * we need to combine the grant/deny pair into a single rights mask in
-			 * a smart way:	 if either grant or deny is "empty", then we use the
-			 * opposite as is, otherwise we remove any denied rights from the grant
-			 * rights mask and construct an additive mask.
-			 */
-			if (ACL_IS_INVALID(tdeny)) {
-				modmask = tgrant | ACL_PRIV_ADDITIVE;
-
-			} else if (ACL_IS_INVALID(tgrant)) {
-				modmask = tdeny | ACL_PRIV_SUBSTRACTIVE;
-
-			} else {
-				modmask = (tgrant & ~tdeny) | ACL_PRIV_ADDITIVE;
-			}
-
-		} else
-#endif /* SLAPD_ACI_ENABLED */
-#endif /* !SLAP_DYNACL */
+#endif /* SLAP_DYNACL */
 		{
 			modmask = b->a_access_mask;
 		}
@@ -2466,11 +2042,6 @@
 
 				a = attr_find( rs->sr_entry->e_attrs, desc );
 				if ( a != NULL ) {
-					int	i;
-
-					for ( i = 0; !BER_BVISNULL( &a->a_nvals[ i ] ); i++ )
-						;
-
 					bvalsp = a->a_nvals;
 				}
 			}
@@ -2501,7 +2072,6 @@
 	slap_callback		cb = { NULL, acl_set_cb_gather, NULL, NULL };
 	acl_set_gather_t	p = { 0 };
 	const char		*text = NULL;
-	static struct berval	defaultFilter_bv = BER_BVC( "(objectClass=*)" );
 
 	/* this routine needs to return the bervals instead of
 	 * plain strings, since syntax is not known.  It should
@@ -2534,7 +2104,7 @@
 		goto url_done;
 	}
 
-	op2.o_bd = select_backend( &op2.o_req_ndn, 0, 1 );
+	op2.o_bd = select_backend( &op2.o_req_ndn, 1 );
 	if ( ( op2.o_bd == NULL ) || ( op2.o_bd->be_search == NULL ) ) {
 		rc = LDAP_NO_SUCH_OBJECT;
 		goto url_done;
@@ -2544,16 +2114,17 @@
 	if ( ludp->lud_filter ) {
 		ber_str2bv_x( ludp->lud_filter, 0, 0, &op2.ors_filterstr,
 				cp->asc_op->o_tmpmemctx );
+		op2.ors_filter = str2filter_x( cp->asc_op, op2.ors_filterstr.bv_val );
+		if ( op2.ors_filter == NULL ) {
+			rc = LDAP_PROTOCOL_ERROR;
+			goto url_done;
+		}
 		
 	} else {
-		op2.ors_filterstr = defaultFilter_bv;
+		op2.ors_filterstr = *slap_filterstr_objectClass_pres;
+		op2.ors_filter = (Filter *)slap_filter_objectClass_pres;
 	}
 
-	op2.ors_filter = str2filter_x( cp->asc_op, op2.ors_filterstr.bv_val );
-	if ( op2.ors_filter == NULL ) {
-		rc = LDAP_PROTOCOL_ERROR;
-		goto url_done;
-	}
 
 	/* Grab the scope */
 	op2.ors_scope = ludp->lud_scope;
@@ -2609,7 +2180,7 @@
 	}
 
 url_done:;
-	if ( op2.ors_filter ) {
+	if ( op2.ors_filter && op2.ors_filter != slap_filter_objectClass_pres ) {
 		filter_free_x( cp->asc_op, op2.ors_filter );
 	}
 	if ( !BER_BVISNULL( &op2.o_req_ndn ) ) {
@@ -2679,7 +2250,7 @@
 	} else {
 		struct berval		subjdn, ndn = BER_BVNULL;
 		struct berval		setat;
-		BerVarray		bvals=NULL;
+		BerVarray		bvals = NULL;
 		const char		*text;
 		AttributeDescription	*desc = NULL;
 
@@ -2790,13 +2361,12 @@
  * statically built-in dynamic ACL initialization
  */
 static int (*acl_init_func[])( void ) = {
-#ifdef SLAPD_ACI_ENABLED
 #ifdef SLAP_DYNACL
+	/* TODO: remove when ACI will only be dynamic */
+#if SLAPD_ACI_ENABLED == SLAPD_MOD_STATIC
 	dynacl_aci_init,
-#else /* !SLAP_DYNACL */
-	aci_init,
-#endif /* !SLAP_DYNACL */
 #endif /* SLAPD_ACI_ENABLED */
+#endif /* SLAP_DYNACL */
 
 	NULL
 };

Modified: openldap/trunk/servers/slapd/aclparse.c
===================================================================
--- openldap/trunk/servers/slapd/aclparse.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/aclparse.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* aclparse.c - routines to parse and check acl's */
-/* $OpenLDAP: pkg/ldap/servers/slapd/aclparse.c,v 1.145.2.21 2007/01/02 21:43:53 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/aclparse.c,v 1.198.2.4 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -52,12 +52,14 @@
 	"users",
 	"self",
 	"ip",
+	"ipv6",
 	"path",
 	NULL
 };
 
 static void		split(char *line, int splitchar, char **left, char **right);
 static void		access_append(Access **l, Access *a);
+static void		access_free( Access *a );
 static int		acl_usage(void);
 
 static void		acl_regex_normalized_dn(const char *src, struct berval *pat);
@@ -327,12 +329,11 @@
 	int		i;
 	char		*left, *right, *style;
 	struct berval	bv;
-	AccessControl	*a;
-	Access	*b;
+	AccessControl	*a = NULL;
+	Access	*b = NULL;
 	int rc;
 	const char *text;
 
-	a = NULL;
 	for ( i = 1; i < argc; i++ ) {
 		/* to clause - select which entries are protected */
 		if ( strcasecmp( argv[i], "to" ) == 0 ) {
@@ -340,7 +341,7 @@
 				Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 					"only one to clause allowed in access line\n",
 				    fname, lineno, 0 );
-				return acl_usage();
+				goto fail;
 			}
 			a = (AccessControl *) ch_calloc( 1, sizeof(AccessControl) );
 			for ( ++i; i < argc; i++ ) {
@@ -357,7 +358,7 @@
 							"%s: line %d: dn pattern"
 							" already specified in to clause.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					ber_str2bv( "*", STRLENOF( "*" ), 1, &a->acl_dn_pat );
@@ -371,7 +372,7 @@
 					Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 						"missing \"=\" in \"%s\" in to clause\n",
 					    fname, lineno, left );
-					return acl_usage();
+					goto fail;
 				}
 
 				if ( strcasecmp( left, "dn" ) == 0 ) {
@@ -382,7 +383,7 @@
 							"%s: line %d: dn pattern"
 							" already specified in to clause.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( style == NULL || *style == '\0' ||
@@ -440,7 +441,7 @@
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"unknown dn style \"%s\" in to clause\n",
 						    fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					continue;
@@ -451,7 +452,7 @@
 						Debug( LDAP_DEBUG_ANY,
 				"%s: line %d: bad filter \"%s\" in to clause\n",
 						    fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 
 				} else if ( strcasecmp( left, "attr" ) == 0		/* TOLERATED */
@@ -471,7 +472,7 @@
 						Debug( LDAP_DEBUG_ANY,
 				"%s: line %d: unknown attr \"%s\" in to clause\n",
 						    fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 
 				} else if ( strncasecmp( left, "val", 3 ) == 0 ) {
@@ -482,14 +483,14 @@
 						Debug( LDAP_DEBUG_ANY,
 				"%s: line %d: attr val already specified in to clause.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 					if ( a->acl_attrs == NULL || !BER_BVISEMPTY( &a->acl_attrs[1].an_name ) )
 					{
 						Debug( LDAP_DEBUG_ANY,
 				"%s: line %d: attr val requires a single attribute.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					ber_str2bv( right, 0, 0, &bv );
@@ -505,7 +506,7 @@
 							Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 								"invalid matching rule \"%s\".\n",
 								fname, lineno, mr );
-							return acl_usage();
+							goto fail;
 						}
 
 						if( !mr_usable_with_at( a->acl_attrval_mr, a->acl_attrs[ 0 ].an_desc->ad_type ) )
@@ -520,7 +521,7 @@
 
 							Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
 								fname, lineno, buf );
-							return acl_usage();
+							goto fail;
 						}
 					}
 					
@@ -540,7 +541,7 @@
 
 								Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
 									fname, lineno, buf );
-								return acl_usage();
+								goto fail;
 							}
 							a->acl_attrval_style = ACL_STYLE_REGEX;
 
@@ -571,25 +572,16 @@
 								} else {
 									char	buf[ SLAP_TEXT_BUFLEN ];
 
-									/* FIXME: should be an error */
-
 									snprintf( buf, sizeof( buf ),
-										"unknown val.<style> \"%s\" "
-										"for attributeType \"%s\" with DN syntax"
-#ifndef SLAPD_CONF_UNKNOWN_BAILOUT
-										"; using \"base\""
-#endif /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
-										SLAPD_CONF_UNKNOWN_IGNORED ".",
+										"unknown val.<style> \"%s\" for attributeType \"%s\" "
+											"with DN syntax.",
 										style,
 										a->acl_attrs[0].an_desc->ad_cname.bv_val );
 
 									Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, 
 										"%s: line %d: %s\n",
 										fname, lineno, buf );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-									return acl_usage();
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
-									a->acl_attrval_style = ACL_STYLE_BASE;
+									goto fail;
 								}
 
 								rc = dnNormalize( 0, NULL, NULL, &bv, &a->acl_attrval, NULL );
@@ -605,29 +597,19 @@
 									Debug( LDAP_DEBUG_ANY, 
 										"%s: line %d: %s\n",
 										fname, lineno, buf );
-									return acl_usage();
+									goto fail;
 								}
 
 							} else {
 								char	buf[ SLAP_TEXT_BUFLEN ];
 
-								/* FIXME: should be an error */
-
 								snprintf( buf, sizeof( buf ),
-									"unknown val.<style> \"%s\" "
-									"for attributeType \"%s\""
-#ifndef SLAPD_CONF_UNKNOWN_BAILOUT
-									"; using \"exact\""
-#endif /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
-									SLAPD_CONF_UNKNOWN_IGNORED ".",
+									"unknown val.<style> \"%s\" for attributeType \"%s\".",
 									style, a->acl_attrs[0].an_desc->ad_cname.bv_val );
 								Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, 
 									"%s: line %d: %s\n",
 									fname, lineno, buf );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-								return acl_usage();
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
-								a->acl_attrval_style = ACL_STYLE_BASE;
+								goto fail;
 							}
 						}
 					}
@@ -648,7 +630,7 @@
 							Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 								"attr \"%s\" does not have an EQUALITY matching rule.\n",
 								fname, lineno, a->acl_attrs[ 0 ].an_name.bv_val );
-							return acl_usage();
+							goto fail;
 						}
 
 						rc = asserted_value_validate_normalize(
@@ -668,7 +650,7 @@
 								a->acl_attrs[ 0 ].an_name.bv_val, rc, text );
 							Debug( LDAP_DEBUG_ANY, "%s: line %d: %s.\n",
 								fname, lineno, buf );
-							return acl_usage();
+							goto fail;
 						}
 					}
 
@@ -676,7 +658,7 @@
 					Debug( LDAP_DEBUG_ANY,
 						"%s: line %d: expecting <what> got \"%s\"\n",
 					    fname, lineno, left );
-					return acl_usage();
+					goto fail;
 				}
 			}
 
@@ -698,7 +680,7 @@
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: bad DN \"%s\" in to DN clause\n",
 							fname, lineno, a->acl_dn_pat.bv_val );
-						return acl_usage();
+						goto fail;
 					}
 					free( a->acl_dn_pat.bv_val );
 					a->acl_dn_pat = bv;
@@ -716,7 +698,7 @@
 							right, err );
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
 							fname, lineno, buf );
-						return acl_usage();
+						goto fail;
 					}
 				}
 			}
@@ -727,24 +709,24 @@
 				Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 					"to clause required before by clause in access line\n",
 					fname, lineno, 0 );
-				return acl_usage();
+				goto fail;
 			}
 
 			/*
 			 * by clause consists of <who> and <access>
 			 */
 
-			b = (Access *) ch_calloc( 1, sizeof(Access) );
-
-			ACL_INVALIDATE( b->a_access_mask );
-
 			if ( ++i == argc ) {
 				Debug( LDAP_DEBUG_ANY,
 					"%s: line %d: premature EOL: expecting <who>\n",
 					fname, lineno, 0 );
-				return acl_usage();
+				goto fail;
 			}
 
+			b = (Access *) ch_calloc( 1, sizeof(Access) );
+
+			ACL_INVALIDATE( b->a_access_mask );
+
 			/* get <who> */
 			for ( ; i < argc; i++ ) {
 				slap_style_t	sty = ACL_STYLE_REGEX;
@@ -769,13 +751,13 @@
 									"%s: line %d: premature eol: "
 									"expecting closing '}' in \"level{n}\"\n",
 									fname, lineno, 0 );
-								return acl_usage();
+								goto fail;
 							} else if ( p == style_level ) {
 								Debug( LDAP_DEBUG_ANY,
 									"%s: line %d: empty level "
 									"in \"level{n}\"\n",
 									fname, lineno, 0 );
-								return acl_usage();
+								goto fail;
 							}
 							p[0] = '\0';
 						}
@@ -809,7 +791,7 @@
 							"%s: line %d: unable to parse level "
 							"in \"level{n}\"\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					sty = ACL_STYLE_LEVEL;
@@ -823,24 +805,29 @@
 				} else if ( strcasecmp( style, "ip" ) == 0 ) {
 					sty = ACL_STYLE_IP;
 
+				} else if ( strcasecmp( style, "ipv6" ) == 0 ) {
+#ifndef LDAP_PF_INET6
+					Debug( LDAP_DEBUG_ANY,
+						"%s: line %d: IPv6 not supported\n",
+						fname, lineno, 0 );
+#endif /* ! LDAP_PF_INET6 */
+					sty = ACL_STYLE_IPV6;
+
 				} else if ( strcasecmp( style, "path" ) == 0 ) {
 					sty = ACL_STYLE_PATH;
 #ifndef LDAP_PF_LOCAL
 					Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,
 						"%s: line %d: "
-						"\"path\" style modifier is useless without local"
-						SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+						"\"path\" style modifier is useless without local.\n",
 						fname, lineno, 0 );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-					return acl_usage();
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
+					goto fail;
 #endif /* LDAP_PF_LOCAL */
 
 				} else {
 					Debug( LDAP_DEBUG_ANY,
 						"%s: line %d: unknown style \"%s\" in by clause\n",
 						fname, lineno, style );
-					return acl_usage();
+					goto fail;
 				}
 
 				if ( style_modifier &&
@@ -849,13 +836,9 @@
 					switch ( sty ) {
 					case ACL_STYLE_REGEX:
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
-							"\"regex\" style implies "
-							"\"expand\" modifier" 
-							SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+							"\"regex\" style implies \"expand\" modifier.\n",
 							fname, lineno, 0 );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-						return acl_usage();
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
+						goto fail;
 						break;
 
 					case ACL_STYLE_EXPAND:
@@ -872,15 +855,10 @@
 				if ( ( sty == ACL_STYLE_EXPAND || expand )
 						&& a->acl_dn_style != ACL_STYLE_REGEX )
 				{
-					Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, "%s: line %d: "
-						"\"expand\" style or modifier used "
-						"in conjunction with "
-						"a non-regex <what> clause"
-						SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+					Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, "%s: line %d: \"expand\" style "
+						"or modifier used in conjunction with a non-regex <what> clause.\n",
 						fname, lineno, 0 );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-						return acl_usage();
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
+						goto fail;
 				}
 
 				if ( strncasecmp( left, "real", STRLENOF( "real" ) ) == 0 ) {
@@ -891,7 +869,7 @@
 
 				if ( strcasecmp( left, "*" ) == 0 ) {
 					if ( is_realdn ) {
-						return acl_usage();
+						goto fail;
 					}
 
 					ber_str2bv( "*", STRLENOF( "*" ), 1, &bv );
@@ -969,7 +947,7 @@
 							"missing \"=\" in (or value after) \"%s\" "
 							"in by clause\n",
 							fname, lineno, left );
-						return acl_usage();
+						goto fail;
 
 					} else {
 						ber_str2bv( right, 0, 1, &bv );
@@ -984,7 +962,7 @@
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: dn pattern already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( sty != ACL_STYLE_REGEX &&
@@ -999,7 +977,7 @@
 							Debug( LDAP_DEBUG_ANY,
 								"%s: line %d: bad DN \"%s\" in by DN clause\n",
 								fname, lineno, bv.bv_val );
-							return acl_usage();
+							goto fail;
 						}
 						free( bv.bv_val );
 						if ( sty == ACL_STYLE_BASE
@@ -1022,11 +1000,11 @@
 						int	gotit = 0;
 
 						for ( exp = strchr( bdn->a_pat.bv_val, '$' );
-								exp && (ber_len_t)(exp - bdn->a_pat.bv_val)
-									< bdn->a_pat.bv_len;
-								exp = strchr( exp, '$' ) )
+							exp && (ber_len_t)(exp - bdn->a_pat.bv_val)
+								< bdn->a_pat.bv_len;
+							exp = strchr( exp, '$' ) )
 						{
-							if ( isdigit( exp[ 1 ] ) ) {
+							if ( isdigit( (unsigned char) exp[ 1 ] ) ) {
 								gotit = 1;
 								break;
 							}
@@ -1036,14 +1014,10 @@
 							bdn->a_expand = expand;
 
 						} else {
-							Debug( LDAP_DEBUG_ANY,
-								"%s: line %d: \"expand\" used "
-								"with no expansions in \"pattern\""
-								SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+							Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+								"\"expand\" used with no expansions in \"pattern\".\n",
 								fname, lineno, 0 );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-							return acl_usage();
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
+							goto fail;
 						} 
 					}
 					if ( sty == ACL_STYLE_SELF ) {
@@ -1055,7 +1029,7 @@
 								"%s: line %d: bad negative level \"%d\" "
 								"in by DN clause\n",
 								fname, lineno, level );
-							return acl_usage();
+							goto fail;
 						} else if ( level == 1 ) {
 							Debug( LDAP_DEBUG_ANY,
 								"%s: line %d: \"onelevel\" should be used "
@@ -1079,14 +1053,14 @@
 							"missing \"=\" in (or value after) \"%s\" "
 							"in by clause\n",
 							fname, lineno, left );
-						return acl_usage();
+						goto fail;
 					}
 
 					if( bdn->a_at != NULL ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: dnattr already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					rc = slap_str2ad( right, &bdn->a_at, &text );
@@ -1100,7 +1074,7 @@
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: %s\n",
 							fname, lineno, buf );
-						return acl_usage();
+						goto fail;
 					}
 
 
@@ -1119,7 +1093,7 @@
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: %s\n",
 							fname, lineno, buf );
-						return acl_usage();
+						goto fail;
 					}
 
 					if( bdn->a_at->ad_type->sat_equality == NULL ) {
@@ -1127,7 +1101,7 @@
 							"%s: line %d: dnattr \"%s\": "
 							"inappropriate matching (no EQUALITY)\n",
 							fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 
 					continue;
@@ -1136,6 +1110,7 @@
 				if ( strncasecmp( left, "group", STRLENOF( "group" ) ) == 0 ) {
 					char *name = NULL;
 					char *value = NULL;
+					char *attr_name = SLAPD_GROUP_ATTR;
 
 					switch ( sty ) {
 					case ACL_STYLE_REGEX:
@@ -1160,7 +1135,7 @@
 							"%s: line %d: "
 							"inappropriate style \"%s\" in by clause.\n",
 							fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || right[0] == '\0' ) {
@@ -1169,14 +1144,14 @@
 							"missing \"=\" in (or value after) \"%s\" "
 							"in by clause.\n",
 							fname, lineno, left );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !BER_BVISEMPTY( &b->a_group_pat ) ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: group pattern already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					/* format of string is
@@ -1204,7 +1179,7 @@
 							Debug( LDAP_DEBUG_ANY,
 								"%s: line %d: bad DN \"%s\".\n",
 								fname, lineno, right );
-							return acl_usage();
+							goto fail;
 						}
 					}
 
@@ -1217,7 +1192,7 @@
 								"%s: line %d: group objectclass "
 								"\"%s\" unknown.\n",
 								fname, lineno, value );
-							return acl_usage();
+							goto fail;
 						}
 
 					} else {
@@ -1228,7 +1203,7 @@
 								"%s: line %d: group default objectclass "
 								"\"%s\" unknown.\n",
 								fname, lineno, SLAPD_GROUP_CLASS );
-							return acl_usage();
+							goto fail;
 						}
 					}
 
@@ -1239,7 +1214,7 @@
 							"%s: line %d: group objectclass \"%s\" "
 							"is subclass of referral.\n",
 							fname, lineno, value );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( is_object_subclass( slap_schema.si_oc_alias,
@@ -1249,69 +1224,61 @@
 							"%s: line %d: group objectclass \"%s\" "
 							"is subclass of alias.\n",
 							fname, lineno, value );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( name && *name ) {
-						rc = slap_str2ad( name, &b->a_group_at, &text );
-
-						if( rc != LDAP_SUCCESS ) {
-							char	buf[ SLAP_TEXT_BUFLEN ];
-
-							snprintf( buf, sizeof( buf ),
-								"group \"%s\": %s.",
-								right, text );
-							Debug( LDAP_DEBUG_ANY,
-								"%s: line %d: %s\n",
-								fname, lineno, buf );
-							return acl_usage();
-						}
+						attr_name = name;
 						*--name = '/';
 
-					} else {
-						rc = slap_str2ad( SLAPD_GROUP_ATTR, &b->a_group_at, &text );
+					}
 
-						if ( rc != LDAP_SUCCESS ) {
-							char	buf[ SLAP_TEXT_BUFLEN ];
+					rc = slap_str2ad( attr_name, &b->a_group_at, &text );
+					if ( rc != LDAP_SUCCESS ) {
+						char	buf[ SLAP_TEXT_BUFLEN ];
 
-							snprintf( buf, sizeof( buf ),
-								"group \"%s\": %s.",
-								SLAPD_GROUP_ATTR, text );
-							Debug( LDAP_DEBUG_ANY,
-								"%s: line %d: %s\n",
-								fname, lineno, buf );
-							return acl_usage();
-						}
+						snprintf( buf, sizeof( buf ),
+							"group \"%s\": %s.",
+							right, text );
+						Debug( LDAP_DEBUG_ANY,
+							"%s: line %d: %s\n",
+							fname, lineno, buf );
+						goto fail;
 					}
 
 					if ( !is_at_syntax( b->a_group_at->ad_type,
-						SLAPD_DN_SYNTAX ) &&
-						!is_at_syntax( b->a_group_at->ad_type,
-						SLAPD_NAMEUID_SYNTAX ) &&
-						!is_at_subtype( b->a_group_at->ad_type, slap_schema.si_ad_labeledURI->ad_type ) )
+							SLAPD_DN_SYNTAX ) /* e.g. "member" */
+						&& !is_at_syntax( b->a_group_at->ad_type,
+							SLAPD_NAMEUID_SYNTAX ) /* e.g. memberUID */
+						&& !is_at_subtype( b->a_group_at->ad_type,
+							slap_schema.si_ad_labeledURI->ad_type ) /* e.g. memberURL */ )
 					{
 						char	buf[ SLAP_TEXT_BUFLEN ];
 
 						snprintf( buf, sizeof( buf ),
-							"group \"%s\": inappropriate syntax: %s.",
+							"group \"%s\" attr \"%s\": inappropriate syntax: %s; "
+							"must be " SLAPD_DN_SYNTAX " (DN), "
+							SLAPD_NAMEUID_SYNTAX " (NameUID) "
+							"or a subtype of labeledURI.",
 							right,
-							b->a_group_at->ad_type->sat_syntax_oid );
+							attr_name,
+							at_syntax( b->a_group_at->ad_type ) );
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: %s\n",
 							fname, lineno, buf );
-						return acl_usage();
+						goto fail;
 					}
 
 
 					{
 						int rc;
-						struct berval vals[2];
+						ObjectClass *ocs[2];
 
-						ber_str2bv( b->a_group_oc->soc_oid, 0, 0, &vals[0] );
-						BER_BVZERO( &vals[1] );
+						ocs[0] = b->a_group_oc;
+						ocs[1] = NULL;
 
 						rc = oc_check_allowed( b->a_group_at->ad_type,
-							vals, NULL );
+							ocs, NULL );
 
 						if( rc != 0 ) {
 							char	buf[ SLAP_TEXT_BUFLEN ];
@@ -1322,7 +1289,7 @@
 								b->a_group_oc->soc_oid );
 							Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
 								fname, lineno, buf );
-							return acl_usage();
+							goto fail;
 						}
 					}
 					continue;
@@ -1336,6 +1303,7 @@
 					case ACL_STYLE_EXPAND:
 						/* cheap replacement to regex for simple expansion */
 					case ACL_STYLE_IP:
+					case ACL_STYLE_IPV6:
 					case ACL_STYLE_PATH:
 						/* legal, peername specific */
 						break;
@@ -1344,7 +1312,7 @@
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"inappropriate style \"%s\" in by clause.\n",
 						    fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || right[0] == '\0' ) {
@@ -1352,14 +1320,14 @@
 							"missing \"=\" in (or value after) \"%s\" "
 							"in by clause.\n",
 							fname, lineno, left );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !BER_BVISEMPTY( &b->a_peername_pat ) ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"peername pattern already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					b->a_peername_style = sty;
@@ -1387,7 +1355,7 @@
 								Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 									"illegal peername address \"%s\".\n",
 									fname, lineno, addr );
-								return acl_usage();
+								goto fail;
 							}
 
 							b->a_peername_mask = (unsigned long)(-1);
@@ -1401,7 +1369,7 @@
 										"illegal peername address mask "
 										"\"%s\".\n",
 										fname, lineno, mask );
-									return acl_usage();
+									goto fail;
 								}
 							} 
 
@@ -1416,9 +1384,55 @@
 										"illegal peername port specification "
 										"\"{%s}\".\n",
 										fname, lineno, port );
-									return acl_usage();
+									goto fail;
 								}
 							}
+
+#ifdef LDAP_PF_INET6
+						} else if ( sty == ACL_STYLE_IPV6 ) {
+							char		*addr = NULL,
+									*mask = NULL,
+									*port = NULL;
+
+							split( right, '{', &addr, &port );
+							split( addr, '%', &addr, &mask );
+
+							if ( inet_pton( AF_INET6, addr, &b->a_peername_addr6 ) != 1 ) {
+								/* illegal address */
+								Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+									"illegal peername address \"%s\".\n",
+									fname, lineno, addr );
+								goto fail;
+							}
+
+							if ( mask == NULL ) {
+								mask = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+							}
+
+							if ( inet_pton( AF_INET6, mask, &b->a_peername_mask6 ) != 1 ) {
+								/* illegal mask */
+								Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+									"illegal peername address mask "
+									"\"%s\".\n",
+									fname, lineno, mask );
+								goto fail;
+							}
+
+							b->a_peername_port = -1;
+							if ( port ) {
+								char	*end = NULL;
+
+								b->a_peername_port = strtol( port, &end, 10 );
+								if ( end == port || end[0] != '}' ) {
+									/* illegal port */
+									Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+										"illegal peername port specification "
+										"\"{%s}\".\n",
+										fname, lineno, port );
+									goto fail;
+								}
+							}
+#endif /* LDAP_PF_INET6 */
 						}
 					}
 					continue;
@@ -1438,7 +1452,7 @@
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"inappropriate style \"%s\" in by clause\n",
 						    fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || right[0] == '\0' ) {
@@ -1446,14 +1460,14 @@
 							"missing \"=\" in (or value after) \"%s\" "
 							"in by clause\n",
 							fname, lineno, left );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !BER_BVISNULL( &b->a_sockname_pat ) ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"sockname pattern already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					b->a_sockname_style = sty;
@@ -1496,7 +1510,7 @@
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"inappropriate style \"%s\" in by clause.\n",
 						    fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || right[0] == '\0' ) {
@@ -1504,14 +1518,14 @@
 							"missing \"=\" in (or value after) \"%s\" "
 							"in by clause.\n",
 							fname, lineno, left );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !BER_BVISEMPTY( &b->a_domain_pat ) ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: domain pattern already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					b->a_domain_style = sty;
@@ -1543,7 +1557,7 @@
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"inappropriate style \"%s\" in by clause.\n",
 						    fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || right[0] == '\0' ) {
@@ -1551,14 +1565,14 @@
 							"missing \"=\" in (or value after) \"%s\" "
 							"in by clause.\n",
 							fname, lineno, left );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !BER_BVISEMPTY( &b->a_sockurl_pat ) ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: sockurl pattern already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					b->a_sockurl_style = sty;
@@ -1596,21 +1610,21 @@
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"inappropriate style \"%s\" in by clause.\n",
 							fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !BER_BVISEMPTY( &b->a_set_pat ) ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: set attribute already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || *right == '\0' ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: no set is defined.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					b->a_set_style = sty;
@@ -1623,11 +1637,18 @@
 				{
 					char		*name = NULL,
 							*opts = NULL;
-					
+
+#if 1 /* tolerate legacy "aci" <who> */
 					if ( strcasecmp( left, "aci" ) == 0 ) {
+						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+							"undocumented deprecated \"aci\" directive "
+							"is superseded by \"dynacl/aci\".\n",
+							fname, lineno, 0 );
 						name = "aci";
 						
-					} else if ( strncasecmp( left, "dynacl/", STRLENOF( "dynacl/" ) ) == 0 ) {
+					} else
+#endif /* tolerate legacy "aci" <who> */
+					if ( strncasecmp( left, "dynacl/", STRLENOF( "dynacl/" ) ) == 0 ) {
 						name = &left[ STRLENOF( "dynacl/" ) ];
 						opts = strchr( name, '/' );
 						if ( opts ) {
@@ -1641,102 +1662,48 @@
 							Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 								"unable to configure dynacl \"%s\".\n",
 								fname, lineno, name );
-							return acl_usage();
+							goto fail;
 						}
 
 						continue;
 					}
 				}
-#else /* ! SLAP_DYNACL */
+#endif /* SLAP_DYNACL */
 
-#ifdef SLAPD_ACI_ENABLED
-				if ( strcasecmp( left, "aci" ) == 0 ) {
-					if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) {
-						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
-							"inappropriate style \"%s\" in by clause.\n",
-						    fname, lineno, style );
-						return acl_usage();
-					}
-
-					if( b->a_aci_at != NULL ) {
-						Debug( LDAP_DEBUG_ANY,
-							"%s: line %d: ACI attribute already specified.\n",
-							fname, lineno, 0 );
-						return acl_usage();
-					}
-
-					if ( right != NULL && *right != '\0' ) {
-						rc = slap_str2ad( right, &b->a_aci_at, &text );
-
-						if( rc != LDAP_SUCCESS ) {
-							char	buf[ SLAP_TEXT_BUFLEN ];
-
-							snprintf( buf, sizeof( buf ),
-								"aci \"%s\": %s.",
-								right, text );
-							Debug( LDAP_DEBUG_ANY,
-								"%s: line %d: %s\n",
-								fname, lineno, buf );
-							return acl_usage();
-						}
-
-					} else {
-						b->a_aci_at = slap_ad_aci;
-					}
-
-					if( !is_at_syntax( b->a_aci_at->ad_type,
-						SLAPD_ACI_SYNTAX) )
-					{
-						char	buf[ SLAP_TEXT_BUFLEN ];
-
-						snprintf( buf, sizeof( buf ),
-							"ACI \"%s\": inappropriate syntax: %s.",
-							right,
-							b->a_aci_at->ad_type->sat_syntax_oid );
-						Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
-							fname, lineno, buf );
-						return acl_usage();
-					}
-
-					continue;
-				}
-#endif /* SLAPD_ACI_ENABLED */
-#endif /* ! SLAP_DYNACL */
-
 				if ( strcasecmp( left, "ssf" ) == 0 ) {
 					if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"inappropriate style \"%s\" in by clause.\n",
 						    fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( b->a_authz.sai_ssf ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: ssf attribute already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || *right == '\0' ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: no ssf is defined.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( lutil_atou( &b->a_authz.sai_ssf, right ) != 0 ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: unable to parse ssf value (%s).\n",
 							fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !b->a_authz.sai_ssf ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: invalid ssf value (%s).\n",
 							fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 					continue;
 				}
@@ -1746,35 +1713,35 @@
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"inappropriate style \"%s\" in by clause.\n",
 							fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( b->a_authz.sai_transport_ssf ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"transport_ssf attribute already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || *right == '\0' ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: no transport_ssf is defined.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( lutil_atou( &b->a_authz.sai_transport_ssf, right ) != 0 ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"unable to parse transport_ssf value (%s).\n",
 							fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !b->a_authz.sai_transport_ssf ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: invalid transport_ssf value (%s).\n",
 							fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 					continue;
 				}
@@ -1784,35 +1751,35 @@
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"inappropriate style \"%s\" in by clause.\n",
 							fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( b->a_authz.sai_tls_ssf ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"tls_ssf attribute already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || *right == '\0' ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: no tls_ssf is defined\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( lutil_atou( &b->a_authz.sai_tls_ssf, right ) != 0 ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"unable to parse tls_ssf value (%s).\n",
 							fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !b->a_authz.sai_tls_ssf ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: invalid tls_ssf value (%s).\n",
 							fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 					continue;
 				}
@@ -1822,35 +1789,35 @@
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"inappropriate style \"%s\" in by clause.\n",
 							fname, lineno, style );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( b->a_authz.sai_sasl_ssf ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"sasl_ssf attribute already specified.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( right == NULL || *right == '\0' ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: no sasl_ssf is defined.\n",
 							fname, lineno, 0 );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( lutil_atou( &b->a_authz.sai_sasl_ssf, right ) != 0 ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"unable to parse sasl_ssf value (%s).\n",
 							fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 
 					if ( !b->a_authz.sai_sasl_ssf ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: invalid sasl_ssf value (%s).\n",
 							fname, lineno, right );
-						return acl_usage();
+						goto fail;
 					}
 					continue;
 				}
@@ -1866,6 +1833,7 @@
 				/* out of arguments or plain stop */
 
 				ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE );
+				ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE);
 				b->a_type = ACL_STOP;
 
 				access_append( &a->acl_access, b );
@@ -1876,6 +1844,7 @@
 				/* plain continue */
 
 				ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE );
+				ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE);
 				b->a_type = ACL_CONTINUE;
 
 				access_append( &a->acl_access, b );
@@ -1886,6 +1855,7 @@
 				/* plain continue */
 
 				ACL_PRIV_ASSIGN(b->a_access_mask, ACL_PRIV_ADDITIVE);
+				ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE);
 				b->a_type = ACL_BREAK;
 
 				access_append( &a->acl_access, b );
@@ -1896,6 +1866,7 @@
 				/* we've gone too far */
 				--i;
 				ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE );
+				ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE);
 				b->a_type = ACL_STOP;
 
 				access_append( &a->acl_access, b );
@@ -1903,23 +1874,26 @@
 			}
 
 			/* get <access> */
-			if ( strncasecmp( left, "self", STRLENOF( "self" ) ) == 0 ) {
-				b->a_dn_self = 1;
-				ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[ STRLENOF( "self" ) ] ) );
+			{
+				char	*lleft = left;
 
-			} else if ( strncasecmp( left, "realself", STRLENOF( "realself" ) ) == 0 ) {
-				b->a_realdn_self = 1;
-				ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[ STRLENOF( "realself" ) ] ) );
+				if ( strncasecmp( left, "self", STRLENOF( "self" ) ) == 0 ) {
+					b->a_dn_self = 1;
+					lleft = &left[ STRLENOF( "self" ) ];
 
-			} else {
-				ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( left ) );
+				} else if ( strncasecmp( left, "realself", STRLENOF( "realself" ) ) == 0 ) {
+					b->a_realdn_self = 1;
+					lleft = &left[ STRLENOF( "realself" ) ];
+				}
+
+				ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( lleft ) );
 			}
 
 			if ( ACL_IS_INVALID( b->a_access_mask ) ) {
 				Debug( LDAP_DEBUG_ANY,
 					"%s: line %d: expecting <access> got \"%s\".\n",
 					fname, lineno, left );
-				return acl_usage();
+				goto fail;
 			}
 
 			b->a_type = ACL_STOP;
@@ -1944,43 +1918,36 @@
 			}
 
 			access_append( &a->acl_access, b );
+			b = NULL;
 
 		} else {
 			Debug( LDAP_DEBUG_ANY,
 				"%s: line %d: expecting \"to\" "
 				"or \"by\" got \"%s\"\n",
 				fname, lineno, argv[i] );
-			return acl_usage();
+			goto fail;
 		}
 	}
 
 	/* if we have no real access clause, complain and do nothing */
 	if ( a == NULL ) {
 		Debug( LDAP_DEBUG_ANY, "%s: line %d: "
-			"warning: no access clause(s) "
-			"specified in access line"
-			SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+			"warning: no access clause(s) specified in access line.\n",
 			fname, lineno, 0 );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-		return acl_usage();
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
+		goto fail;
 
 	} else {
 #ifdef LDAP_DEBUG
-		if ( ldap_debug & LDAP_DEBUG_ACL ) {
+		if ( slap_debug & LDAP_DEBUG_ACL ) {
 			print_acl( be, a );
 		}
 #endif
 	
 		if ( a->acl_access == NULL ) {
 			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
-				"warning: no by clause(s) "
-				"specified in access line"
-				SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+				"warning: no by clause(s) specified in access line.\n",
 				fname, lineno, 0 );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-			return acl_usage();
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
+			goto fail;
 		}
 
 		if ( be != NULL ) {
@@ -2036,6 +2003,11 @@
 	}
 
 	return 0;
+
+fail:
+	if ( b ) access_free( b );
+	if ( a ) acl_free( a );
+	return acl_usage();
 }
 
 char *
@@ -2215,7 +2187,10 @@
 			} else if( TOLOWER((unsigned char) str[i]) == 'd' ) {
 				ACL_PRIV_SET(mask, ACL_PRIV_DISCLOSE);
 
-			} else if( str[i] != '0' ) {
+			} else if( str[i] == '0' ) {
+				ACL_PRIV_SET(mask, ACL_PRIV_NONE);
+
+			} else {
 				ACL_INVALIDATE(mask);
 				return mask;
 			}
@@ -2283,18 +2258,14 @@
 			"\t[domain[.<domainstyle>]=<domain>] [sockurl[.<style>]=<url>]\n"
 #ifdef SLAP_DYNACL
 			"\t[dynacl/<name>[/<options>][.<dynstyle>][=<pattern>]]\n"
-#else /* ! SLAP_DYNACL */
-#ifdef SLAPD_ACI_ENABLED
-			"\t[aci[=<attrname>]]\n"
-#endif /* SLAPD_ACI_ENABLED */
-#endif /* ! SLAP_DYNACL */
+#endif /* SLAP_DYNACL */
 			"\t[ssf=<n>] [transport_ssf=<n>] [tls_ssf=<n>] [sasl_ssf=<n>]\n"
 		"<style> ::= exact | regex | base(Object)\n"
 		"<dnstyle> ::= base(Object) | one(level) | sub(tree) | children | "
 			"exact | regex\n"
 		"<attrstyle> ::= exact | regex | base(Object) | one(level) | "
 			"sub(tree) | children\n"
-		"<peernamestyle> ::= exact | regex | ip | path\n"
+		"<peernamestyle> ::= exact | regex | ip | ipv6 | path\n"
 		"<domainstyle> ::= exact | regex | base(Object) | sub(tree)\n"
 		"<access> ::= [[real]self]{<level>|<priv>}\n"
 		"<level> ::= none|disclose|auth|compare|search|read|{write|add|delete}|manage\n"
@@ -2462,6 +2433,14 @@
 			free( an->an_name.bv_val );
 		}
 		free( a->acl_attrs );
+
+		if ( a->acl_attrval_style == ACL_STYLE_REGEX ) {
+			regfree( &a->acl_attrval_re );
+		}
+
+		if ( !BER_BVISNULL( &a->acl_attrval ) ) {
+			ber_memfree( a->acl_attrval.bv_val );
+		}
 	}
 	for ( ; a->acl_access; a->acl_access = n ) {
 		n = a->acl_access->a_next;
@@ -2533,11 +2512,6 @@
 		return ACL_NONE;
 
 	} else if ( strcasecmp( str, "disclose" ) == 0 ) {
-#ifndef SLAP_ACL_HONOR_DISCLOSE
-		Debug( LDAP_DEBUG_ACL, "str2access: warning, "
-			"\"disclose\" privilege disabled.\n",
-		0, 0, 0 );
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 		return ACL_DISCLOSE;
 
 	} else if ( strcasecmp( str, "auth" ) == 0 ) {
@@ -2724,13 +2698,6 @@
 			}
 		}
 	}
-#else /* ! SLAP_DYNACL */
-#ifdef SLAPD_ACI_ENABLED
-	if ( b->a_aci_at != NULL ) {
-		ptr = lutil_strcopy( ptr, " aci=" );
-		ptr = lutil_strcopy( ptr, b->a_aci_at->ad_cname.bv_val );
-	}
-#endif
 #endif /* SLAP_DYNACL */
 
 	/* Security Strength Factors */

Modified: openldap/trunk/servers/slapd/ad.c
===================================================================
--- openldap/trunk/servers/slapd/ad.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/ad.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ad.c - routines for dealing with attribute descriptions */
-/* $OpenLDAP: pkg/ldap/servers/slapd/ad.c,v 1.74.2.16 2007/03/05 15:19:00 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/ad.c,v 1.95.2.3 2007/08/31 23:13:57 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -58,7 +58,7 @@
 	int           prefix;	/* NAME is a tag and range prefix */
 } Attr_option;
 
-static Attr_option lang_option = { { sizeof("lang-")-1, "lang-" }, 1 };
+static Attr_option lang_option = { BER_BVC("lang-"), 1 };
 
 /* Options sorted by name, and number of options */
 static Attr_option *options = &lang_option;
@@ -175,8 +175,9 @@
 	}
 
 	/* find valid base attribute type; parse in place */
-	memset( &desc, 0, sizeof( desc ) );
 	desc.ad_cname = *bv;
+	desc.ad_flags = 0;
+	BER_BVZERO( &desc.ad_tags );
 	name = bv->bv_val;
 	options = ber_bvchr( bv, ';' );
 	if ( options != NULL && (unsigned) ( options - name ) < bv->bv_len ) {
@@ -200,7 +201,6 @@
 	 * parse options in place
 	 */
 	ntags = 0;
-	memset( tags, 0, sizeof( tags ));
 	tagslen = 0;
 	optn = bv->bv_val + bv->bv_len;
 
@@ -213,8 +213,8 @@
 			*text = "zero length option is invalid";
 			return rtn;
 		
-		} else if ( optlen == sizeof("binary")-1 &&
-			strncasecmp( opt, "binary", sizeof("binary")-1 ) == 0 )
+		} else if ( optlen == STRLENOF("binary") &&
+			strncasecmp( opt, "binary", STRLENOF("binary") ) == 0 )
 		{
 			/* binary option */
 			if( slap_ad_is_binary( &desc ) ) {
@@ -356,10 +356,10 @@
 		if (desc.ad_tags.bv_len || desc.ad_flags != SLAP_DESC_NONE) {
 			dlen = desc.ad_type->sat_cname.bv_len + 1;
 			if (desc.ad_tags.bv_len) {
-				dlen += 1+desc.ad_tags.bv_len;
+				dlen += 1 + desc.ad_tags.bv_len;
 			}
-			if( slap_ad_is_binary( &desc ) ) {
-				dlen += sizeof(";binary")+desc.ad_tags.bv_len;
+			if ( slap_ad_is_binary( &desc ) ) {
+				dlen += 1 + STRLENOF(";binary") + desc.ad_tags.bv_len;
 			}
 		}
 
@@ -384,7 +384,7 @@
 				lp = NULL;
 				if( desc.ad_tags.bv_len ) {
 					lp = desc.ad_tags.bv_val;
-					while( strncasecmp(lp, "binary", sizeof("binary")-1) < 0
+					while( strncasecmp(lp, "binary", STRLENOF("binary")) < 0
 					       && (lp = strchr( lp, ';' )) != NULL )
 						++lp;
 					if( lp != desc.ad_tags.bv_val ) {
@@ -773,6 +773,24 @@
 	return LDAP_SUCCESS;
 }
 
+AttributeDescription *
+slap_bv2tmp_ad(
+	struct berval *bv,
+	void *memctx )
+{
+	AttributeDescription *ad =
+		 slap_sl_mfuncs.bmf_malloc( sizeof(AttributeDescription) +
+			bv->bv_len + 1, memctx );
+
+	ad->ad_cname.bv_val = (char *)(ad+1);
+	strncpy( ad->ad_cname.bv_val, bv->bv_val, bv->bv_len+1 );
+	ad->ad_cname.bv_len = bv->bv_len;
+	ad->ad_flags = SLAP_DESC_TEMPORARY;
+	ad->ad_type = slap_schema.si_at_undefined;
+
+	return ad;
+}
+
 static int
 undef_promote(
 	AttributeType	*at,
@@ -945,10 +963,8 @@
 	return( an );
 
 reterr:
-	for ( i = 0; an[i].an_name.bv_val; i++ ) {
-		free( an[i].an_name.bv_val );
-	}
-	free( an );
+	anlist_free( an, 1, NULL );
+
 	/*
 	 * overwrites input string
 	 * on error!
@@ -958,6 +974,24 @@
 	return NULL;
 }
 
+void
+anlist_free( AttributeName *an, int freename, void *ctx )
+{
+	if ( an == NULL ) {
+		return;
+	}
+
+	if ( freename ) {
+		int	i;
+
+		for ( i = 0; an[i].an_name.bv_val; i++ ) {
+			ber_memfree_x( an[i].an_name.bv_val, ctx );
+		}
+	}
+
+	ber_memfree_x( an, ctx );
+}
+
 char **anlist2charray_x( AttributeName *an, int dup, void *ctx )
 {
     char **attrs;
@@ -1115,7 +1149,7 @@
 		}
 		an = str2anlist( an, line, brkstr );
 		if ( an == NULL )
-			return NULL;
+			break;
 		lcur = line;
 	}
 	ch_free( line );

Modified: openldap/trunk/servers/slapd/add.c
===================================================================
--- openldap/trunk/servers/slapd/add.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/add.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/add.c,v 1.208.2.18 2007/01/03 08:50:41 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/add.c,v 1.244.2.4 2007/09/29 09:55:21 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -49,7 +49,9 @@
 	int		rc = 0;
 	int		freevals = 1;
 
-	Debug( LDAP_DEBUG_TRACE, "do_add\n", 0, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE, "%s do_add\n",
+		op->o_log_prefix, 0, 0 );
+
 	/*
 	 * Parse the add request.  It looks like this:
 	 *
@@ -64,27 +66,15 @@
 
 	/* get the name */
 	if ( ber_scanf( ber, "{m", /*}*/ &dn ) == LBER_ERROR ) {
-		Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_add: ber_scanf failed\n",
+			op->o_log_prefix, 0, 0 );
 		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
 		return SLAPD_DISCONNECT;
 	}
 
-	op->ora_e = (Entry *) ch_calloc( 1, sizeof(Entry) );
+	Debug( LDAP_DEBUG_ARGS, "%s do_add: dn (%s)\n",
+		op->o_log_prefix, dn.bv_val, 0 );
 
-	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
-		op->o_tmpmemctx );
-
-	if ( rs->sr_err != LDAP_SUCCESS ) {
-		Debug( LDAP_DEBUG_ANY, "do_add: invalid dn (%s)\n", dn.bv_val, 0, 0 );
-		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
-		goto done;
-	}
-
-	ber_dupbv( &op->ora_e->e_name, &op->o_req_dn );
-	ber_dupbv( &op->ora_e->e_nname, &op->o_req_ndn );
-
-	Debug( LDAP_DEBUG_ARGS, "do_add: dn (%s)\n", op->ora_e->e_dn, 0, 0 );
-
 	/* get the attrs */
 	for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
 	    tag = ber_next_element( ber, &len, last ) )
@@ -97,15 +87,16 @@
 		rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_values );
 
 		if ( rtag == LBER_ERROR ) {
-			Debug( LDAP_DEBUG_ANY, "do_add: decoding error\n", 0, 0, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s do_add: decoding error\n",
+				op->o_log_prefix, 0, 0 );
 			send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
 			rs->sr_err = SLAPD_DISCONNECT;
 			goto done;
 		}
 
 		if ( tmp.sml_values == NULL ) {
-			Debug( LDAP_DEBUG_ANY, "no values for type %s\n",
-				tmp.sml_type.bv_val, 0, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s do_add: no values for type %s\n",
+				op->o_log_prefix, tmp.sml_type.bv_val, 0 );
 			send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
 				"no values for attribute type" );
 			goto done;
@@ -125,26 +116,42 @@
 	}
 
 	if ( ber_scanf( ber, /*{*/ "}") == LBER_ERROR ) {
-		Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_add: ber_scanf failed\n",
+			op->o_log_prefix, 0, 0 );
 		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
 		rs->sr_err = SLAPD_DISCONNECT;
 		goto done;
 	}
 
 	if ( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
-		Debug( LDAP_DEBUG_ANY, "do_add: get_ctrls failed\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_add: get_ctrls failed\n",
+			op->o_log_prefix, 0, 0 );
 		goto done;
 	} 
 
+	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
+		op->o_tmpmemctx );
+
+	if ( rs->sr_err != LDAP_SUCCESS ) {
+		Debug( LDAP_DEBUG_ANY, "%s do_add: invalid dn (%s)\n",
+			op->o_log_prefix, dn.bv_val, 0 );
+		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
+		goto done;
+	}
+
+	op->ora_e = entry_alloc();
+	ber_dupbv( &op->ora_e->e_name, &op->o_req_dn );
+	ber_dupbv( &op->ora_e->e_nname, &op->o_req_ndn );
+
+	Statslog( LDAP_DEBUG_STATS, "%s ADD dn=\"%s\"\n",
+	    op->o_log_prefix, op->o_req_dn.bv_val, 0, 0, 0 );
+
 	if ( modlist == NULL ) {
 		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
 			"no attributes provided" );
 		goto done;
 	}
 
-	Statslog( LDAP_DEBUG_STATS, "%s ADD dn=\"%s\"\n",
-	    op->o_log_prefix, op->ora_e->e_name.bv_val, 0, 0, 0 );
-
 	if ( dn_match( &op->ora_e->e_nname, &slap_empty_bv ) ) {
 		/* protocolError may be a more appropriate error */
 		send_ldap_error( op, rs, LDAP_ALREADY_EXISTS,
@@ -157,7 +164,7 @@
 		goto done;
 	}
 
-	rs->sr_err = slap_mods_check( modlist, &rs->sr_text,
+	rs->sr_err = slap_mods_check( op, modlist, &rs->sr_text,
 		textbuf, textlen, NULL );
 
 	if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -180,6 +187,13 @@
 
 	op->o_bd = frontendDB;
 	rc = frontendDB->be_add( op, rs );
+
+#ifdef LDAP_X_TXN
+	if ( rc == LDAP_X_TXN_SPECIFY_OKAY ) {
+		/* skip cleanup */
+		return rc;
+	} else
+#endif
 	if ( rc == 0 ) {
 		if ( op->ora_e != NULL && op->o_private != NULL ) {
 			BackendDB	*bd = op->o_bd;
@@ -213,22 +227,18 @@
 int
 fe_op_add( Operation *op, SlapReply *rs )
 {
-	int		manageDSAit;
-	Modifications	*modlist = op->ora_modlist;
-	Modifications	**modtail = &modlist;
+	Modifications	**modtail = &op->ora_modlist;
 	int		rc = 0;
-	BackendDB *op_be, *bd = op->o_bd;
+	BackendDB	*op_be, *bd = op->o_bd;
 	char		textbuf[ SLAP_TEXT_BUFLEN ];
 	size_t		textlen = sizeof( textbuf );
 
-	manageDSAit = get_manageDSAit( op );
-
 	/*
 	 * We could be serving multiple database backends.  Select the
 	 * appropriate one, or send a referral to our "referral server"
 	 * if we don't hold it.
 	 */
-	op->o_bd = select_backend( &op->ora_e->e_nname, manageDSAit, 1 );
+	op->o_bd = select_backend( &op->ora_e->e_nname, 1 );
 	if ( op->o_bd == NULL ) {
 		op->o_bd = bd;
 		rs->sr_ref = referral_rewrite( default_referral,
@@ -242,10 +252,8 @@
 				ber_bvarray_free( rs->sr_ref );
 			}
 		} else {
-			op->o_bd = frontendDB;
 			send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
 				"no global superior knowledge" );
-			op->o_bd = NULL;
 		}
 		goto done;
 	}
@@ -253,7 +261,7 @@
 	/* If we've got a glued backend, check the real backend */
 	op_be = op->o_bd;
 	if ( SLAP_GLUE_INSTANCE( op->o_bd )) {
-		op->o_bd = select_backend( &op->ora_e->e_nname, manageDSAit, 0 );
+		op->o_bd = select_backend( &op->ora_e->e_nname, 0 );
 	}
 
 	/* check restrictions */
@@ -267,7 +275,7 @@
 		goto done;
 	}
 
-	rs->sr_err = slap_mods_obsolete_check( op, modlist,
+	rs->sr_err = slap_mods_obsolete_check( op, op->ora_modlist,
 		&rs->sr_text, textbuf, textlen );
 
 	if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -284,17 +292,13 @@
 	if ( op->o_bd->be_add ) {
 		/* do the update here */
 		int repl_user = be_isupdate( op );
-#ifndef SLAPD_MULTIMASTER
-		if ( !SLAP_SHADOW(op->o_bd) || repl_user )
-#endif
-		{
+		if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user ) {
 			int		update = !BER_BVISEMPTY( &op->o_bd->be_update_ndn );
-			slap_callback	cb = { NULL, slap_replog_cb, NULL, NULL };
 
 			op->o_bd = op_be;
 
 			if ( !update ) {
-				rs->sr_err = slap_mods_no_user_mod_check( op, modlist,
+				rs->sr_err = slap_mods_no_user_mod_check( op, op->ora_modlist,
 					&rs->sr_text, textbuf, textlen );
 
 				if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -305,7 +309,7 @@
 
 			if ( !repl_user ) {
 				/* go to the last mod */
-				for ( modtail = &modlist;
+				for ( modtail = &op->ora_modlist;
 						*modtail != NULL;
 						modtail = &(*modtail)->sml_next )
 				{
@@ -316,29 +320,13 @@
 
 				/* check for unmodifiable attributes */
 				rs->sr_err = slap_mods_no_repl_user_mod_check( op,
-					modlist, &rs->sr_text, textbuf, textlen );
+					op->ora_modlist, &rs->sr_text, textbuf, textlen );
 				if ( rs->sr_err != LDAP_SUCCESS ) {
 					send_ldap_result( op, rs );
 					goto done;
 				}
-
-#if 0			/* This is a no-op since *modtail is NULL */
-				rs->sr_err = slap_mods2entry( *modtail, &op->ora_e,
-					0, 0, &rs->sr_text, textbuf, textlen );
-				if ( rs->sr_err != LDAP_SUCCESS ) {
-					send_ldap_result( op, rs );
-					goto done;
-				}
-#endif
 			}
 
-#ifdef SLAPD_MULTIMASTER
-			if ( !repl_user )
-#endif
-			{
-				cb.sc_next = op->o_callback;
-				op->o_callback = &cb;
-			}
 			rc = op->o_bd->be_add( op, rs );
 			if ( rc == LDAP_SUCCESS ) {
 				/* NOTE: be_entry_release_w() is
@@ -348,7 +336,6 @@
 				op->o_private = op->o_bd;
 			}
 
-#ifndef SLAPD_MULTIMASTER
 		} else {
 			BerVarray defref = NULL;
 
@@ -371,11 +358,10 @@
 					LDAP_UNWILLING_TO_PERFORM,
 					"shadow context; no update referral" );
 			}
-#endif /* SLAPD_MULTIMASTER */
 		}
 	} else {
-	    Debug( LDAP_DEBUG_ARGS, "	 do_add: no backend support\n", 0, 0, 0 );
-	    send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
+		Debug( LDAP_DEBUG_ARGS, "do_add: no backend support\n", 0, 0, 0 );
+		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
 			"operation not supported within namingContext" );
 	}
 
@@ -394,6 +380,7 @@
 	char *textbuf, size_t textlen )
 {
 	Attribute **tail;
+	int i;
 
 	if ( initial ) {
 		assert( (*e)->e_attrs == NULL );
@@ -414,7 +401,7 @@
 		if( attr != NULL ) {
 #define SLURPD_FRIENDLY
 #ifdef SLURPD_FRIENDLY
-			ber_len_t i,j;
+			int j;
 
 			if ( !initial ) {
 				/*	
@@ -427,12 +414,9 @@
 				return LDAP_SUCCESS;
 			}
 
-			for( i=0; attr->a_vals[i].bv_val; i++ ) {
-				/* count them */
-			}
-			for( j=0; mods->sml_values[j].bv_val; j++ ) {
-				/* count them */
-			}
+			i = attr->a_numvals;
+			j = mods->sml_numvals;
+			attr->a_numvals += j;
 			j++;	/* NULL */
 			
 			attr->a_vals = ch_realloc( attr->a_vals,
@@ -477,53 +461,12 @@
 #endif
 		}
 
-#if 0	/* checked for duplicates in slap_mods_check */
-		if( mods->sml_values[1].bv_val != NULL ) {
-			/* check for duplicates */
-			int		i, j, rc, match;
-			MatchingRule *mr = mods->sml_desc->ad_type->sat_equality;
+		attr = attr_alloc( mods->sml_desc );
 
-			for ( i = 1; mods->sml_values[i].bv_val != NULL; i++ ) {
-				/* test asserted values against themselves */
-				for( j = 0; j < i; j++ ) {
-					rc = ordered_value_match( &match, mods->sml_desc, mr,
-						SLAP_MR_EQUALITY
-						| SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX
-						| SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH
-						| SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
-						mods->sml_nvalues
-							? &mods->sml_nvalues[i]
-							: &mods->sml_values[i],
-						mods->sml_nvalues
-							? &mods->sml_nvalues[j]
-							: &mods->sml_values[j],
-						text );
-
-					if ( rc == LDAP_SUCCESS && match == 0 ) {
-						/* value exists already */
-						snprintf( textbuf, textlen,
-							"%s: value #%d provided more than once",
-							mods->sml_desc->ad_cname.bv_val, j );
-						*text = textbuf;
-						return LDAP_TYPE_OR_VALUE_EXISTS;
-
-					} else if ( rc != LDAP_SUCCESS ) {
-						return rc;
-					}
-				}
-			}
-		}
-#endif
-
-		attr = ch_calloc( 1, sizeof(Attribute) );
-
-		/* move ad to attr structure */
-		attr->a_desc = mods->sml_desc;
-
 		/* move values to attr structure */
+		i = mods->sml_numvals;
+		attr->a_numvals = mods->sml_numvals;
 		if ( dup ) { 
-			int i;
-			for ( i = 0; mods->sml_values[i].bv_val; i++ ) /* EMPTY */;
 			attr->a_vals = (BerVarray) ch_calloc( i+1, sizeof( BerValue ));
 			for ( i = 0; mods->sml_values[i].bv_val; i++ ) {
 				ber_dupbv( &attr->a_vals[i], &mods->sml_values[i] );
@@ -535,8 +478,7 @@
 
 		if ( mods->sml_nvalues ) {
 			if ( dup ) {
-				int i;
-				for ( i = 0; mods->sml_nvalues[i].bv_val; i++ ) /* EMPTY */;
+				i = mods->sml_numvals;
 				attr->a_nvals = (BerVarray) ch_calloc( i+1, sizeof( BerValue ));
 				for ( i = 0; mods->sml_nvalues[i].bv_val; i++ ) {
 					ber_dupbv( &attr->a_nvals[i], &mods->sml_nvalues[i] );
@@ -548,6 +490,9 @@
 		} else {
 			attr->a_nvals = attr->a_vals;
 		}
+		/* slap_mods_check() gives us sorted results */
+		if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL )
+			attr->a_flags |= SLAP_ATTR_SORTED_VALS;
 
 		*tail = attr;
 		tail = &attr->a_next;
@@ -583,7 +528,8 @@
 
 		mod->sml_type = a_new_desc->ad_cname;
 
-		for ( count = 0; a_new->a_vals[count].bv_val; count++ ) /* EMPTY */;
+		count = a_new->a_numvals;
+		mod->sml_numvals = a_new->a_numvals;
 
 		mod->sml_values = (struct berval*) malloc(
 			(count+1) * sizeof( struct berval) );
@@ -639,29 +585,11 @@
 	char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
 	Attribute *a;
 
-	a = attr_find( op->ora_e->e_attrs,
-		slap_schema.si_ad_structuralObjectClass );
-
-	if ( !a ) {
-		Attribute *oc;
-		int rc;
-
-		oc = attr_find( op->ora_e->e_attrs, slap_schema.si_ad_objectClass );
-		if ( oc ) {
-			rc = structural_class( oc->a_vals, &tmp, NULL, text,
-				textbuf, textlen );
-			if( rc != LDAP_SUCCESS ) return rc;
-
-			attr_merge_one( op->ora_e, slap_schema.si_ad_structuralObjectClass,
-				&tmp, NULL );
-		}
-	}
-
 	if ( SLAP_LASTMOD( op->o_bd ) ) {
 		char *ptr;
 		int gotcsn = 0;
-		timestamp.bv_val = timebuf;
 
+		timestamp.bv_val = timebuf;
 		a = attr_find( op->ora_e->e_attrs, slap_schema.si_ad_entryCSN );
 		if ( a ) {
 			gotcsn = 1;
@@ -681,10 +609,9 @@
 		}
 		ptr = ber_bvchr( &csn, '#' );
 		if ( ptr ) {
-			timestamp.bv_len = ptr - csn.bv_val;
-			if ( timestamp.bv_len >= sizeof(timebuf) )
-				timestamp.bv_len = sizeof(timebuf) - 1;
-			strncpy( timebuf, csn.bv_val, timestamp.bv_len );
+			timestamp.bv_len = STRLENOF("YYYYMMDDHHMMSSZ");
+			AC_MEMCPY( timebuf, csn.bv_val, timestamp.bv_len );
+			timebuf[timestamp.bv_len-1] = 'Z';
 			timebuf[timestamp.bv_len] = '\0';
 		} else {
 			time_t now = slap_get_time();
@@ -746,7 +673,7 @@
 			attr_merge_one( op->ora_e,
 				slap_schema.si_ad_modifyTimestamp, &timestamp, NULL );
 		}
-
 	}
+
 	return LDAP_SUCCESS;
 }

Modified: openldap/trunk/servers/slapd/alock.c
===================================================================
--- openldap/trunk/servers/slapd/alock.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/alock.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* alock.c - access lock library */
-/* $OpenLDAP: pkg/ldap/servers/slapd/alock.c,v 1.2.2.5 2007/01/02 21:43:54 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/alock.c,v 1.5.2.6 2007/09/26 15:46:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2005-2007 The OpenLDAP Foundation.
@@ -21,7 +21,7 @@
 
 #include "portable.h"
 
-#if SLAPD_BDB || SLAPD_HDB || SLAPD_LDBM
+#if SLAPD_BDB || SLAPD_HDB
 
 #include "alock.h"
 
@@ -32,7 +32,9 @@
 #include <ac/assert.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>
+#endif
 #include <fcntl.h>
 
 #ifdef _WIN32
@@ -229,7 +231,7 @@
 	}
 	
 	if (alock_read_iattr (slotbuf) != ALOCK_MAGIC) {
-		return 1;
+		return -1;
 	}
 	slot_data->al_lock  = alock_read_iattr (slotbuf+8);
 	slot_data->al_stamp = alock_read_iattr (slotbuf+16);
@@ -262,7 +264,8 @@
 	alock_write_iattr (slotbuf+16, slot_data->al_stamp);
 	alock_write_iattr (slotbuf+24, slot_data->al_pid);
 
-	strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1);
+	if (slot_data->al_appname)
+		strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1);
 	slotbuf[ALOCK_SLOT_SIZE-1] = '\0';
 
 	res = lseek (info->al_fd, 
@@ -513,7 +516,7 @@
 }
 
 int
-alock_close ( alock_info_t * info )
+alock_close ( alock_info_t * info, int nosave )
 {
 	alock_slot_t slot_data;
 	int res;
@@ -537,7 +540,9 @@
 			free (slot_data.al_appname);
 		return ALOCK_UNSTABLE;
 	}
-	slot_data.al_lock = ALOCK_UNLOCKED | (slot_data.al_lock & ALOCK_NOSAVE);
+	slot_data.al_lock = ALOCK_UNLOCKED;
+	if ( nosave )
+		slot_data.al_lock |= ALOCK_NOSAVE;
 	res = alock_write_slot (info, &slot_data);
 	if (res == -1) {
 		close (info->al_fd);

Modified: openldap/trunk/servers/slapd/alock.h
===================================================================
--- openldap/trunk/servers/slapd/alock.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/alock.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* alock.h - access lock header */
-/* $OpenLDAP: pkg/ldap/servers/slapd/alock.h,v 1.1.2.4 2007/01/02 21:43:54 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/alock.h,v 1.3.2.3 2007/09/26 15:46:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2005-2007 The OpenLDAP Foundation.
@@ -66,7 +66,7 @@
 LDAP_SLAPD_F (int) alock_open LDAP_P(( alock_info_t * info, const char * appname,
 	const char * envdir, int locktype ));
 LDAP_SLAPD_F (int) alock_scan LDAP_P(( alock_info_t * info ));
-LDAP_SLAPD_F (int) alock_close LDAP_P(( alock_info_t * info ));
+LDAP_SLAPD_F (int) alock_close LDAP_P(( alock_info_t * info, int nosave ));
 LDAP_SLAPD_F (int) alock_recover LDAP_P(( alock_info_t * info ));
 
 LDAP_END_DECL

Modified: openldap/trunk/servers/slapd/at.c
===================================================================
--- openldap/trunk/servers/slapd/at.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/at.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* at.c - routines for dealing with attribute types */
-/* $OpenLDAP: pkg/ldap/servers/slapd/at.c,v 1.62.2.10 2007/01/02 21:43:54 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/at.c,v 1.84.2.3 2007/08/31 23:13:58 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -27,16 +27,32 @@
 #include "slap.h"
 
 
-int is_at_syntax(
-	AttributeType *at,
-	const char *oid )
+const char *
+at_syntax(
+	AttributeType	*at )
 {
-	for( ; at != NULL; at = at->sat_sup ) {
-		if( at->sat_syntax_oid ) {
-			return ( strcmp( at->sat_syntax_oid, oid ) == 0 );
+	for ( ; at != NULL; at = at->sat_sup ) {
+		if ( at->sat_syntax_oid ) {
+			return at->sat_syntax_oid;
 		}
 	}
 
+	assert( 0 );
+
+	return NULL;
+}
+
+int
+is_at_syntax(
+	AttributeType	*at,
+	const char	*oid )
+{
+	const char *syn_oid = at_syntax( at );
+
+	if ( syn_oid ) {
+		return strcmp( syn_oid, oid ) == 0;
+	}
+
 	return 0;
 }
 
@@ -58,9 +74,12 @@
 
 static Avlnode	*attr_index = NULL;
 static Avlnode	*attr_cache = NULL;
-static LDAP_STAILQ_HEAD(ATList, slap_attribute_type) attr_list
+static LDAP_STAILQ_HEAD(ATList, AttributeType) attr_list
 	= LDAP_STAILQ_HEAD_INITIALIZER(attr_list);
 
+/* Last hardcoded attribute registered */
+AttributeType *at_sys_tail;
+
 int at_oc_cache;
 
 static int
@@ -110,9 +129,13 @@
 
 	air = avl_find( attr_index, name, attr_index_name_cmp );
 
-	if ( air && ( slapMode & SLAP_TOOL_MODE ) && at_oc_cache ) {
-		avl_insert( &attr_cache, (caddr_t) air,
-			attr_index_cmp, avl_dup_error );
+	if ( air ) {
+		if ( air->air_at->sat_flags & SLAP_AT_DELETED ) {
+			air = NULL;
+		} else if (( slapMode & SLAP_TOOL_MODE ) && at_oc_cache ) {
+			avl_insert( &attr_cache, (caddr_t) air,
+				attr_index_cmp, avl_dup_error );
+		}
 	}
 
 	return air != NULL ? air->air_at : NULL;
@@ -204,46 +227,100 @@
 	return -1;
 }
 
+static void
+at_delete_names( AttributeType *at )
+{
+	char			**names = at->sat_names;
+
+	while (*names) {
+		struct aindexrec	tmpair, *air;
+
+		ber_str2bv( *names, 0, 0, &tmpair.air_name );
+		tmpair.air_at = at;
+		air = (struct aindexrec *)avl_delete( &attr_index,
+			(caddr_t)&tmpair, attr_index_cmp );
+		assert( air != NULL );
+		ldap_memfree( air );
+		names++;
+	}
+}
+
+/* Mark the attribute as deleted, remove from list, and remove all its
+ * names from the AVL tree. Leave the OID in the tree.
+ */
 void
-at_destroy( void )
+at_delete( AttributeType *at )
 {
-	AttributeType *a;
-	avl_free(attr_index, ldap_memfree);
+	at->sat_flags |= SLAP_AT_DELETED;
 
-	while( !LDAP_STAILQ_EMPTY(&attr_list) ) {
-		a = LDAP_STAILQ_FIRST(&attr_list);
-		LDAP_STAILQ_REMOVE_HEAD(&attr_list, sat_next);
+	LDAP_STAILQ_REMOVE(&attr_list, at, AttributeType, sat_next);
 
-		if ( a->sat_equality ) {
-			MatchingRule	*mr;
+	at_delete_names( at );
+}
 
-			mr = mr_find( a->sat_equality->smr_oid );
-			assert( mr != NULL );
-			if ( mr != a->sat_equality ) {
-				ch_free( a->sat_equality );
-				a->sat_equality = NULL;
-			}
+static void
+at_clean( AttributeType *a )
+{
+	if ( a->sat_equality ) {
+		MatchingRule	*mr;
+
+		mr = mr_find( a->sat_equality->smr_oid );
+		assert( mr != NULL );
+		if ( mr != a->sat_equality ) {
+			ch_free( a->sat_equality );
+			a->sat_equality = NULL;
 		}
+	}
 
-		assert( a->sat_syntax != NULL );
-		if ( a->sat_syntax != NULL ) {
-			Syntax		*syn;
+	assert( a->sat_syntax != NULL );
+	if ( a->sat_syntax != NULL ) {
+		Syntax		*syn;
 
-			syn = syn_find( a->sat_syntax->ssyn_oid );
-			assert( syn != NULL );
-			if ( syn != a->sat_syntax ) {
-				ch_free( a->sat_syntax );
-				a->sat_syntax = NULL;
-			}
+		syn = syn_find( a->sat_syntax->ssyn_oid );
+		assert( syn != NULL );
+		if ( syn != a->sat_syntax ) {
+			ch_free( a->sat_syntax );
+			a->sat_syntax = NULL;
 		}
+	}
 
-		if ( a->sat_oidmacro ) ldap_memfree( a->sat_oidmacro );
-		if ( a->sat_subtypes ) ldap_memfree( a->sat_subtypes );
-		ad_destroy(a->sat_ad);
-		ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex);
-		ldap_attributetype_free((LDAPAttributeType *)a);
+	if ( a->sat_oidmacro ) {
+		ldap_memfree( a->sat_oidmacro );
+		a->sat_oidmacro = NULL;
 	}
+	if ( a->sat_subtypes ) {
+		ldap_memfree( a->sat_subtypes );
+		a->sat_subtypes = NULL;
+	}
+}
 
+static void
+at_destroy_one( void *v )
+{
+	struct aindexrec *air = v;
+	AttributeType *a = air->air_at;
+
+	at_clean( a );
+	ad_destroy(a->sat_ad);
+	ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex);
+	ldap_attributetype_free((LDAPAttributeType *)a);
+	ldap_memfree(air);
+}
+
+void
+at_destroy( void )
+{
+	AttributeType *a;
+
+	while( !LDAP_STAILQ_EMPTY(&attr_list) ) {
+		a = LDAP_STAILQ_FIRST(&attr_list);
+		LDAP_STAILQ_REMOVE_HEAD(&attr_list, sat_next);
+
+		at_delete_names( a );
+	}
+
+	avl_free(attr_index, at_destroy_one);
+
 	if ( slap_schema.si_at_undefined ) {
 		ad_destroy(slap_schema.si_at_undefined->sat_ad);
 	}
@@ -268,7 +345,7 @@
 {
 	assert( at != NULL );
 
-#if 1	/* pedantic check */
+#if 0	/* pedantic check: don't use this */
 	{
 		AttributeType *tmp = NULL;
 
@@ -338,36 +415,84 @@
 	return SLAP_SCHERR_ATTR_DUP;
 }
 
+static struct aindexrec *air_old;
 
 static int
+at_dup_error( void *left, void *right )
+{
+	air_old = left;
+	return -1;
+}
+
+static int
 at_insert(
-    AttributeType	*sat,
+    AttributeType	**rat,
+	AttributeType	*prev,
     const char		**err )
 {
 	struct aindexrec	*air;
 	char			**names = NULL;
+	AttributeType	*sat = *rat;
 
-
 	if ( sat->sat_oid ) {
 		air = (struct aindexrec *)
 			ch_calloc( 1, sizeof(struct aindexrec) );
 		ber_str2bv( sat->sat_oid, 0, 0, &air->air_name );
 		air->air_at = sat;
+		air_old = NULL;
+
 		if ( avl_insert( &attr_index, (caddr_t) air,
-		                 attr_index_cmp, avl_dup_error ) )
+		                 attr_index_cmp, at_dup_error ) )
 		{
 			AttributeType	*old_sat;
 			int		rc;
 
 			*err = sat->sat_oid;
 
-			old_sat = at_bvfind( &air->air_name );
-			assert( old_sat != NULL );
-			rc = at_check_dup( old_sat, sat );
+			assert( air_old != NULL );
+			old_sat = air_old->air_at;
 
-			ldap_memfree( air );
+			/* replacing a deleted definition? */
+			if ( old_sat->sat_flags & SLAP_AT_DELETED ) {
+				AttributeType tmp;
+				AttributeDescription *ad;
+				
+				/* Keep old oid, free new oid;
+				 * Keep old ads, free new ads;
+				 * Keep old ad_mutex, free new ad_mutex;
+				 * Keep new everything else, free old
+				 */
+				tmp = *old_sat;
+				*old_sat = *sat;
+				old_sat->sat_oid = tmp.sat_oid;
+				tmp.sat_oid = sat->sat_oid;
+				old_sat->sat_ad = tmp.sat_ad;
+				tmp.sat_ad = sat->sat_ad;
+				old_sat->sat_ad_mutex = tmp.sat_ad_mutex;
+				tmp.sat_ad_mutex = sat->sat_ad_mutex;
+				*sat = tmp;
 
-			return rc;
+				/* Check for basic ad pointing at old cname */
+				for ( ad = old_sat->sat_ad; ad; ad=ad->ad_next ) {
+					if ( ad->ad_cname.bv_val == sat->sat_cname.bv_val ) {
+						ad->ad_cname = old_sat->sat_cname;
+						break;
+					}
+				}
+
+				at_clean( sat );
+				at_destroy_one( air );
+
+				air = air_old;
+				sat = old_sat;
+				*rat = sat;
+			} else {
+				ldap_memfree( air );
+
+				rc = at_check_dup( old_sat, sat );
+
+				return rc;
+			}
 		}
 		/* FIX: temporal consistency check */
 		at_bvfind( &air->air_name );
@@ -437,7 +562,15 @@
 		}
 	}
 
-	LDAP_STAILQ_INSERT_TAIL( &attr_list, sat, sat_next );
+	if ( sat->sat_flags & SLAP_AT_HARDCODE ) {
+		prev = at_sys_tail;
+		at_sys_tail = sat;
+	}
+	if ( prev ) {
+		LDAP_STAILQ_INSERT_AFTER( &attr_list, prev, sat, sat_next );
+	} else {
+		LDAP_STAILQ_INSERT_TAIL( &attr_list, sat, sat_next );
+	}
 
 	return 0;
 }
@@ -447,6 +580,7 @@
 	LDAPAttributeType	*at,
 	int			user,
 	AttributeType		**rsat,
+	AttributeType	*prev,
 	const char		**err )
 {
 	AttributeType	*sat = NULL;
@@ -457,6 +591,11 @@
 	char		*cname = NULL;
 	char		*oidm = NULL;
 
+	if ( !at->at_oid ) {
+		*err = "";
+		return SLAP_SCHERR_ATTR_INCOMPLETE;
+	}
+
 	if ( !OID_LEADCHAR( at->at_oid[0] )) {
 		char	*oid;
 
@@ -501,13 +640,9 @@
 
 		cname = at->at_names[0];
 
-	} else if ( at->at_oid ) {
+	} else {
 		cname = at->at_oid;
 
-	} else {
-		*err = "";
-		code = SLAP_SCHERR_ATTR_INCOMPLETE;
-		goto error_return;
 	}
 
 	*err = cname;
@@ -619,9 +754,12 @@
 			goto error_return;
 		}
 
-		if( sat->sat_syntax != NULL && sat->sat_syntax != syn ) {
-			code = SLAP_SCHERR_ATTR_BAD_SUP;
-			goto error_return;
+		if ( sat->sat_syntax != NULL && sat->sat_syntax != syn ) {
+			/* BEWARE: no loop detection! */
+			if ( syn_is_sup( sat->sat_syntax, syn ) ) {
+				code = SLAP_SCHERR_ATTR_BAD_SUP;
+				goto error_return;
+			}
 		}
 
 		sat->sat_syntax = syn;
@@ -768,7 +906,7 @@
 		sat->sat_substr = mr;
 	}
 
-	code = at_insert( sat, err );
+	code = at_insert( &sat, prev, err );
 	if ( code != 0 ) {
 error_return:;
 		if ( sat ) {
@@ -823,7 +961,7 @@
 	/* count the result size */
 	i = 0;
 	for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) {
-		if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) continue;
+		if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break;
 		i++;
 		if ( at == end ) break;
 	}
@@ -840,7 +978,7 @@
 	i = 0;
 	for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) {
 		LDAPAttributeType lat, *latp;
-		if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) continue;
+		if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break;
 		if ( at->sat_oidmacro ) {
 			lat = at->sat_atype;
 			lat.at_oid = at->sat_oidmacro;
@@ -891,3 +1029,46 @@
 	}
 	return 0;
 }
+
+int
+register_at( char *def, AttributeDescription **rad, int dupok )
+{
+	LDAPAttributeType *at;
+	int code, freeit = 0;
+	const char *err;
+	AttributeDescription *ad = NULL;
+
+	at = ldap_str2attributetype( def, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
+	if ( !at ) {
+		Debug( LDAP_DEBUG_ANY,
+			"register_at: AttributeType \"%s\": %s, %s\n",
+				def, ldap_scherr2str(code), err );
+		return code;
+	}
+
+	code = at_add( at, 0, NULL, NULL, &err );
+	if ( code ) {
+		if ( code == SLAP_SCHERR_ATTR_DUP && dupok ) {
+			freeit = 1;
+
+		} else {
+			ldap_attributetype_free( at );
+			Debug( LDAP_DEBUG_ANY,
+				"register_at: AttributeType \"%s\": %s, %s\n",
+				def, scherr2str(code), err );
+			return code;
+		}
+	}
+	code = slap_str2ad( at->at_names[0], &ad, &err );
+	if ( freeit || code ) {
+		ldap_attributetype_free( at );
+	} else {
+		ldap_memfree( at );
+	}
+	if ( code ) {
+		Debug( LDAP_DEBUG_ANY, "register_at: AttributeType \"%s\": %s\n",
+			def, err, 0 );
+	}
+	if ( rad ) *rad = ad;
+	return code;
+}

Modified: openldap/trunk/servers/slapd/attr.c
===================================================================
--- openldap/trunk/servers/slapd/attr.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/attr.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* attr.c - routines for dealing with attributes */
-/* $OpenLDAP: pkg/ldap/servers/slapd/attr.c,v 1.100.2.12 2007/02/21 21:32:21 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/attr.c,v 1.112.2.6 2007/11/27 19:52:32 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -40,39 +40,132 @@
 
 #include "slap.h"
 
+/*
+ * Allocate in chunks, minimum of 1000 at a time.
+ */
+#define	CHUNK_SIZE	1000
+typedef struct slap_list {
+	struct slap_list *next;
+} slap_list;
+static slap_list *attr_chunks;
+static Attribute *attr_list;
+static ldap_pvt_thread_mutex_t attr_mutex;
+
+int
+attr_prealloc( int num )
+{
+	Attribute *a;
+	slap_list *s;
+
+	if (!num) return 0;
+
+	s = ch_calloc( 1, sizeof(slap_list) + num * sizeof(Attribute));
+	s->next = attr_chunks;
+	attr_chunks = s;
+
+	a = (Attribute *)(s+1);
+	for ( ;num>1; num--) {
+		a->a_next = a+1;
+		a++;
+	}
+	a->a_next = attr_list;
+	attr_list = (Attribute *)(s+1);
+
+	return 0;
+}
+
 Attribute *
 attr_alloc( AttributeDescription *ad )
 {
-	Attribute *a = ch_malloc( sizeof(Attribute) );
+	Attribute *a;
 
+	ldap_pvt_thread_mutex_lock( &attr_mutex );
+	if ( !attr_list )
+		attr_prealloc( CHUNK_SIZE );
+	a = attr_list;
+	attr_list = a->a_next;
+	a->a_next = NULL;
+	ldap_pvt_thread_mutex_unlock( &attr_mutex );
+	
 	a->a_desc = ad;
-	a->a_next = NULL;
-	a->a_flags = 0;
-	a->a_vals = NULL;
-	a->a_nvals = NULL;
-#ifdef LDAP_COMP_MATCH
-	a->a_comp_data = NULL;
-#endif
 
 	return a;
 }
 
+/* Return a list of num attrs */
+Attribute *
+attrs_alloc( int num )
+{
+	Attribute *head = NULL;
+	Attribute **a;
+
+	ldap_pvt_thread_mutex_lock( &attr_mutex );
+	for ( a = &attr_list; *a && num > 0; a = &(*a)->a_next ) {
+		if ( !head )
+			head = *a;
+		num--;
+	}
+	attr_list = *a;
+	if ( num > 0 ) {
+		attr_prealloc( num > CHUNK_SIZE ? num : CHUNK_SIZE );
+		*a = attr_list;
+		for ( ; *a && num > 0; a = &(*a)->a_next ) {
+			if ( !head )
+				head = *a;
+			num--;
+		}
+		attr_list = *a;
+	}
+	*a = NULL;
+	ldap_pvt_thread_mutex_unlock( &attr_mutex );
+
+	return head;
+}
+
+
 void
-attr_free( Attribute *a )
+attr_clean( Attribute *a )
 {
-	if ( a->a_nvals && a->a_nvals != a->a_vals ) {
-		ber_bvarray_free( a->a_nvals );
+	if ( a->a_nvals && a->a_nvals != a->a_vals &&
+		!( a->a_flags & SLAP_ATTR_DONT_FREE_VALS )) {
+		if ( a->a_flags & SLAP_ATTR_DONT_FREE_DATA ) {
+			free( a->a_nvals );
+		} else {
+			ber_bvarray_free( a->a_nvals );
+		}
 	}
 	/* a_vals may be equal to slap_dummy_bv, a static empty berval;
 	 * this is used as a placeholder for attributes that do not carry
 	 * values, e.g. when proxying search entries with the "attrsonly"
 	 * bit set. */
-	if ( a->a_vals != &slap_dummy_bv ) {
-		ber_bvarray_free( a->a_vals );
+	if ( a->a_vals != &slap_dummy_bv &&
+		!( a->a_flags & SLAP_ATTR_DONT_FREE_VALS )) {
+		if ( a->a_flags & SLAP_ATTR_DONT_FREE_DATA ) {
+			free( a->a_vals );
+		} else {
+			ber_bvarray_free( a->a_vals );
+		}
 	}
-	free( a );
+	a->a_desc = NULL;
+	a->a_vals = NULL;
+	a->a_nvals = NULL;
+#ifdef LDAP_COMP_MATCH
+	a->a_comp_data = NULL;
+#endif
+	a->a_flags = 0;
+	a->a_numvals = 0;
 }
 
+void
+attr_free( Attribute *a )
+{
+	attr_clean( a );
+	ldap_pvt_thread_mutex_lock( &attr_mutex );
+	a->a_next = attr_list;
+	attr_list = a;
+	ldap_pvt_thread_mutex_unlock( &attr_mutex );
+}
+
 #ifdef LDAP_COMP_MATCH
 void
 comp_tree_free( Attribute *a )
@@ -93,32 +186,38 @@
 void
 attrs_free( Attribute *a )
 {
-	Attribute *next;
+	if ( a ) {
+		Attribute *b = (Attribute *)0xBAD, *tail, *next;
 
-	for( ; a != NULL ; a = next ) {
-		next = a->a_next;
-		attr_free( a );
+		/* save tail */
+		tail = a;
+		do {
+			next = a->a_next;
+			attr_clean( a );
+			a->a_next = b;
+			b = a;
+			a = next;
+		} while ( next );
+
+		ldap_pvt_thread_mutex_lock( &attr_mutex );
+		/* replace NULL with current attr list and let attr list
+		 * start from last attribute returned to list */
+		tail->a_next = attr_list;
+		attr_list = b;
+		ldap_pvt_thread_mutex_unlock( &attr_mutex );
 	}
 }
 
-Attribute *
-attr_dup( Attribute *a )
+static void
+attr_dup2( Attribute *tmp, Attribute *a )
 {
-	Attribute *tmp;
-
-	if ( a == NULL) return NULL;
-
-	tmp = attr_alloc( a->a_desc );
-
+	tmp->a_flags = a->a_flags & SLAP_ATTR_PERSISTENT_FLAGS;
 	if ( a->a_vals != NULL ) {
 		int	i;
 
-		for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) {
-			/* EMPTY */ ;
-		}
-
-		tmp->a_vals = ch_malloc( (i + 1) * sizeof(struct berval) );
-		for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) {
+		tmp->a_numvals = a->a_numvals;
+		tmp->a_vals = ch_malloc( (tmp->a_numvals + 1) * sizeof(struct berval) );
+		for ( i = 0; i < tmp->a_numvals; i++ ) {
 			ber_dupbv( &tmp->a_vals[i], &a->a_vals[i] );
 			if ( BER_BVISNULL( &tmp->a_vals[i] ) ) break;
 			/* FIXME: error? */
@@ -131,7 +230,7 @@
 		if ( a->a_nvals != a->a_vals ) {
 			int	j;
 
-			tmp->a_nvals = ch_malloc( (i + 1) * sizeof(struct berval) );
+			tmp->a_nvals = ch_malloc( (tmp->a_numvals + 1) * sizeof(struct berval) );
 			for ( j = 0; !BER_BVISNULL( &a->a_nvals[j] ); j++ ) {
 				assert( j < i );
 				ber_dupbv( &tmp->a_nvals[j], &a->a_nvals[j] );
@@ -144,34 +243,202 @@
 		} else {
 			tmp->a_nvals = tmp->a_vals;
 		}
+	}
+}
 
-	} else {
-		tmp->a_vals = NULL;
-		tmp->a_nvals = NULL;
-	}
+Attribute *
+attr_dup( Attribute *a )
+{
+	Attribute *tmp;
+
+	if ( a == NULL) return NULL;
+
+	tmp = attr_alloc( a->a_desc );
+	attr_dup2( tmp, a );
 	return tmp;
 }
 
 Attribute *
 attrs_dup( Attribute *a )
 {
-	Attribute *tmp, **next;
+	int i;
+	Attribute *tmp, *anew;
 
 	if( a == NULL ) return NULL;
 
-	tmp = NULL;
-	next = &tmp;
+	/* count them */
+	for( tmp=a,i=0; tmp; tmp=tmp->a_next ) {
+		i++;
+	}
 
-	for( ; a != NULL ; a = a->a_next ) {
-		*next = attr_dup( a );
-		next = &((*next)->a_next);
+	anew = attrs_alloc( i );
+
+	for( tmp=anew; a; a=a->a_next ) {
+		tmp->a_desc = a->a_desc;
+		attr_dup2( tmp, a );
+		tmp=tmp->a_next;
 	}
-	*next = NULL;
 
-	return tmp;
+	return anew;
 }
 
+int
+attr_valfind(
+	Attribute *a,
+	unsigned flags,
+	struct berval *val,
+	unsigned *slot,
+	void *ctx )
+{
+	struct berval nval = BER_BVNULL, *cval;
+	MatchingRule *mr;
+	const char *text;
+	int match = -1, rc;
+	unsigned i;
 
+	if ( flags & SLAP_MR_ORDERING )
+		mr = a->a_desc->ad_type->sat_ordering;
+	else
+		mr = a->a_desc->ad_type->sat_equality;
+
+	if( !SLAP_IS_MR_ASSERTED_VALUE_NORMALIZED_MATCH( flags ) &&
+		mr->smr_normalize )
+	{
+		rc = (mr->smr_normalize)(
+			flags & (SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK|SLAP_MR_VALUE_OF_SYNTAX),
+			a->a_desc->ad_type->sat_syntax,
+			mr, val, &nval, ctx );
+
+		if( rc != LDAP_SUCCESS ) {
+			return LDAP_INVALID_SYNTAX;
+		}
+		cval = &nval;
+	} else {
+		cval = val;
+	}
+
+	if ( a->a_flags & SLAP_ATTR_SORTED_VALS ) {
+		/* Binary search */
+		unsigned base = 0, n = a->a_numvals;
+
+		while ( 0 < n ) {
+			unsigned pivot = n >> 1;
+			i = base + pivot;
+			if ( i >= a->a_numvals ) {
+				i = a->a_numvals - 1;
+				break;
+			}
+			rc = value_match( &match, a->a_desc, mr, flags,
+				&a->a_nvals[i], cval, &text );
+			if ( rc == LDAP_SUCCESS && match == 0 )
+				break;
+			n = pivot;
+			if ( match < 0 )
+				base = i+1;
+		}
+		if ( match < 0 )
+			i++;
+	} else {
+	/* Linear search */
+		for ( i = 0; i < a->a_numvals; i++ ) {
+			const char *text;
+
+			rc = ordered_value_match( &match, a->a_desc, mr, flags,
+				&a->a_nvals[i], cval, &text );
+			if ( rc == LDAP_SUCCESS && match == 0 )
+				break;
+		}
+	}
+	if ( slot )
+		*slot = i;
+	if ( match )
+		rc = LDAP_NO_SUCH_ATTRIBUTE;
+	if ( nval.bv_val )
+		slap_sl_free( nval.bv_val, ctx );
+
+	return rc;
+}
+
+int
+attr_valadd(
+	Attribute *a,
+	BerVarray vals,
+	BerVarray nvals,
+	int nn )
+{
+	int		i;
+	BerVarray	v2;
+
+	v2 = (BerVarray) SLAP_REALLOC( (char *) a->a_vals,
+		    (a->a_numvals + nn + 1) * sizeof(struct berval) );
+	if( v2 == NULL ) {
+		Debug(LDAP_DEBUG_TRACE,
+		  "attr_valadd: SLAP_REALLOC failed.\n", 0, 0, 0 );
+		return LBER_ERROR_MEMORY;
+	}
+	a->a_vals = v2;
+	if ( nvals ) {
+		v2 = (BerVarray) SLAP_REALLOC( (char *) a->a_nvals,
+				(a->a_numvals + nn + 1) * sizeof(struct berval) );
+		if( v2 == NULL ) {
+			Debug(LDAP_DEBUG_TRACE,
+			  "attr_valadd: SLAP_REALLOC failed.\n", 0, 0, 0 );
+			return LBER_ERROR_MEMORY;
+		}
+		a->a_nvals = v2;
+	} else {
+		a->a_nvals = a->a_vals;
+	}
+
+	/* If sorted and old vals exist, must insert */
+	if (( a->a_flags & SLAP_ATTR_SORTED_VALS ) && a->a_numvals ) {
+		unsigned slot;
+		int j, rc;
+		v2 = nvals ? nvals : vals;
+		for ( i = 0; i < nn; i++ ) {
+			rc = attr_valfind( a, SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX |
+				SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
+				&v2[i], &slot, NULL );
+			if ( rc != LDAP_NO_SUCH_ATTRIBUTE ) {
+				/* should never happen */
+				if ( rc == LDAP_SUCCESS )
+					rc = LDAP_TYPE_OR_VALUE_EXISTS;
+				return rc;
+			}
+			for ( j = a->a_numvals; j >= slot; j-- ) {
+				a->a_vals[j+1] = a->a_vals[j];
+				if ( nvals )
+					a->a_nvals[j+1] = a->a_nvals[j];
+			}
+			ber_dupbv( &a->a_nvals[slot], &v2[i] );
+			if ( nvals )
+				ber_dupbv( &a->a_vals[slot], &vals[i] );
+			a->a_numvals++;
+		}
+		BER_BVZERO( &a->a_vals[a->a_numvals] );
+		if ( a->a_vals != a->a_nvals )
+			BER_BVZERO( &a->a_nvals[a->a_numvals] );
+	} else {
+		v2 = &a->a_vals[a->a_numvals];
+		for ( i = 0 ; i < nn; i++ ) {
+			ber_dupbv( &v2[i], &vals[i] );
+			if ( BER_BVISNULL( &v2[i] ) ) break;
+		}
+		BER_BVZERO( &v2[i] );
+
+		if ( nvals ) {
+			v2 = &a->a_nvals[a->a_numvals];
+			for ( i = 0 ; i < nn; i++ ) {
+				ber_dupbv( &v2[i], &nvals[i] );
+				if ( BER_BVISNULL( &v2[i] ) ) break;
+			}
+			BER_BVZERO( &v2[i] );
+		}
+		a->a_numvals += i;
+	}
+	return 0;
+}
+
 /*
  * attr_merge - merge the given type and value with the list of
  * attributes in attrs.
@@ -190,7 +457,7 @@
 	BerVarray	vals,
 	BerVarray	nvals )
 {
-	int rc;
+	int i = 0;
 
 	Attribute	**a;
 
@@ -213,30 +480,29 @@
 					|| ( (*a)->a_nvals != (*a)->a_vals ) ) ) );
 	}
 
-	rc = value_add( &(*a)->a_vals, vals );
-
-	if ( rc == LDAP_SUCCESS ) {
-		if ( nvals ) {
-			rc = value_add( &(*a)->a_nvals, nvals );
-			/* FIXME: what if rc != LDAP_SUCCESS ? */
-		} else {
-			(*a)->a_nvals = (*a)->a_vals;
-		}
+	if ( vals != NULL ) {
+		for ( ; !BER_BVISNULL( &vals[i] ); i++ ) ;
 	}
-
-	return rc;
+	return attr_valadd( *a, vals, nvals, i );
 }
 
+/*
+ * if a normalization function is defined for the equality matchingRule
+ * of desc, the value is normalized and stored in nval; otherwise nval 
+ * is NULL
+ */
 int
-attr_merge_normalize(
-	Entry		*e,
-	AttributeDescription *desc,
-	BerVarray	vals,
-	void	 *memctx )
+attr_normalize(
+	AttributeDescription	*desc,
+	BerVarray		vals,
+	BerVarray		*nvalsp,
+	void	 		*memctx )
 {
+	int		rc = LDAP_SUCCESS;
 	BerVarray	nvals = NULL;
-	int		rc;
 
+	*nvalsp = NULL;
+
 	if ( desc->ad_type->sat_equality &&
 		desc->ad_type->sat_equality->smr_normalize )
 	{
@@ -246,7 +512,7 @@
 
 		nvals = slap_sl_calloc( sizeof(struct berval), i + 1, memctx );
 		for ( i = 0; !BER_BVISNULL( &vals[i] ); i++ ) {
-			rc = (*desc->ad_type->sat_equality->smr_normalize)(
+			rc = desc->ad_type->sat_equality->smr_normalize(
 					SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
 					desc->ad_type->sat_syntax,
 					desc->ad_type->sat_equality,
@@ -254,29 +520,48 @@
 
 			if ( rc != LDAP_SUCCESS ) {
 				BER_BVZERO( &nvals[i + 1] );
-				goto error_return;
+				break;
 			}
 		}
 		BER_BVZERO( &nvals[i] );
+		*nvalsp = nvals;
 	}
 
-	rc = attr_merge( e, desc, vals, nvals );
-
-error_return:;
-	if ( nvals != NULL ) {
+	if ( rc != LDAP_SUCCESS && nvals != NULL ) {
 		ber_bvarray_free_x( nvals, memctx );
 	}
+
 	return rc;
 }
 
 int
+attr_merge_normalize(
+	Entry			*e,
+	AttributeDescription	*desc,
+	BerVarray		vals,
+	void	 		*memctx )
+{
+	BerVarray	nvals = NULL;
+	int		rc;
+
+	rc = attr_normalize( desc, vals, &nvals, memctx );
+	if ( rc == LDAP_SUCCESS ) {
+		rc = attr_merge( e, desc, vals, nvals );
+		if ( nvals != NULL ) {
+			ber_bvarray_free_x( nvals, memctx );
+		}
+	}
+
+	return rc;
+}
+
+int
 attr_merge_one(
 	Entry		*e,
 	AttributeDescription *desc,
 	struct berval	*val,
 	struct berval	*nval )
 {
-	int rc;
 	Attribute	**a;
 
 	for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
@@ -289,42 +574,55 @@
 		*a = attr_alloc( desc );
 	}
 
-	rc = value_add_one( &(*a)->a_vals, val );
-
-	if ( rc == LDAP_SUCCESS ) {
-		if ( nval ) {
-			rc = value_add_one( &(*a)->a_nvals, nval );
-			/* FIXME: what if rc != LDAP_SUCCESS ? */
-		} else {
-			(*a)->a_nvals = (*a)->a_vals;
-		}
-	}
-	return rc;
+	return attr_valadd( *a, val, nval, 1 );
 }
 
+/*
+ * if a normalization function is defined for the equality matchingRule
+ * of desc, the value is normalized and stored in nval; otherwise nval 
+ * is NULL
+ */
 int
-attr_merge_normalize_one(
-	Entry		*e,
+attr_normalize_one(
 	AttributeDescription *desc,
 	struct berval	*val,
+	struct berval	*nval,
 	void		*memctx )
 {
-	struct berval	nval;
-	struct berval	*nvalp = NULL;
-	int		rc;
+	int		rc = LDAP_SUCCESS;
 
+	BER_BVZERO( nval );
+
 	if ( desc->ad_type->sat_equality &&
 		desc->ad_type->sat_equality->smr_normalize )
 	{
-		rc = (*desc->ad_type->sat_equality->smr_normalize)(
+		rc = desc->ad_type->sat_equality->smr_normalize(
 				SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
 				desc->ad_type->sat_syntax,
 				desc->ad_type->sat_equality,
-				val, &nval, memctx );
+				val, nval, memctx );
 
 		if ( rc != LDAP_SUCCESS ) {
 			return rc;
 		}
+	}
+
+	return rc;
+}
+
+int
+attr_merge_normalize_one(
+	Entry		*e,
+	AttributeDescription *desc,
+	struct berval	*val,
+	void		*memctx )
+{
+	struct berval	nval = BER_BVNULL;
+	struct berval	*nvalp = NULL;
+	int		rc;
+
+	rc = attr_normalize_one( desc, val, &nval, memctx );
+	if ( rc == LDAP_SUCCESS && !BER_BVISNULL( &nval ) ) {
 		nvalp = &nval;
 	}
 
@@ -399,3 +697,22 @@
 	return LDAP_NO_SUCH_ATTRIBUTE;
 }
 
+int
+attr_init( void )
+{
+	ldap_pvt_thread_mutex_init( &attr_mutex );
+	return 0;
+}
+
+int
+attr_destroy( void )
+{
+	slap_list *a;
+
+	for ( a=attr_chunks; a; a=attr_chunks ) {
+		attr_chunks = a->next;
+		free( a );
+	}
+	ldap_pvt_thread_mutex_destroy( &attr_mutex );
+	return 0;
+}

Modified: openldap/trunk/servers/slapd/ava.c
===================================================================
--- openldap/trunk/servers/slapd/ava.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/ava.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ava.c - routines for dealing with attribute value assertions */
-/* $OpenLDAP: pkg/ldap/servers/slapd/ava.c,v 1.40.2.6 2007/01/02 21:43:54 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/ava.c,v 1.45.2.2 2007/08/31 23:13:58 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -48,6 +48,8 @@
 		nibble_mem_free ( ava->aa_cf->cf_ca->ca_comp_data.cd_mem_op );
 #endif
 	op->o_tmpfree( ava->aa_value.bv_val, op->o_tmpmemctx );
+	if ( ava->aa_desc->ad_flags & SLAP_DESC_TEMPORARY )
+		op->o_tmpfree( ava->aa_desc, op->o_tmpmemctx );
 	if ( freeit ) op->o_tmpfree( (char *) ava, op->o_tmpmemctx );
 }
 
@@ -55,7 +57,7 @@
 get_ava(
 	Operation *op,
 	BerElement	*ber,
-	AttributeAssertion	**ava,
+	Filter *f,
 	unsigned usage,
 	const char **text )
 {
@@ -85,13 +87,17 @@
 	rc = slap_bv2ad( &type, &aa->aa_desc, text );
 
 	if( rc != LDAP_SUCCESS ) {
+		f->f_choice |= SLAPD_FILTER_UNDEFINED;
+		*text = NULL;
 		rc = slap_bv2undef_ad( &type, &aa->aa_desc, text,
 				SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
 
 		if( rc != LDAP_SUCCESS ) {
 			Debug( LDAP_DEBUG_FILTER,
 			"get_ava: unknown attributeType %s\n", type.bv_val, 0, 0 );
-			op->o_tmpfree( aa, op->o_tmpmemctx );
+			aa->aa_desc = slap_bv2tmp_ad( &type, op->o_tmpmemctx );
+			ber_dupbv_x( &aa->aa_value, &value, op->o_tmpmemctx );
+			f->f_ava = aa;
 			return rc;
 		}
 	}
@@ -101,10 +107,11 @@
 		usage, &value, &aa->aa_value, text, op->o_tmpmemctx );
 
 	if( rc != LDAP_SUCCESS ) {
+		f->f_choice |= SLAPD_FILTER_UNDEFINED;
 		Debug( LDAP_DEBUG_FILTER,
 		"get_ava: illegal value for attributeType %s\n", type.bv_val, 0, 0 );
-		op->o_tmpfree( aa, op->o_tmpmemctx );
-		return rc;
+		ber_dupbv_x( &aa->aa_value, &value, op->o_tmpmemctx );
+		rc = LDAP_SUCCESS;
 	}
 
 #ifdef LDAP_COMP_MATCH
@@ -120,6 +127,6 @@
 		}
 	}
 #endif
-	*ava = aa;
+	f->f_ava = aa;
 	return LDAP_SUCCESS;
 }

Modified: openldap/trunk/servers/slapd/back-bdb/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-bdb
-# $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/Makefile.in,v 1.29.2.5 2007/01/02 21:43:59 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/Makefile.in,v 1.34.2.4 2007/08/31 23:14:01 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -18,14 +18,14 @@
 	extended.c referral.c operational.c \
 	attr.c index.c key.c dbcache.c filterindex.c \
 	dn2entry.c dn2id.c error.c id2entry.c idl.c \
-	nextid.c cache.c trans.c
+	nextid.c cache.c trans.c monitor.c
 
 OBJS = init.lo tools.lo config.lo \
 	add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
 	extended.lo referral.lo operational.lo \
 	attr.lo index.lo key.lo dbcache.lo filterindex.lo \
 	dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo \
-	nextid.lo cache.lo trans.lo
+	nextid.lo cache.lo trans.lo monitor.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries
@@ -35,7 +35,7 @@
 
 mod_DEFS = -DSLAPD_IMPORT
 MOD_DEFS = $(@BUILD_BDB at _DEFS)
-MOD_LIBS = $(LDBM_LIBS)
+MOD_LIBS = $(BDB_LIBS)
 
 shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA)
 NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC at _LDAP_LIBS)

Modified: openldap/trunk/servers/slapd/back-bdb/add.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/add.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/add.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* add.c - ldap BerkeleyDB back-end add routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/add.c,v 1.126.2.17 2007/08/08 16:21:17 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/add.c,v 1.152.2.6 2007/11/11 19:33:12 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -26,7 +26,7 @@
 {
 	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
 	struct berval	pdn;
-	Entry		*p = NULL;
+	Entry		*p = NULL, *oe = op->ora_e;
 	EntryInfo	*ei;
 	char textbuf[SLAP_TEXT_BUFLEN];
 	size_t textlen = sizeof textbuf;
@@ -35,36 +35,80 @@
 	DB_TXN		*ltid = NULL, *lt2;
 	struct bdb_op_info opinfo = {0};
 	int subentry;
-	u_int32_t	locker = 0;
+	BDB_LOCKER	locker = 0, rlocker = 0;
 	DB_LOCK		lock;
 
 	int		num_retries = 0;
+	int		success;
 
 	LDAPControl **postread_ctrl = NULL;
 	LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
 	int num_ctrls = 0;
 
+#ifdef LDAP_X_TXN
+	int settle = 0;
+#endif
+
 	Debug(LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_add) ": %s\n",
 		op->oq_add.rs_e->e_name.bv_val, 0, 0);
 
+#ifdef LDAP_X_TXN
+	if( op->o_txnSpec ) {
+		/* acquire connection lock */
+		ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
+		if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
+			rs->sr_text = "invalid transaction identifier";
+			rs->sr_err = LDAP_X_TXN_ID_INVALID;
+			goto txnReturn;
+		} else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+			settle=1;
+			goto txnReturn;
+		}
+
+		if( op->o_conn->c_txn_backend == NULL ) {
+			op->o_conn->c_txn_backend = op->o_bd;
+
+		} else if( op->o_conn->c_txn_backend != op->o_bd ) {
+			rs->sr_text = "transaction cannot span multiple database contexts";
+			rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS;
+			goto txnReturn;
+		}
+
+		/* insert operation into transaction */
+
+		rs->sr_text = "transaction specified";
+		rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY;
+
+txnReturn:
+		/* release connection lock */
+		ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
+
+		if( !settle ) {
+			send_ldap_result( op, rs );
+			return rs->sr_err;
+		}
+	}
+#endif
+
 	ctrls[num_ctrls] = 0;
 
-	/* add opattrs to shadow as well, only missing attrs will actually
-	 * be added; helps compatibility with older OL versions */
-	rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
+	/* check entry's schema */
+	rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
+		get_relax(op), 1, &rs->sr_text, textbuf, textlen );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE,
-			LDAP_XSTRING(bdb_add) ": entry failed op attrs add: "
+			LDAP_XSTRING(bdb_add) ": entry failed schema check: "
 			"%s (%d)\n", rs->sr_text, rs->sr_err, 0 );
 		goto return_results;
 	}
 
-	/* check entry's schema */
-	rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
-		get_manageDIT(op), &rs->sr_text, textbuf, textlen );
+	/* add opattrs to shadow as well, only missing attrs will actually
+	 * be added; helps compatibility with older OL versions */
+	rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE,
-			LDAP_XSTRING(bdb_add) ": entry failed schema check: "
+			LDAP_XSTRING(bdb_add) ": entry failed op attrs add: "
 			"%s (%d)\n", rs->sr_text, rs->sr_err, 0 );
 		goto return_results;
 	}
@@ -85,12 +129,15 @@
 		goto return_results;
 	}
 
+	/* Get our thread locker ID */
+	rs->sr_err = LOCK_ID( bdb->bi_dbenv, &rlocker );
+
 	if( 0 ) {
 retry:	/* transaction retry */
 		if( p ) {
 			/* free parent and reader lock */
 			if ( p != (Entry *)&slap_entry_root ) {
-				bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
+				bdb_unlocked_cache_return_entry_r( bdb, p );
 			}
 			p = NULL;
 		}
@@ -172,7 +219,7 @@
 		rs->sr_ref = is_entry_referral( p )
 			? get_entry_referrals( op, p )
 			: NULL;
-		bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
+		bdb_unlocked_cache_return_entry_r( bdb, p );
 		p = NULL;
 		Debug( LDAP_DEBUG_TRACE,
 			LDAP_XSTRING(bdb_add) ": parent "
@@ -211,6 +258,7 @@
 			rs->sr_text = "parent is a subentry";
 			goto return_results;;
 		}
+
 		if ( is_entry_alias( p ) ) {
 			/* parent is an alias, don't allow add */
 			Debug( LDAP_DEBUG_TRACE,
@@ -220,22 +268,23 @@
 			rs->sr_text = "parent is an alias";
 			goto return_results;;
 		}
-	
+
 		if ( is_entry_referral( p ) ) {
 			/* parent is a referral, don't allow add */
 			rs->sr_matched = ber_strdup_x( p->e_name.bv_val,
 				op->o_tmpmemctx );
 			rs->sr_ref = get_entry_referrals( op, p );
-			bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
+			bdb_unlocked_cache_return_entry_r( bdb, p );
 			p = NULL;
 			Debug( LDAP_DEBUG_TRACE,
 				LDAP_XSTRING(bdb_add) ": parent is referral\n",
 				0, 0, 0 );
-	
+
 			rs->sr_err = LDAP_REFERRAL;
 			rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
 			goto return_results;
 		}
+
 	}
 
 	if ( subentry ) {
@@ -245,7 +294,7 @@
 
 	/* free parent and reader lock */
 	if ( p != (Entry *)&slap_entry_root ) {
-		bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
+		bdb_unlocked_cache_return_entry_r( bdb, p );
 	}
 	p = NULL;
 
@@ -352,7 +401,11 @@
 			Debug( LDAP_DEBUG_TRACE,
 				"<=- " LDAP_XSTRING(bdb_add) ": post-read "
 				"failed!\n", 0, 0, 0 );
-			goto return_results;
+			if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
+				/* FIXME: is it correct to abort
+				 * operation if control fails? */
+				goto return_results;
+			}
 		}
 	}
 
@@ -367,17 +420,17 @@
 
 	} else {
 		struct berval nrdn;
-		Entry *e = entry_dup( op->ora_e );
 
 		/* pick the RDN if not suffix; otherwise pick the entire DN */
 		if (pdn.bv_len) {
-			nrdn.bv_val = e->e_nname.bv_val;
+			nrdn.bv_val = op->ora_e->e_nname.bv_val;
 			nrdn.bv_len = pdn.bv_val - op->ora_e->e_nname.bv_val - 1;
 		} else {
-			nrdn = e->e_nname;
+			nrdn = op->ora_e->e_nname;
 		}
 
-		bdb_cache_add( bdb, ei, e, &nrdn, locker );
+		/* Use the thread locker here, outside the txn */
+		bdb_cache_add( bdb, ei, op->ora_e, &nrdn, rlocker, &lock );
 
 		if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
 			rs->sr_text = "txn_commit failed";
@@ -406,6 +459,7 @@
 	if( num_ctrls ) rs->sr_ctrls = ctrls;
 
 return_results:
+	success = rs->sr_err;
 	send_ldap_result( op, rs );
 	slap_graduate_commit_csn( op );
 
@@ -414,14 +468,26 @@
 	}
 	op->o_private = NULL;
 
+	if( success == LDAP_SUCCESS ) {
+		/* We own the entry now, and it can be purged at will
+		 * Check to make sure it's the same entry we entered with.
+		 * Possibly a callback may have mucked with it, although
+		 * in general callbacks should treat the entry as read-only.
+		 */
+		bdb_cache_return_entry_r( bdb, oe, &lock );
+		if ( op->ora_e == oe )
+			op->ora_e = NULL;
+
+		if ( bdb->bi_txn_cp_kbyte ) {
+			TXN_CHECKPOINT( bdb->bi_dbenv,
+				bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
+		}
+	}
+
 	if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
 		slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
 		slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
 	}
 
-	if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
-		TXN_CHECKPOINT( bdb->bi_dbenv,
-			bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
-	}
 	return rs->sr_err;
 }

Modified: openldap/trunk/servers/slapd/back-bdb/attr.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/attr.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/attr.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* attr.c - backend routines for dealing with attributes */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/attr.c,v 1.19.2.10 2007/01/02 21:43:59 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/attr.c,v 1.36.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -94,7 +94,7 @@
 	int			argc,
 	char		**argv )
 {
-	int rc;
+	int rc = 0;
 	int	i;
 	slap_mask_t mask;
 	char **attrs;
@@ -116,7 +116,8 @@
 			fprintf( stderr, "%s: line %d: "
 				"no indexes specified: %s\n",
 				fname, lineno, argv[1] );
-			return LDAP_PARAM_ERROR;
+			rc = LDAP_PARAM_ERROR;
+			goto done;
 		}
 	}
 
@@ -134,7 +135,8 @@
 				fprintf( stderr, "%s: line %d: "
 					"index type \"%s\" undefined\n",
 					fname, lineno, indexes[i] );
-				return LDAP_PARAM_ERROR;
+				rc = LDAP_PARAM_ERROR;
+				goto done;
 			}
 
 			mask |= index;
@@ -145,7 +147,8 @@
 		fprintf( stderr, "%s: line %d: "
 			"no indexes selected\n",
 			fname, lineno );
-		return LDAP_PARAM_ERROR;
+		rc = LDAP_PARAM_ERROR;
+		goto done;
 	}
 
 	for ( i = 0; attrs[i] != NULL; i++ ) {
@@ -169,7 +172,7 @@
 				fprintf( stderr, "%s: line %d: "
 					"index component reference\"%s\" undefined\n",
 					fname, lineno, attrs[i] );
-				return rc;
+				goto done;
 			}
 			cr->cr_indexmask = mask;
 			/*
@@ -180,11 +183,6 @@
 			cr = NULL;
 		}
 #endif
-		a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
-
-#ifdef LDAP_COMP_MATCH
-		a->ai_cr = NULL;
-#endif
 		ad = NULL;
 		rc = slap_str2ad( attrs[i], &ad, &text );
 
@@ -192,14 +190,15 @@
 			fprintf( stderr, "%s: line %d: "
 				"index attribute \"%s\" undefined\n",
 				fname, lineno, attrs[i] );
-			return rc;
+			goto done;
 		}
 
 		if( slap_ad_is_binary( ad ) ) {
 			fprintf( stderr, "%s: line %d: "
 				"index of attribute \"%s\" disallowed\n",
 				fname, lineno, attrs[i] );
-			return LDAP_UNWILLING_TO_PERFORM;
+			rc = LDAP_UNWILLING_TO_PERFORM;
+			goto done;
 		}
 
 		if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !(
@@ -210,7 +209,8 @@
 			fprintf( stderr, "%s: line %d: "
 				"approx index of attribute \"%s\" disallowed\n",
 				fname, lineno, attrs[i] );
-			return LDAP_INAPPROPRIATE_MATCHING;
+			rc = LDAP_INAPPROPRIATE_MATCHING;
+			goto done;
 		}
 
 		if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !(
@@ -221,7 +221,8 @@
 			fprintf( stderr, "%s: line %d: "
 				"equality index of attribute \"%s\" disallowed\n",
 				fname, lineno, attrs[i] );
-			return LDAP_INAPPROPRIATE_MATCHING;
+			rc = LDAP_INAPPROPRIATE_MATCHING;
+			goto done;
 		}
 
 		if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !(
@@ -232,12 +233,18 @@
 			fprintf( stderr, "%s: line %d: "
 				"substr index of attribute \"%s\" disallowed\n",
 				fname, lineno, attrs[i] );
-			return LDAP_INAPPROPRIATE_MATCHING;
+			rc = LDAP_INAPPROPRIATE_MATCHING;
+			goto done;
 		}
 
 		Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n",
 			ad->ad_cname.bv_val, mask, 0 ); 
 
+		a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
+
+#ifdef LDAP_COMP_MATCH
+		a->ai_cr = NULL;
+#endif
 		a->ai_desc = ad;
 
 		if ( bdb->bi_flags & BDB_IS_OPEN ) {
@@ -260,14 +267,16 @@
 				rc = insert_component_reference( cr, &a_cr->ai_cr );
 				if ( rc != LDAP_SUCCESS) {
 					fprintf( stderr, " error during inserting component reference in %s ", attrs[i]);
-					return LDAP_PARAM_ERROR;
+					rc = LDAP_PARAM_ERROR;
+					goto done;
 				}
 				continue;
 			} else {
 				rc = insert_component_reference( cr, &a->ai_cr );
 				if ( rc != LDAP_SUCCESS) {
 					fprintf( stderr, " error during inserting component reference in %s ", attrs[i]);
-					return LDAP_PARAM_ERROR;
+					rc = LDAP_PARAM_ERROR;
+					goto done;
 				}
 			}
 		}
@@ -285,18 +294,20 @@
 				ch_free( a );
 				continue;
 			}
-			fprintf( stderr, "%s: line %d: duplicate index definition "
-				"for attr \"%s\"" SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+			fprintf( stderr,
+				"%s: line %d: duplicate index definition for attr \"%s\".\n",
 				fname, lineno, attrs[i] );
 
-			return LDAP_PARAM_ERROR;
+			rc = LDAP_PARAM_ERROR;
+			goto done;
 		}
 	}
 
+done:
 	ldap_charray_free( attrs );
 	if ( indexes != NULL ) ldap_charray_free( indexes );
 
-	return LDAP_SUCCESS;
+	return rc;
 }
 
 static int

Modified: openldap/trunk/servers/slapd/back-bdb/back-bdb.h
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/back-bdb.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/back-bdb.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* back-bdb.h - bdb back-end header file */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/back-bdb.h,v 1.117.2.14 2007/08/06 12:32:51 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/back-bdb.h,v 1.141.2.10 2007/12/06 17:29:52 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -58,6 +58,30 @@
 #define	BDB_PAGESIZE	4096	/* BDB's original default */
 #endif
 
+/* 4.6.18 redefines cursor->locker */
+#if DB_VERSION_FULL >= 0x04060012
+
+struct __db_locker {
+	u_int32_t	id;
+};
+
+typedef struct __db_locker * BDB_LOCKER;
+
+extern int __lock_getlocker(DB_LOCKTAB *lt, u_int32_t locker, int create, DB_LOCKER **ret);
+
+#define CURSOR_SETLOCKER(cursor, id)	cursor->locker = id
+#define CURSOR_GETLOCKER(cursor)	cursor->locker
+#define BDB_LOCKID(locker)	locker->id
+#else
+
+typedef u_int32_t BDB_LOCKER;
+
+#define CURSOR_SETLOCKER(cursor, id)	cursor->locker = id
+#define CURSOR_GETLOCKER(cursor)	cursor->locker
+#define BDB_LOCKID(locker)	locker
+
+#endif
+
 #define DEFAULT_CACHE_SIZE     1000
 
 /* The default search IDL stack cache depth */
@@ -70,6 +94,7 @@
 	struct berval kstr;
 	ID      *idl;
 	DB      *db;
+	int		idl_flags;
 	struct bdb_idl_cache_entry_s* idl_lru_prev;
 	struct bdb_idl_cache_entry_s* idl_lru_next;
 } bdb_idl_cache_entry_t;
@@ -83,7 +108,7 @@
 	 * to avoid conflicting with BDB's internal locks. So add a byte here
 	 * that is always zero.
 	 */
-	char bei_lockpad;
+	short bei_lockpad;
 
 	short bei_state;
 #define	CACHE_ENTRY_DELETED	1
@@ -93,6 +118,9 @@
 #define	CACHE_ENTRY_LOADING	0x10
 #define	CACHE_ENTRY_WALKING	0x20
 #define	CACHE_ENTRY_ONELEVEL	0x40
+#define	CACHE_ENTRY_REFERENCED	0x80
+#define	CACHE_ENTRY_NOT_CACHED	0x100
+	int bei_finders;
 
 	/*
 	 * remaining fields require backend cache lock to access
@@ -120,20 +148,23 @@
 
 /* for the in-core cache of entries */
 typedef struct bdb_cache {
-	int             c_maxsize;
-	int             c_cursize;
-	int		c_minfree;
-	int		c_eiused;	/* EntryInfo's in use */
-	int		c_leaves;	/* EntryInfo leaf nodes */
-	EntryInfo	c_dntree;
 	EntryInfo	*c_eifree;	/* free list */
-	Avlnode         *c_idtree;
+	Avlnode		*c_idtree;
 	EntryInfo	*c_lruhead;	/* lru - add accessed entries here */
 	EntryInfo	*c_lrutail;	/* lru - rem lru entries from here */
+	EntryInfo	c_dntree;
+	unsigned	c_maxsize;
+	int		c_cursize;
+	unsigned	c_minfree;
+	unsigned	c_eimax;
+	int		c_eiused;	/* EntryInfo's in use */
+	int		c_leaves;	/* EntryInfo leaf nodes */
+	int		c_purging;
+	BDB_LOCKER	c_locker;	/* used by lru cleaner */
 	ldap_pvt_thread_rdwr_t c_rwlock;
-	ldap_pvt_thread_mutex_t lru_head_mutex;
-	ldap_pvt_thread_mutex_t lru_tail_mutex;
-	u_int32_t	c_locker;	/* used by lru cleaner */
+	ldap_pvt_thread_mutex_t c_lru_mutex;
+	ldap_pvt_thread_mutex_t c_count_mutex;
+	ldap_pvt_thread_mutex_t c_eifree_mutex;
 #ifdef SLAP_ZONE_ALLOC
 	void *c_zctx;
 #endif
@@ -145,10 +176,19 @@
 #define BDB_INDICES		128
 
 struct bdb_db_info {
-	char		*bdi_name;
+	struct berval	bdi_name;
 	DB			*bdi_db;
 };
 
+#ifdef LDAP_DEVEL
+#define BDB_MONITOR_IDX
+#endif /* LDAP_DEVEL */
+
+typedef struct bdb_monitor_t {
+	void		*bdm_cb;
+	struct berval	bdm_ndn;
+} bdb_monitor_t;
+
 /* From ldap_rq.h */
 struct re_s;
 
@@ -185,7 +225,7 @@
 
 	ID			bi_lastid;
 	ldap_pvt_thread_mutex_t	bi_lastid_mutex;
-	int		bi_idl_cache_max_size;
+	unsigned	bi_idl_cache_max_size;
 	int		bi_idl_cache_size;
 	Avlnode		*bi_idl_tree;
 	bdb_idl_cache_entry_t	*bi_idl_lru_head;
@@ -195,6 +235,13 @@
 	alock_info_t	bi_alock_info;
 	char		*bi_db_config_path;
 	BerVarray	bi_db_config;
+	bdb_monitor_t	bi_monitor;
+
+#ifdef BDB_MONITOR_IDX
+	ldap_pvt_thread_mutex_t	bi_idx_mutex;
+	Avlnode		*bi_idx;
+#endif /* BDB_MONITOR_IDX */
+
 	int		bi_flags;
 #define	BDB_IS_OPEN		0x01
 #define	BDB_HAS_CONFIG	0x02
@@ -210,6 +257,7 @@
 #define bi_id2entry	bi_databases[BDB_ID2ENTRY]
 #define bi_dn2id	bi_databases[BDB_DN2ID]
 
+
 struct bdb_lock_info {
 	struct bdb_lock_info *bli_next;
 	ID		bli_id;
@@ -219,8 +267,8 @@
 struct bdb_op_info {
 	BackendDB*	boi_bdb;
 	DB_TXN*		boi_txn;
+	BDB_LOCKER	boi_locker;
 	u_int32_t	boi_err;
-	u_int32_t	boi_locker;
 	int		boi_acl_cache;
 	struct bdb_lock_info *boi_locks;	/* used when no txn */
 };
@@ -260,8 +308,40 @@
 	((db)->open)(db, NULL, file, name, type, flags, mode)
 #endif
 
+/* BDB 4.6.18 makes locker a struct instead of an int */
+#if DB_VERSION_FULL >= 0x04060012
+#undef TXN_ID
+#define TXN_ID(txn)	(txn)->locker
 #endif
 
+/* #undef BDB_LOG_DEBUG */
+
+#ifdef BDB_LOG_DEBUG
+
+/* env->log_printf appeared in 4.4 */
+#if DB_VERSION_FULL >= 0x04040000
+#define	BDB_LOG_PRINTF(env,txn,fmt,...)	(env)->log_printf((env),(txn),(fmt),__VA_ARGS__)
+#else
+extern int __db_logmsg(const DB_ENV *env, DB_TXN *txn, const char *op, u_int32_t flags,
+	const char *fmt,...);
+#define	BDB_LOG_PRINTF(env,txn,fmt,...)	__db_logmsg((env),(txn),"DIAGNOSTIC",0,(fmt),__VA_ARGS__)
+#endif
+
+/* !BDB_LOG_DEBUG */
+#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+	(defined(__GNUC__) && __GNUC__ >= 3 && !defined(__STRICT_ANSI__))
+#define BDB_LOG_PRINTF(a,b,c,...)
+#else
+#define BDB_LOG_PRINTF (void)	/* will evaluate and discard the arguments */
+
+#endif /* BDB_LOG_DEBUG */
+
+#endif
+
+#ifndef DB_BUFFER_SMALL
+#define DB_BUFFER_SMALL			ENOMEM
+#endif
+
 #define BDB_REUSE_LOCKERS
 
 #define BDB_CSN_COMMIT	0

Modified: openldap/trunk/servers/slapd/back-bdb/bind.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* bind.c - bdb backend bind routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/bind.c,v 1.41.2.4 2007/01/02 21:43:59 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/bind.c,v 1.45.2.3 2007/09/07 10:34:18 ando Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -17,7 +17,6 @@
 #include "portable.h"
 
 #include <stdio.h>
-#include <ac/krb.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
 
@@ -30,16 +29,10 @@
 	Entry		*e;
 	Attribute	*a;
 	EntryInfo	*ei;
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-	char		krbname[MAX_K_NAME_SZ + 1];
-	AttributeDescription *krbattr = slap_schema.si_ad_krbName;
-	struct berval	krbval;
-	AUTH_DAT	ad;
-#endif
 
 	AttributeDescription *password = slap_schema.si_ad_userPassword;
 
-	u_int32_t	locker;
+	BDB_LOCKER	locker;
 	DB_LOCK		lock;
 
 	Debug( LDAP_DEBUG_ARGS,
@@ -47,10 +40,19 @@
 		op->o_req_dn.bv_val, 0, 0);
 
 	/* allow noauth binds */
-	if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
-		ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
-		/* front end will send result */
-		return LDAP_SUCCESS;
+	switch ( be_rootdn_bind( op, NULL ) ) {
+	case LDAP_SUCCESS:
+		/* frontend will send result */
+		return rs->sr_err;
+
+	default:
+		/* give the database a chanche */
+		/* NOTE: this behavior departs from that of other backends,
+		 * since the others, in case of password checking failure
+		 * do not give the database a chance.  If an entry with
+		 * rootdn's name does not exist in the database the result
+		 * will be the same.  See ITS#4962 for discussion. */
+		break;
 	}
 
 	rs->sr_err = LOCK_ID(bdb->bi_dbenv, &locker);
@@ -88,8 +90,7 @@
 	e = ei->bei_e;
 	if ( rs->sr_err == DB_NOTFOUND ) {
 		if( e != NULL ) {
-			bdb_cache_return_entry_r( bdb->bi_dbenv,
-				&bdb->bi_cache, e, &lock );
+			bdb_cache_return_entry_r( bdb, e, &lock );
 			e = NULL;
 		}
 
@@ -145,50 +146,8 @@
 		rs->sr_err = 0;
 		break;
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-	case LDAP_AUTH_KRBV41:
-		if ( krbv4_ldap_auth( op->o_bd, &op->oq_bind.rb_cred, &ad )
-			!= LDAP_SUCCESS )
-		{
-			rs->sr_err = LDAP_INVALID_CREDENTIALS,
-			goto done;
-		}
-
-		rs->sr_err = access_allowed( op, e,
-			krbattr, NULL, ACL_AUTH, NULL );
-		if ( ! rs->sr_err ) {
-			rs->sr_err = LDAP_INSUFFICIENT_ACCESS,
-			goto done;
-		}
-
-		krbval.bv_len = sprintf( krbname, "%s%s%s@%s", ad.pname,
-			*ad.pinst ? "." : "", ad.pinst, ad.prealm );
-
-		if ( (a = attr_find( e->e_attrs, krbattr )) == NULL ) {
-			/*
-			 * no krbname values present: check against DN
-			 */
-			if ( strcasecmp( op->o_req_dn.bv_val, krbname ) == 0 ) {
-				rs->sr_err = 0;
-				break;
-			}
-			rs->sr_err = LDAP_INAPPROPRIATE_AUTH,
-			goto done;
-
-		} else {	/* look for krbname match */
-			krbval.bv_val = krbname;
-
-			if ( value_find( a->a_desc, a->a_vals, &krbval ) != 0 ) {
-				rs->sr_err = LDAP_INVALID_CREDENTIALS;
-				goto done;
-			}
-		}
-		rs->sr_err = 0;
-		break;
-#endif
-
 	default:
-		assert( 0 ); /* should not be unreachable */
+		assert( 0 ); /* should not be reachable */
 		rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
 		rs->sr_text = "authentication method not supported";
 	}
@@ -196,7 +155,7 @@
 done:
 	/* free entry and reader lock */
 	if( e != NULL ) {
-		bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
+		bdb_cache_return_entry_r( bdb, e, &lock );
 	}
 
 	LOCK_ID_FREE(bdb->bi_dbenv, locker);

Modified: openldap/trunk/servers/slapd/back-bdb/cache.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/cache.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/cache.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* cache.c - routines to maintain an in-core cache of entries */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/cache.c,v 1.88.2.21 2007/01/25 12:42:38 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/cache.c,v 1.120.2.7 2007/12/06 05:43:27 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -29,52 +29,143 @@
 #include "ldap_rq.h"
 
 #ifdef BDB_HIER
-#define bdb_cache_lru_add	hdb_cache_lru_add
+#define bdb_cache_lru_purge	hdb_cache_lru_purge
 #endif
-static void bdb_cache_lru_add( struct bdb_info *bdb, EntryInfo *ei );
+static void bdb_cache_lru_purge( struct bdb_info *bdb );
 
 static int	bdb_cache_delete_internal(Cache *cache, EntryInfo *e, int decr);
 #ifdef LDAP_DEBUG
+#define SLAPD_UNUSED
 #ifdef SLAPD_UNUSED
 static void	bdb_lru_print(Cache *cache);
 #endif
 #endif
 
+/* For concurrency experiments only! */
+#if 0
+#define	ldap_pvt_thread_rdwr_wlock(a)	0
+#define	ldap_pvt_thread_rdwr_wunlock(a)	0
+#define	ldap_pvt_thread_rdwr_rlock(a)	0
+#define	ldap_pvt_thread_rdwr_runlock(a)	0
+#endif
+
+#if 0
+#define ldap_pvt_thread_mutex_trylock(a) 0
+#endif
+
 static EntryInfo *
 bdb_cache_entryinfo_new( Cache *cache )
 {
 	EntryInfo *ei = NULL;
 
 	if ( cache->c_eifree ) {
-		ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
+		ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex );
 		if ( cache->c_eifree ) {
 			ei = cache->c_eifree;
 			cache->c_eifree = ei->bei_lrunext;
+			ei->bei_finders = 0;
 		}
-		ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
+		ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex );
 	}
-	if ( ei ) {
-		ei->bei_lrunext = NULL;
-		ei->bei_state = 0;
-	} else {
-		ei = ch_calloc(1, sizeof(struct bdb_entry_info));
+	if ( !ei ) {
+		ei = ch_calloc(1, sizeof(EntryInfo));
 		ldap_pvt_thread_mutex_init( &ei->bei_kids_mutex );
 	}
 
+	ei->bei_state = CACHE_ENTRY_REFERENCED;
+
 	return ei;
 }
 
+static void
+bdb_cache_entryinfo_free( Cache *cache, EntryInfo *ei )
+{
+	free( ei->bei_nrdn.bv_val );
+	ei->bei_nrdn.bv_val = NULL;
+#ifdef BDB_HIER
+	free( ei->bei_rdn.bv_val );
+	ei->bei_rdn.bv_val = NULL;
+	ei->bei_modrdns = 0;
+	ei->bei_ckids = 0;
+	ei->bei_dkids = 0;
+#endif
+	ei->bei_parent = NULL;
+	ei->bei_kids = NULL;
+	ei->bei_lruprev = NULL;
+
+	ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex );
+	ei->bei_lrunext = cache->c_eifree;
+	cache->c_eifree = ei;
+	ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex );
+}
+
+#define LRU_DEL( c, e ) do { \
+	if ( e == (c)->c_lruhead ) (c)->c_lruhead = e->bei_lruprev; \
+	if ( e == (c)->c_lrutail ) (c)->c_lrutail = e->bei_lruprev; \
+	e->bei_lrunext->bei_lruprev = e->bei_lruprev; \
+	e->bei_lruprev->bei_lrunext = e->bei_lrunext; \
+	e->bei_lruprev = NULL; \
+} while ( 0 )
+
+/* Note - we now use a Second-Chance / Clock algorithm instead of
+ * Least-Recently-Used. This tremendously improves concurrency
+ * because we no longer need to manipulate the lists every time an
+ * entry is touched. We only need to lock the lists when adding
+ * or deleting an entry. It's now a circular doubly-linked list.
+ * We always append to the tail, but the head traverses the circle
+ * during a purge operation.
+ */
+static void
+bdb_cache_lru_link( struct bdb_info *bdb, EntryInfo *ei )
+{
+
+	/* Already linked, ignore */
+	if ( ei->bei_lruprev )
+		return;
+
+	/* Insert into circular LRU list */
+	ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex );
+
+	ei->bei_lruprev = bdb->bi_cache.c_lrutail;
+	if ( bdb->bi_cache.c_lrutail ) {
+		ei->bei_lrunext = bdb->bi_cache.c_lrutail->bei_lrunext;
+		bdb->bi_cache.c_lrutail->bei_lrunext = ei;
+		if ( ei->bei_lrunext )
+			ei->bei_lrunext->bei_lruprev = ei;
+	} else {
+		ei->bei_lrunext = ei->bei_lruprev = ei;
+		bdb->bi_cache.c_lruhead = ei;
+	}
+	bdb->bi_cache.c_lrutail = ei;
+	ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
+}
+
+#ifdef NO_THREADS
+#define NO_DB_LOCK
+#endif
+
+/* #define NO_DB_LOCK 1 */
+/* Note: The BerkeleyDB locks are much slower than regular
+ * mutexes or rdwr locks. But the BDB implementation has the
+ * advantage of using a fixed size lock table, instead of
+ * allocating a lock object per entry in the DB. That's a
+ * key benefit for scaling. It also frees us from worrying
+ * about undetectable deadlocks between BDB activity and our
+ * own cache activity. It's still worth exploring faster
+ * alternatives though.
+ */
+
 /* Atomically release and reacquire a lock */
 int
 bdb_cache_entry_db_relock(
-	DB_ENV *env,
-	u_int32_t locker,
+	struct bdb_info *bdb,
+	BDB_LOCKER locker,
 	EntryInfo *ei,
 	int rw,
 	int tryOnly,
 	DB_LOCK *lock )
 {
-#ifdef NO_THREADS
+#ifdef NO_DB_LOCK
 	return 0;
 #else
 	int	rc;
@@ -92,7 +183,7 @@
 	list[1].lock = *lock;
 	list[1].mode = rw ? DB_LOCK_WRITE : DB_LOCK_READ;
 	list[1].obj = &lockobj;
-	rc = env->lock_vec(env, locker, tryOnly ? DB_LOCK_NOWAIT : 0,
+	rc = bdb->bi_dbenv->lock_vec(bdb->bi_dbenv, BDB_LOCKID(locker), tryOnly ? DB_LOCK_NOWAIT : 0,
 		list, 2, NULL );
 
 	if (rc && !tryOnly) {
@@ -107,10 +198,10 @@
 }
 
 static int
-bdb_cache_entry_db_lock( DB_ENV *env, u_int32_t locker, EntryInfo *ei,
+bdb_cache_entry_db_lock( struct bdb_info *bdb, BDB_LOCKER locker, EntryInfo *ei,
 	int rw, int tryOnly, DB_LOCK *lock )
 {
-#ifdef NO_THREADS
+#ifdef NO_DB_LOCK
 	return 0;
 #else
 	int       rc;
@@ -127,7 +218,7 @@
 	lockobj.data = &ei->bei_id;
 	lockobj.size = sizeof(ei->bei_id) + 1;
 
-	rc = LOCK_GET(env, locker, tryOnly ? DB_LOCK_NOWAIT : 0,
+	rc = LOCK_GET(bdb->bi_dbenv, BDB_LOCKID(locker), tryOnly ? DB_LOCK_NOWAIT : 0,
 					&lockobj, db_rw, lock);
 	if (rc && !tryOnly) {
 		Debug( LDAP_DEBUG_TRACE,
@@ -135,24 +226,46 @@
 			ei->bei_id, rw, rc );
 	}
 	return rc;
-#endif /* NO_THREADS */
+#endif /* NO_DB_LOCK */
 }
 
 int
-bdb_cache_entry_db_unlock ( DB_ENV *env, DB_LOCK *lock )
+bdb_cache_entry_db_unlock ( struct bdb_info *bdb, DB_LOCK *lock )
 {
-#ifdef NO_THREADS
+#ifdef NO_DB_LOCK
 	return 0;
 #else
 	int rc;
 
 	if ( !lock || lock->mode == DB_LOCK_NG ) return 0;
 
-	rc = LOCK_PUT ( env, lock );
+	rc = LOCK_PUT ( bdb->bi_dbenv, lock );
 	return rc;
 #endif
 }
 
+void
+bdb_cache_return_entry_rw( struct bdb_info *bdb, Entry *e,
+	int rw, DB_LOCK *lock )
+{
+	EntryInfo *ei;
+	int free = 0;
+
+	bdb_cache_entry_db_unlock( bdb, lock );
+	ei = e->e_private;
+	bdb_cache_entryinfo_lock( ei );
+	if ( ei->bei_state & CACHE_ENTRY_NOT_CACHED ) {
+		ei->bei_e = NULL;
+		ei->bei_state ^= CACHE_ENTRY_NOT_CACHED;
+		free = 1;
+	}
+	bdb_cache_entryinfo_unlock( ei );
+	if ( free ) {
+		e->e_private = NULL;
+		bdb_entry_return( e );
+	}
+}
+
 static int
 bdb_cache_entryinfo_destroy( EntryInfo *e )
 {
@@ -165,34 +278,6 @@
 	return 0;
 }
 
-#define LRU_DELETE( cache, ei ) do { \
-	if ( (ei)->bei_lruprev != NULL ) { \
-		(ei)->bei_lruprev->bei_lrunext = (ei)->bei_lrunext; \
-	} else { \
-		(cache)->c_lruhead = (ei)->bei_lrunext; \
-	} \
-	if ( (ei)->bei_lrunext != NULL ) { \
-		(ei)->bei_lrunext->bei_lruprev = (ei)->bei_lruprev; \
-	} else { \
-		(cache)->c_lrutail = (ei)->bei_lruprev; \
-	} \
-	(ei)->bei_lrunext = (ei)->bei_lruprev = NULL; \
-} while(0)
-
-#define LRU_ADD( cache, ei ) do { \
-	(ei)->bei_lrunext = (cache)->c_lruhead; \
-	if ( (ei)->bei_lrunext != NULL ) { \
-		(ei)->bei_lrunext->bei_lruprev = (ei); \
-	} \
-	(cache)->c_lruhead = (ei); \
-	(ei)->bei_lruprev = NULL; \
-	if ( !ldap_pvt_thread_mutex_trylock( &(cache)->lru_tail_mutex )) { \
-		if ( (cache)->c_lrutail == NULL ) \
-			(cache)->c_lrutail = (ei); \
-		ldap_pvt_thread_mutex_unlock( &(cache)->lru_tail_mutex ); \
-	} \
-} while(0)
-
 /* Do a length-ordered sort on normalized RDNs */
 static int
 bdb_rdn_cmp( const void *v_e1, const void *v_e2 )
@@ -213,6 +298,14 @@
 	return e1->bei_id - e2->bei_id;
 }
 
+static int
+bdb_id_dup_err( void *v1, void *v2 )
+{
+	EntryInfo *e2 = v2;
+	e2->bei_lrunext = v1;
+	return -1;
+}
+
 /* Create an entryinfo in the cache. Caller must release the locks later.
  */
 static int
@@ -240,10 +333,10 @@
 #endif
 
 	/* Add to cache ID tree */
-	if (avl_insert( &bdb->bi_cache.c_idtree, ei2, bdb_id_cmp, avl_dup_error )) {
-		EntryInfo *eix;
-		eix = avl_find( bdb->bi_cache.c_idtree, ei2, bdb_id_cmp );
-		bdb_cache_entryinfo_destroy( ei2 );
+	if (avl_insert( &bdb->bi_cache.c_idtree, ei2, bdb_id_cmp,
+		bdb_id_dup_err )) {
+		EntryInfo *eix = ei2->bei_lrunext;
+		bdb_cache_entryinfo_free( &bdb->bi_cache, ei2 );
 		ei2 = eix;
 #ifdef BDB_HIER
 		/* It got freed above because its value was
@@ -252,6 +345,8 @@
 		ei->bei_rdn.bv_val = NULL;
 #endif
 	} else {
+		int rc;
+
 		bdb->bi_cache.c_eiused++;
 		ber_dupbv( &ei2->bei_nrdn, &ei->bei_nrdn );
 
@@ -261,8 +356,13 @@
 		 */
 		if ( ei->bei_parent->bei_kids || !ei->bei_parent->bei_id )
 			bdb->bi_cache.c_leaves++;
-		avl_insert( &ei->bei_parent->bei_kids, ei2, bdb_rdn_cmp,
+		rc = avl_insert( &ei->bei_parent->bei_kids, ei2, bdb_rdn_cmp,
 			avl_dup_error );
+		if ( rc ) {
+			/* This should never happen; entry cache is corrupt */
+			bdb->bi_dbenv->log_flush( bdb->bi_dbenv, NULL );
+			assert( !rc );
+		}
 #ifdef BDB_HIER
 		ei->bei_parent->bei_ckids++;
 #endif
@@ -281,7 +381,7 @@
 int
 bdb_cache_find_ndn(
 	Operation	*op,
-	DB_TXN		*txn,
+	BDB_LOCKER		locker,
 	struct berval	*ndn,
 	EntryInfo	**res )
 {
@@ -315,9 +415,11 @@
 	}
 	
 	for ( bdb_cache_entryinfo_lock( eip ); eip; ) {
+		eip->bei_state |= CACHE_ENTRY_REFERENCED;
 		ei.bei_parent = eip;
 		ei2 = (EntryInfo *)avl_find( eip->bei_kids, &ei, bdb_rdn_cmp );
 		if ( !ei2 ) {
+			DB_LOCK lock;
 			int len = ei.bei_nrdn.bv_len;
 				
 			if ( BER_BVISEMPTY( ndn )) {
@@ -329,18 +431,27 @@
 				(ei.bei_nrdn.bv_val - ndn->bv_val);
 			bdb_cache_entryinfo_unlock( eip );
 
-			rc = bdb_dn2id( op, txn, &ei.bei_nrdn, &ei );
+			BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Reading %s",
+				ei.bei_nrdn.bv_val );
+
+			lock.mode = DB_LOCK_NG;
+			rc = bdb_dn2id( op, &ei.bei_nrdn, &ei, locker, &lock );
 			if (rc) {
 				bdb_cache_entryinfo_lock( eip );
+				bdb_cache_entry_db_unlock( bdb, &lock );
 				*res = eip;
 				return rc;
 			}
 
+			BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Read got %s(%d)",
+				ei.bei_nrdn.bv_val, ei.bei_id );
+
 			/* DN exists but needs to be added to cache */
 			ei.bei_nrdn.bv_len = len;
 			rc = bdb_entryinfo_add_internal( bdb, &ei, &ei2 );
 			/* add_internal left eip and c_rwlock locked */
 			ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
+			bdb_cache_entry_db_unlock( bdb, &lock );
 			if ( rc ) {
 				*res = eip;
 				return rc;
@@ -384,22 +495,20 @@
 int
 hdb_cache_find_parent(
 	Operation *op,
-	DB_TXN *txn,
-	u_int32_t	locker,
+	BDB_LOCKER	locker,
 	ID id,
 	EntryInfo **res )
 {
 	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
 	EntryInfo ei, eip, *ei2 = NULL, *ein = NULL, *eir = NULL;
 	int rc;
-	int addlru = 0;
 
 	ei.bei_id = id;
 	ei.bei_kids = NULL;
 	ei.bei_ckids = 0;
 
 	for (;;) {
-		rc = hdb_dn2id_parent( op, txn, locker, &ei, &eip.bei_id );
+		rc = hdb_dn2id_parent( op, locker, &ei, &eip.bei_id );
 		if ( rc ) break;
 
 		/* Save the previous node, if any */
@@ -418,19 +527,19 @@
 		ei.bei_ckids = 0;
 		
 		/* This node is not fully connected yet */
-		ein->bei_state = CACHE_ENTRY_NOT_LINKED;
+		ein->bei_state |= CACHE_ENTRY_NOT_LINKED;
 
 		/* Insert this node into the ID tree */
 		ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
 		if ( avl_insert( &bdb->bi_cache.c_idtree, (caddr_t)ein,
-			bdb_id_cmp, avl_dup_error ) ) {
+			bdb_id_cmp, bdb_id_dup_err ) ) {
+			EntryInfo *eix = ein->bei_lrunext;
 
 			/* Someone else created this node just before us.
 			 * Free our new copy and use the existing one.
 			 */
-			bdb_cache_entryinfo_destroy( ein );
-			ein = (EntryInfo *)avl_find( bdb->bi_cache.c_idtree,
-				(caddr_t) &ei, bdb_id_cmp );
+			bdb_cache_entryinfo_free( &bdb->bi_cache, ein );
+			ein = eix;
 			
 			/* Link in any kids we've already processed */
 			if ( ei2 ) {
@@ -440,8 +549,6 @@
 				ein->bei_ckids++;
 				bdb_cache_entryinfo_unlock( ein );
 			}
-			addlru = 0;
-
 		}
 
 		/* If this is the first time, save this node
@@ -464,25 +571,22 @@
 				bdb->bi_cache.c_leaves++;
 		ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
 
-		if ( addlru ) {
-			ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_head_mutex );
-			bdb_cache_lru_add( bdb, ein );
-		}
-		addlru = 1;
-
 		/* Got the parent, link in and we're done. */
 		if ( ei2 ) {
+			bdb_cache_entryinfo_lock( eir );
 			bdb_cache_entryinfo_lock( ei2 );
 			ein->bei_parent = ei2;
+
 			avl_insert( &ei2->bei_kids, (caddr_t)ein, bdb_rdn_cmp,
 				avl_dup_error);
 			ei2->bei_ckids++;
-			bdb_cache_entryinfo_unlock( ei2 );
-			bdb_cache_entryinfo_lock( eir );
 
 			/* Reset all the state info */
 			for (ein = eir; ein != ei2; ein=ein->bei_parent)
 				ein->bei_state &= ~CACHE_ENTRY_NOT_LINKED;
+
+			bdb_cache_entryinfo_unlock( ei2 );
+
 			*res = eir;
 			break;
 		}
@@ -531,24 +635,25 @@
 }
 #endif
 
-/* caller must have lru_head_mutex locked. mutex
- * will be unlocked on return.
+/* This is best-effort only. If all entries in the cache are
+ * busy, they will all be kept. This is unlikely to happen
+ * unless the cache is very much smaller than the working set.
  */
 static void
-bdb_cache_lru_add(
-	struct bdb_info *bdb,
-	EntryInfo *ei )
+bdb_cache_lru_purge( struct bdb_info *bdb )
 {
 	DB_LOCK		lock, *lockp;
-	EntryInfo *elru, *elprev;
-	int count = 0;
+	EntryInfo *elru, *elnext = NULL;
+	int count, islocked, eimax;
 
-	LRU_ADD( &bdb->bi_cache, ei );
-	ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_head_mutex );
+	/* Wait for the mutex; we're the only one trying to purge. */
+	ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex );
 
-	/* See if we're above the cache size limit */
-	if ( bdb->bi_cache.c_cursize <= bdb->bi_cache.c_maxsize )
+	if ( bdb->bi_cache.c_cursize <= bdb->bi_cache.c_maxsize ) {
+		ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
+		bdb->bi_cache.c_purging = 0;
 		return;
+	}
 
 	if ( bdb->bi_cache.c_locker ) {
 		lockp = &lock;
@@ -556,29 +661,49 @@
 		lockp = NULL;
 	}
 
-	/* Don't bother if we can't get the lock */
-	if ( ldap_pvt_thread_mutex_trylock( &bdb->bi_cache.lru_tail_mutex ) )
-		return;
+	count = 0;
 
+	/* maximum number of EntryInfo leaves to cache. In slapcat
+	 * we always free all leaf nodes.
+	 */
+	if ( slapMode & SLAP_TOOL_READONLY )
+		eimax = 0;
+	else
+		eimax = bdb->bi_cache.c_eimax;
+
 	/* Look for an unused entry to remove */
-	for (elru = bdb->bi_cache.c_lrutail; elru; elru = elprev ) {
-		elprev = elru->bei_lruprev;
+	for ( elru = bdb->bi_cache.c_lruhead; elru; elru = elnext ) {
+		elnext = elru->bei_lrunext;
 
+		if ( bdb_cache_entryinfo_trylock( elru ))
+			goto bottom;
+
+		/* This flag implements the clock replacement behavior */
+		if ( elru->bei_state & ( CACHE_ENTRY_REFERENCED )) {
+			elru->bei_state &= ~CACHE_ENTRY_REFERENCED;
+			bdb_cache_entryinfo_unlock( elru );
+			goto bottom;
+		}
+
+		/* If this node is in the process of linking into the cache,
+		 * or this node is being deleted, skip it.
+		 */
+		if (( elru->bei_state & ( CACHE_ENTRY_NOT_LINKED |
+			CACHE_ENTRY_DELETED | CACHE_ENTRY_LOADING )) ||
+			elru->bei_finders > 0 ) {
+			bdb_cache_entryinfo_unlock( elru );
+			goto bottom;
+		}
+
+		/* entryinfo is locked */
+		islocked = 1;
+
 		/* If we can successfully writelock it, then
 		 * the object is idle.
 		 */
-		if ( bdb_cache_entry_db_lock( bdb->bi_dbenv,
-				bdb->bi_cache.c_locker, elru, 1, 1, lockp ) == 0 ) {
+		if ( bdb_cache_entry_db_lock( bdb,
+			bdb->bi_cache.c_locker, elru, 1, 1, lockp ) == 0 ) {
 
-
-			/* If this node is in the process of linking into the cache,
-			 * or this node is being deleted, skip it.
-			 */
-			if ( elru->bei_state &
-				( CACHE_ENTRY_NOT_LINKED | CACHE_ENTRY_DELETED )) {
-				bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
-				continue;
-			}
 			/* Free entry for this node if it's present */
 			if ( elru->bei_e ) {
 				elru->bei_e->e_private = NULL;
@@ -590,35 +715,39 @@
 				elru->bei_e = NULL;
 				count++;
 			}
-			/* ITS#4010 if we're in slapcat, and this node is a leaf
-			 * node, free it.
-			 *
-			 * FIXME: we need to do this for slapd as well, (which is
-			 * why we compute bi_cache.c_leaves now) but at the moment
-			 * we can't because it causes unresolvable deadlocks. 
+			bdb_cache_entry_db_unlock( bdb, lockp );
+
+			/* 
+			 * If it is a leaf node, and we're over the limit, free it.
 			 */
-			if ( slapMode & SLAP_TOOL_READONLY ) {
-				if ( !elru->bei_kids ) {
-					/* This does LRU_DELETE for us */
-					bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 );
-					bdb_cache_delete_cleanup( &bdb->bi_cache, elru );
-				}
-				/* Leave node on LRU list for a future pass */
-			} else {
-				LRU_DELETE( &bdb->bi_cache, elru );
-			}
-			bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
+			if ( elru->bei_kids ) {
+				/* Drop from list, we ignore it... */
+				LRU_DEL( &bdb->bi_cache, elru );
+			} else if ( bdb->bi_cache.c_leaves > eimax ) {
+				/* Too many leaf nodes, free this one */
+				bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 );
+				bdb_cache_delete_cleanup( &bdb->bi_cache, elru );
+				islocked = 0;
+			}	/* Leave on list until we need to free it */
+		}
 
-			if ( count >= bdb->bi_cache.c_minfree ) {
-				ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
-				bdb->bi_cache.c_cursize -= count;
-				ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-				break;
-			}
+		if ( islocked )
+			bdb_cache_entryinfo_unlock( elru );
+
+		if ( count >= bdb->bi_cache.c_minfree ) {
+			ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
+			bdb->bi_cache.c_cursize -= count;
+			ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
+			break;
 		}
+bottom:
+		if ( elnext == bdb->bi_cache.c_lruhead )
+			break;
 	}
 
-	ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_tail_mutex );
+	bdb->bi_cache.c_lruhead = elnext;
+	ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
+	bdb->bi_cache.c_purging = 0;
 }
 
 EntryInfo *
@@ -640,7 +769,7 @@
 
 /*
  * cache_find_id - find an entry in the cache, given id.
- * The entry is locked for Read upon return. Call with islocked TRUE if
+ * The entry is locked for Read upon return. Call with flag ID_LOCKED if
  * the supplied *eip was already locked.
  */
 
@@ -650,8 +779,8 @@
 	DB_TXN	*tid,
 	ID				id,
 	EntryInfo	**eip,
-	int		islocked,
-	u_int32_t	locker,
+	int		flag,
+	BDB_LOCKER	locker,
 	DB_LOCK		*lock )
 {
 	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
@@ -671,8 +800,7 @@
 			(caddr_t) &ei, bdb_id_cmp );
 		if ( *eip ) {
 			/* If the lock attempt fails, the info is in use */
-			if ( ldap_pvt_thread_mutex_trylock(
-					&(*eip)->bei_kids_mutex )) {
+			if ( bdb_cache_entryinfo_trylock( *eip )) {
 				ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock );
 				/* If this node is being deleted, treat
 				 * as if the delete has already finished
@@ -693,7 +821,7 @@
 				ldap_pvt_thread_yield();
 				goto again;
 			}
-			islocked = 1;
+			flag |= ID_LOCKED;
 		}
 		ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock );
 	}
@@ -703,9 +831,9 @@
 #ifndef BDB_HIER
 		rc = bdb_id2entry( op->o_bd, tid, locker, id, &ep );
 		if ( rc == 0 ) {
-			rc = bdb_cache_find_ndn( op, tid,
+			rc = bdb_cache_find_ndn( op, locker,
 				&ep->e_nname, eip );
-			if ( *eip ) islocked = 1;
+			if ( *eip ) flag |= ID_LOCKED;
 			if ( rc ) {
 				ep->e_private = NULL;
 #ifdef SLAP_ZONE_ALLOC
@@ -717,8 +845,8 @@
 			}
 		}
 #else
-		rc = hdb_cache_find_parent(op, tid, locker, id, eip );
-		if ( rc == 0 ) islocked = 1;
+		rc = hdb_cache_find_parent(op, locker, id, eip );
+		if ( rc == 0 ) flag |= ID_LOCKED;
 #endif
 	}
 
@@ -727,6 +855,8 @@
 		if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
 			rc = DB_NOTFOUND;
 		} else {
+			(*eip)->bei_finders++;
+			(*eip)->bei_state |= CACHE_ENTRY_REFERENCED;
 			/* Make sure only one thread tries to load the entry */
 load1:
 #ifdef SLAP_ZONE_ALLOC
@@ -740,23 +870,27 @@
 				load = 1;
 				(*eip)->bei_state |= CACHE_ENTRY_LOADING;
 			}
-			if ( islocked ) {
+
+			/* If the entry was loaded before but uncached, and we need
+			 * it again, clear the uncached state
+			 */
+			if ( (*eip)->bei_state & CACHE_ENTRY_NOT_CACHED ) {
+				(*eip)->bei_state ^= CACHE_ENTRY_NOT_CACHED;
+				if ( flag & ID_NOCACHE )
+					flag ^= ID_NOCACHE;
+			}
+
+			if ( flag & ID_LOCKED ) {
 				bdb_cache_entryinfo_unlock( *eip );
-				islocked = 0;
+				flag ^= ID_LOCKED;
 			}
-			rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, *eip, 0, 0, lock );
+			rc = bdb_cache_entry_db_lock( bdb, locker, *eip, load, 0, lock );
 			if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
 				rc = DB_NOTFOUND;
-				bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
+				bdb_cache_entry_db_unlock( bdb, lock );
 			} else if ( rc == 0 ) {
 				if ( load ) {
-					/* Give up original read lock, obtain write lock
-					 */
-				    if ( rc == 0 ) {
-						rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
-							*eip, 1, 0, lock );
-					}
-					if ( rc == 0 && !ep) {
+					if ( !ep) {
 						rc = bdb_id2entry( op->o_bd, tid, locker, id, &ep );
 					}
 					if ( rc == 0 ) {
@@ -769,26 +903,28 @@
 						(*eip)->bei_zseq = *((ber_len_t *)ep - 2);
 #endif
 						ep = NULL;
+						bdb_cache_lru_link( bdb, *eip );
+						if ( flag & ID_NOCACHE ) {
+							bdb_cache_entryinfo_lock( *eip );
+							(*eip)->bei_state |= CACHE_ENTRY_NOT_CACHED;
+							bdb_cache_entryinfo_unlock( *eip );
+						}
 					}
-					bdb_cache_entryinfo_lock( *eip );
-					(*eip)->bei_state ^= CACHE_ENTRY_LOADING;
-					bdb_cache_entryinfo_unlock( *eip );
 					if ( rc == 0 ) {
 						/* If we succeeded, downgrade back to a readlock. */
-						rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
+						rc = bdb_cache_entry_db_relock( bdb, locker,
 							*eip, 0, 0, lock );
 					} else {
 						/* Otherwise, release the lock. */
-						bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
+						bdb_cache_entry_db_unlock( bdb, lock );
 					}
 				} else if ( !(*eip)->bei_e ) {
 					/* Some other thread is trying to load the entry,
-					 * give it a chance to finish.
+					 * wait for it to finish.
 					 */
-					bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
-					ldap_pvt_thread_yield();
+					bdb_cache_entry_db_unlock( bdb, lock );
 					bdb_cache_entryinfo_lock( *eip );
-					islocked = 1;
+					flag |= ID_LOCKED;
 					goto load1;
 #ifdef BDB_HIER
 				} else {
@@ -796,21 +932,25 @@
 					 */
 					rc = bdb_fix_dn( (*eip)->bei_e, 1 );
 					if ( rc ) {
-						bdb_cache_entry_db_relock( bdb->bi_dbenv,
+						bdb_cache_entry_db_relock( bdb,
 							locker, *eip, 1, 0, lock );
 						/* check again in case other modifier did it already */
 						if ( bdb_fix_dn( (*eip)->bei_e, 1 ) )
 							rc = bdb_fix_dn( (*eip)->bei_e, 2 );
-						bdb_cache_entry_db_relock( bdb->bi_dbenv,
+						bdb_cache_entry_db_relock( bdb,
 							locker, *eip, 0, 0, lock );
 					}
 #endif
 				}
-
+				bdb_cache_entryinfo_lock( *eip );
+				(*eip)->bei_finders--;
+				if ( load )
+					(*eip)->bei_state ^= CACHE_ENTRY_LOADING;
+				bdb_cache_entryinfo_unlock( *eip );
 			}
 		}
 	}
-	if ( islocked ) {
+	if ( flag & ID_LOCKED ) {
 		bdb_cache_entryinfo_unlock( *eip );
 	}
 	if ( ep ) {
@@ -822,31 +962,22 @@
 #endif
 	}
 	if ( rc == 0 ) {
+		int purge = 0;
 
 		if ( load ) {
-			ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
-			bdb->bi_cache.c_cursize++;
-			ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-		}
-
-		ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_head_mutex );
-
-		/* If the LRU list has only one entry and this is it, it
-		 * doesn't need to be added again.
-		 */
-		if ( bdb->bi_cache.c_lruhead == bdb->bi_cache.c_lrutail &&
-			bdb->bi_cache.c_lruhead == *eip ) {
-			ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_head_mutex );
-		} else {
-			/* if entry is on LRU list, remove from old spot */
-			if ( (*eip)->bei_lrunext || (*eip)->bei_lruprev ) {
-				ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_tail_mutex );
-				LRU_DELETE( &bdb->bi_cache, *eip );
-				ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_tail_mutex );
+			if ( !( flag & ID_NOCACHE )) {
+				ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
+				bdb->bi_cache.c_cursize++;
+				if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize &&
+					!bdb->bi_cache.c_purging ) {
+					purge = 1;
+					bdb->bi_cache.c_purging = 1;
+				}
+				ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
 			}
-			/* lru_head_mutex is unlocked for us */
-			bdb_cache_lru_add( bdb, *eip );
 		}
+		if ( purge )
+			bdb_cache_lru_purge( bdb );
 	}
 
 #ifdef SLAP_ZONE_ALLOC
@@ -886,11 +1017,11 @@
 	EntryInfo *eip,
 	Entry *e,
 	struct berval *nrdn,
-	u_int32_t locker )
+	BDB_LOCKER locker,
+	DB_LOCK *lock )
 {
 	EntryInfo *new, ei;
-	DB_LOCK lock;
-	int rc;
+	int rc, purge = 0;
 #ifdef BDB_HIER
 	struct berval rdn = e->e_name;
 #endif
@@ -903,7 +1034,7 @@
 	/* Lock this entry so that bdb_add can run to completion.
 	 * It can only fail if BDB has run out of lock resources.
 	 */
-	rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, &ei, 1, 0, &lock );
+	rc = bdb_cache_entry_db_lock( bdb, locker, &ei, 0, 0, lock );
 	if ( rc ) {
 		bdb_cache_entryinfo_unlock( eip );
 		return rc;
@@ -931,37 +1062,43 @@
 	}
 	new->bei_e = e;
 	e->e_private = new;
-	new->bei_state = CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
+	new->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
 	eip->bei_state &= ~CACHE_ENTRY_NO_KIDS;
 	if (eip->bei_parent) {
 		eip->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS;
 	}
 	bdb_cache_entryinfo_unlock( eip );
 
+	ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
+	ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
 	++bdb->bi_cache.c_cursize;
-	ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
+	if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize &&
+		!bdb->bi_cache.c_purging ) {
+		purge = 1;
+		bdb->bi_cache.c_purging = 1;
+	}
+	ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
 
-	/* set lru mutex */
-	ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_head_mutex );
+	bdb_cache_lru_link( bdb, new );
 
-	/* lru_head_mutex is unlocked for us */
-	bdb_cache_lru_add( bdb, new );
+	if ( purge )
+		bdb_cache_lru_purge( bdb );
 
 	return rc;
 }
 
 int
 bdb_cache_modify(
+	struct bdb_info *bdb,
 	Entry *e,
 	Attribute *newAttrs,
-	DB_ENV *env,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	DB_LOCK *lock )
 {
 	EntryInfo *ei = BEI(e);
 	int rc;
 	/* Get write lock on data */
-	rc = bdb_cache_entry_db_relock( env, locker, ei, 1, 0, lock );
+	rc = bdb_cache_entry_db_relock( bdb, locker, ei, 1, 0, lock );
 
 	/* If we've done repeated mods on a cached entry, then e_attrs
 	 * is no longer contiguous with the entry, and must be freed.
@@ -985,7 +1122,7 @@
 	struct berval *nrdn,
 	Entry *new,
 	EntryInfo *ein,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	DB_LOCK *lock )
 {
 	EntryInfo *ei = BEI(e), *pei;
@@ -995,7 +1132,7 @@
 #endif
 
 	/* Get write lock on data */
-	rc =  bdb_cache_entry_db_relock( bdb->bi_dbenv, locker, ei, 1, 0, lock );
+	rc =  bdb_cache_entry_db_relock( bdb, locker, ei, 1, 0, lock );
 	if ( rc ) return rc;
 
 	/* If we've done repeated mods on a cached entry, then e_attrs
@@ -1021,9 +1158,6 @@
 	free( ei->bei_nrdn.bv_val );
 	ber_dupbv( &ei->bei_nrdn, nrdn );
 
-	if ( !pei->bei_kids )
-		pei->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
-
 #ifdef BDB_HIER
 	free( ei->bei_rdn.bv_val );
 
@@ -1034,8 +1168,16 @@
 		rdn.bv_len = ptr - rdn.bv_val;
 	}
 	ber_dupbv( &ei->bei_rdn, &rdn );
-	pei->bei_ckids--;
-	if ( pei->bei_dkids ) pei->bei_dkids--;
+
+	/* If new parent, decrement kid counts */
+	if ( ein ) {
+		pei->bei_ckids--;
+		if ( pei->bei_dkids ) {
+			pei->bei_dkids--;
+			if ( pei->bei_dkids < 2 )
+				pei->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
+		}
+	}
 #endif
 
 	if (!ein) {
@@ -1044,26 +1186,32 @@
 		ei->bei_parent = ein;
 		bdb_cache_entryinfo_unlock( pei );
 		bdb_cache_entryinfo_lock( ein );
-	}
-	/* parent now has kids */
-	if ( ein->bei_state & CACHE_ENTRY_NO_KIDS )
-		ein->bei_state ^= CACHE_ENTRY_NO_KIDS;
+
+		/* new parent now has kids */
+		if ( ein->bei_state & CACHE_ENTRY_NO_KIDS )
+			ein->bei_state ^= CACHE_ENTRY_NO_KIDS;
+		/* grandparent has grandkids */
+		if ( ein->bei_parent )
+			ein->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS;
 #ifdef BDB_HIER
-	/* parent might now have grandkids */
-	if ( ein->bei_state & CACHE_ENTRY_NO_GRANDKIDS &&
-		!(ei->bei_state & (CACHE_ENTRY_NO_KIDS)))
-		ein->bei_state ^= CACHE_ENTRY_NO_GRANDKIDS;
+		/* parent might now have grandkids */
+		if ( ein->bei_state & CACHE_ENTRY_NO_GRANDKIDS &&
+			!(ei->bei_state & CACHE_ENTRY_NO_KIDS))
+			ein->bei_state ^= CACHE_ENTRY_NO_GRANDKIDS;
 
-	{
-		/* Record the generation number of this change */
-		ldap_pvt_thread_mutex_lock( &bdb->bi_modrdns_mutex );
-		bdb->bi_modrdns++;
-		ei->bei_modrdns = bdb->bi_modrdns;
-		ldap_pvt_thread_mutex_unlock( &bdb->bi_modrdns_mutex );
+		ein->bei_ckids++;
+		if ( ein->bei_dkids ) ein->bei_dkids++;
+#endif
 	}
-	ein->bei_ckids++;
-	if ( ein->bei_dkids ) ein->bei_dkids++;
+
+#ifdef BDB_HIER
+	/* Record the generation number of this change */
+	ldap_pvt_thread_mutex_lock( &bdb->bi_modrdns_mutex );
+	bdb->bi_modrdns++;
+	ei->bei_modrdns = bdb->bi_modrdns;
+	ldap_pvt_thread_mutex_unlock( &bdb->bi_modrdns_mutex );
 #endif
+
 	avl_insert( &ein->bei_kids, ei, bdb_rdn_cmp, avl_dup_error );
 	bdb_cache_entryinfo_unlock( ein );
 	return rc;
@@ -1077,10 +1225,9 @@
  */
 int
 bdb_cache_delete(
-    Cache	*cache,
+	struct bdb_info *bdb,
     Entry		*e,
-    DB_ENV	*env,
-    u_int32_t	locker,
+    BDB_LOCKER	locker,
     DB_LOCK	*lock )
 {
 	EntryInfo *ei = BEI(e);
@@ -1095,7 +1242,7 @@
 	bdb_cache_entryinfo_lock( ei );
 
 	/* Get write lock on the data */
-	rc = bdb_cache_entry_db_relock( env, locker, ei, 1, 0, lock );
+	rc = bdb_cache_entry_db_relock( bdb, locker, ei, 1, 0, lock );
 	if ( rc ) {
 		/* couldn't lock, undo and give up */
 		ei->bei_state ^= CACHE_ENTRY_DELETED;
@@ -1107,18 +1254,12 @@
 		e->e_id, 0, 0 );
 
 	/* set lru mutex */
-	ldap_pvt_thread_mutex_lock( &cache->lru_tail_mutex );
+	ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex );
 
-	/* set cache write lock */
-	ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
+	rc = bdb_cache_delete_internal( &bdb->bi_cache, e->e_private, 1 );
 
-	rc = bdb_cache_delete_internal( cache, e->e_private, 1 );
-
-	/* free cache write lock */
-	ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
-
 	/* free lru mutex */
-	ldap_pvt_thread_mutex_unlock( &cache->lru_tail_mutex );
+	ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
 
 	/* Leave entry info locked */
 
@@ -1140,23 +1281,7 @@
 		ei->bei_e = NULL;
 	}
 
-	free( ei->bei_nrdn.bv_val );
-	ei->bei_nrdn.bv_val = NULL;
-#ifdef BDB_HIER
-	free( ei->bei_rdn.bv_val );
-	ei->bei_rdn.bv_val = NULL;
-	ei->bei_modrdns = 0;
-	ei->bei_ckids = 0;
-	ei->bei_dkids = 0;
-#endif
-	ei->bei_parent = NULL;
-	ei->bei_kids = NULL;
-	ei->bei_lruprev = NULL;
-
-	ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
-	ei->bei_lrunext = cache->c_eifree;
-	cache->c_eifree = ei;
-	ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
+	bdb_cache_entryinfo_free( cache, ei );
 	bdb_cache_entryinfo_unlock( ei );
 }
 
@@ -1167,6 +1292,7 @@
     int		decr )
 {
 	int rc = 0;	/* return code */
+	int decr_leaf = 0;
 
 	/* Lock the parent's kids tree */
 	bdb_cache_entryinfo_lock( e->bei_parent );
@@ -1182,23 +1308,32 @@
 		rc = -1;
 	}
 	if ( e->bei_parent->bei_kids )
-		cache->c_leaves--;
+		decr_leaf = 1;
 
+	bdb_cache_entryinfo_unlock( e->bei_parent );
+
+	ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
 	/* id tree */
-	if ( avl_delete( &cache->c_idtree, (caddr_t) e, bdb_id_cmp ) == NULL ) {
+	if ( avl_delete( &cache->c_idtree, (caddr_t) e, bdb_id_cmp )) {
+		cache->c_eiused--;
+		if ( decr_leaf )
+			cache->c_leaves--;
+	} else {
 		rc = -1;
 	}
+	ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 
 	if ( rc == 0 ){
-		cache->c_eiused--;
+		/* lru */
+		LRU_DEL( cache, e );
 
-		/* lru */
-		LRU_DELETE( cache, e );
-		if ( e->bei_e ) cache->c_cursize--;
+		if ( e->bei_e ) {
+			ldap_pvt_thread_mutex_lock( &cache->c_count_mutex );
+			cache->c_cursize--;
+			ldap_pvt_thread_mutex_unlock( &cache->c_count_mutex );
+		}
 	}
 
-	bdb_cache_entryinfo_unlock( e->bei_parent );
-
 	return( rc );
 }
 
@@ -1226,7 +1361,7 @@
 	/* set cache write lock */
 	ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
 	/* set lru mutex */
-	ldap_pvt_thread_mutex_lock( &cache->lru_tail_mutex );
+	ldap_pvt_thread_mutex_lock( &cache->c_lru_mutex );
 
 	Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_release_all\n", 0, 0, 0 );
 
@@ -1245,7 +1380,7 @@
 	cache->c_dntree.bei_kids = NULL;
 
 	/* free lru mutex */
-	ldap_pvt_thread_mutex_unlock( &cache->lru_tail_mutex );
+	ldap_pvt_thread_mutex_unlock( &cache->c_lru_mutex );
 	/* free cache write lock */
 	ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
 }
@@ -1257,15 +1392,22 @@
 {
 	EntryInfo	*e;
 
-	fprintf( stderr, "LRU queue (head to tail):\n" );
-	for ( e = cache->c_lruhead; e != NULL; e = e->bei_lrunext ) {
-		fprintf( stderr, "\trdn \"%20s\" id %ld\n",
-			e->bei_nrdn.bv_val, e->bei_id );
+	fprintf( stderr, "LRU circle head: %p\n", (void *) cache->c_lruhead );
+	fprintf( stderr, "LRU circle (tail forward):\n" );
+	for ( e = cache->c_lrutail; ; ) {
+		fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n",
+			(void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val );
+		e = e->bei_lrunext;
+		if ( e == cache->c_lrutail )
+			break;
 	}
-	fprintf( stderr, "LRU queue (tail to head):\n" );
-	for ( e = cache->c_lrutail; e != NULL; e = e->bei_lruprev ) {
-		fprintf( stderr, "\trdn \"%20s\" id %ld\n",
-			e->bei_nrdn.bv_val, e->bei_id );
+	fprintf( stderr, "LRU circle (tail backward):\n" );
+	for ( e = cache->c_lrutail; ; ) {
+		fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n",
+			(void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val );
+		e = e->bei_lruprev;
+		if ( e == cache->c_lrutail )
+			break;
 	}
 }
 #endif
@@ -1276,9 +1418,15 @@
 bdb_locker_id_free( void *key, void *data )
 {
 	DB_ENV *env = key;
-	u_int32_t lockid = (long)data;
+	u_int32_t lockid;
 	int rc;
 
+#if DB_VERSION_FULL >= 0x04060012
+	BDB_LOCKER lptr = data;
+	lockid = lptr->id;
+#else
+	lockid = (long)data;
+#endif
 	rc = XLOCK_ID_FREE( env, lockid );
 	if ( rc == EINVAL ) {
 		DB_LOCKREQ lr;
@@ -1307,7 +1455,7 @@
 }
 
 int
-bdb_locker_id( Operation *op, DB_ENV *env, u_int32_t *locker )
+bdb_locker_id( Operation *op, DB_ENV *env, BDB_LOCKER *locker )
 {
 	int i, rc;
 	u_int32_t lockid;
@@ -1337,7 +1485,14 @@
 		if ( rc != 0) {
 			return rc;
 		}
+#if DB_VERSION_FULL >= 0x04060012
+		{ BDB_LOCKER lptr;
+		__lock_getlocker( env->lk_handle, lockid, 0, &lptr );
+		data = lptr;
+		}
+#else
 		data = (void *)((long)lockid);
+#endif
 		if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, env,
 			data, bdb_locker_id_free ) ) ) {
 			XLOCK_ID_FREE( env, lockid );
@@ -1349,33 +1504,11 @@
 	} else {
 		lockid = (long)data;
 	}
+#if DB_VERSION_FULL >= 0x04060012
+	*locker = data;
+#else
 	*locker = lockid;
+#endif
 	return 0;
 }
 #endif /* BDB_REUSE_LOCKERS */
-
-void
-bdb_cache_delete_entry(
-	struct bdb_info *bdb,
-	EntryInfo *ei,
-	u_int32_t locker,
-	DB_LOCK *lock )
-{
-	ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
-	if ( bdb_cache_entry_db_lock( bdb->bi_dbenv, bdb->bi_cache.c_locker, ei, 1, 1, lock ) == 0 )
-	{
-		if ( ei->bei_e && !(ei->bei_state & CACHE_ENTRY_NOT_LINKED )) {
-			LRU_DELETE( &bdb->bi_cache, ei );
-			ei->bei_e->e_private = NULL;
-#ifdef SLAP_ZONE_ALLOC
-			bdb_entry_return( bdb, ei->bei_e, ei->bei_zseq );
-#else
-			bdb_entry_return( ei->bei_e );
-#endif
-			ei->bei_e = NULL;
-			--bdb->bi_cache.c_cursize;
-		}
-		bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
-	}
-	ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-}

Modified: openldap/trunk/servers/slapd/back-bdb/compare.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* compare.c - bdb backend compare routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/compare.c,v 1.44.2.4 2007/01/02 21:43:59 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/compare.c,v 1.51.2.4 2007/09/29 09:55:22 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -30,7 +30,7 @@
 	Attribute	*a;
 	int		manageDSAit = get_manageDSAit( op );
 
-	u_int32_t	locker;
+	BDB_LOCKER	locker;
 	DB_LOCK		lock;
 
 	rs->sr_err = LOCK_ID(bdb->bi_dbenv, &locker);
@@ -66,16 +66,13 @@
 	e = ei->bei_e;
 	if ( rs->sr_err == DB_NOTFOUND ) {
 		if ( e != NULL ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 			/* return referral only if "disclose" is granted on the object */
 			if ( ! access_allowed( op, e, slap_schema.si_ad_entry,
 				NULL, ACL_DISCLOSE, NULL ) )
 			{
 				rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
-			} else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-			{
+			} else {
 				rs->sr_matched = ch_strdup( e->e_dn );
 				rs->sr_ref = is_entry_referral( e )
 					? get_entry_referrals( op, e )
@@ -83,7 +80,7 @@
 				rs->sr_err = LDAP_REFERRAL;
 			}
 
-			bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
+			bdb_cache_return_entry_r( bdb, e, &lock );
 			e = NULL;
 
 		} else {
@@ -103,15 +100,12 @@
 	}
 
 	if (!manageDSAit && is_entry_referral( e ) ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 		/* return referral only if "disclose" is granted on the object */
 		if ( !access_allowed( op, e, slap_schema.si_ad_entry,
 			NULL, ACL_DISCLOSE, NULL ) )
 		{
 			rs->sr_err = LDAP_NO_SUCH_OBJECT;
-		} else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-		{
+		} else {
 			/* entry is a referral, don't allow compare */
 			rs->sr_ref = get_entry_referrals( op, e );
 			rs->sr_err = LDAP_REFERRAL;
@@ -131,14 +125,11 @@
 	if ( get_assert( op ) &&
 		( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
 	{
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 		if ( !access_allowed( op, e, slap_schema.si_ad_entry,
 			NULL, ACL_DISCLOSE, NULL ) )
 		{
 			rs->sr_err = LDAP_NO_SUCH_OBJECT;
-		} else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-		{
+		} else {
 			rs->sr_err = LDAP_ASSERTION_FAILED;
 		}
 		goto return_results;
@@ -147,16 +138,13 @@
 	if ( !access_allowed( op, e, op->oq_compare.rs_ava->aa_desc,
 		&op->oq_compare.rs_ava->aa_value, ACL_COMPARE, NULL ) )
 	{
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 		/* return error only if "disclose"
 		 * is granted on the object */
 		if ( !access_allowed( op, e, slap_schema.si_ad_entry,
 					NULL, ACL_DISCLOSE, NULL ) )
 		{
 			rs->sr_err = LDAP_NO_SUCH_OBJECT;
-		} else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-		{
+		} else {
 			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
 		}
 		goto return_results;
@@ -170,10 +158,10 @@
 	{
 		rs->sr_err = LDAP_COMPARE_FALSE;
 
-		if ( value_find_ex( op->oq_compare.rs_ava->aa_desc,
+		if ( attr_valfind( a,
 			SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
 				SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-			a->a_nvals, &op->oq_compare.rs_ava->aa_value,
+			&op->oq_compare.rs_ava->aa_value, NULL,
 			op->o_tmpmemctx ) == 0 )
 		{
 			rs->sr_err = LDAP_COMPARE_TRUE;
@@ -194,8 +182,7 @@
 done:
 	/* free entry */
 	if ( e != NULL ) {
-		bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache,
-				e, &lock );
+		bdb_cache_return_entry_r( bdb, e, &lock );
 	}
 
 	LOCK_ID_FREE ( bdb->bi_dbenv, locker );

Modified: openldap/trunk/servers/slapd/back-bdb/config.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* config.c - bdb backend configuration file routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/config.c,v 1.43.2.19 2007/09/02 21:57:35 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/config.c,v 1.91.2.7 2007/10/18 01:03:41 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <ac/ctype.h>
 #include <ac/string.h>
+#include <ac/errno.h>
 
 #include "back-bdb.h"
 
@@ -31,7 +32,7 @@
 #	define	SLAP_BDB_ALLOW_DIRTY_READ
 #endif
 
-#define bdb_cf_gen			BDB_SYMBOL(cf_gen)
+#define bdb_cf_gen		BDB_SYMBOL(cf_gen)
 #define	bdb_cf_cleanup		BDB_SYMBOL(cf_cleanup)
 #define bdb_checkpoint		BDB_SYMBOL(checkpoint)
 #define bdb_online_index	BDB_SYMBOL(online_index)
@@ -55,12 +56,12 @@
 			"DESC 'Directory for database content' "
 			"EQUALITY caseIgnoreMatch "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
-	{ "cachefree", "size", 2, 2, 0, ARG_INT|ARG_OFFSET,
+	{ "cachefree", "size", 2, 2, 0, ARG_UINT|ARG_OFFSET,
 		(void *)offsetof(struct bdb_info, bi_cache.c_minfree),
 		"( OLcfgDbAt:1.11 NAME 'olcDbCacheFree' "
 			"DESC 'Number of extra entries to free when max is reached' "
 			"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-	{ "cachesize", "size", 2, 2, 0, ARG_INT|ARG_OFFSET,
+	{ "cachesize", "size", 2, 2, 0, ARG_UINT|ARG_OFFSET,
 		(void *)offsetof(struct bdb_info, bi_cache.c_maxsize),
 		"( OLcfgDbAt:1.1 NAME 'olcDbCacheSize' "
 			"DESC 'Entry cache size in entries' "
@@ -72,7 +73,7 @@
 	{ "dbconfig", "DB_CONFIG setting", 1, 0, 0, ARG_MAGIC|BDB_CONFIG,
 		bdb_cf_gen, "( OLcfgDbAt:1.3 NAME 'olcDbConfig' "
 			"DESC 'BerkeleyDB DB_CONFIG configuration directives' "
-			"SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
+			"SYNTAX OMsIA5String X-ORDERED 'VALUES' )", NULL, NULL },
 	{ "dbnosync", NULL, 1, 2, 0, ARG_ON_OFF|ARG_MAGIC|BDB_NOSYNC,
 		bdb_cf_gen, "( OLcfgDbAt:1.4 NAME 'olcDbNoSync' "
 			"DESC 'Disable synchronous database writes' "
@@ -86,8 +87,13 @@
 		"( OLcfgDbAt:1.5 NAME 'olcDbDirtyRead' "
 		"DESC 'Allow reads of uncommitted data' "
 		"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
-	{ "idlcachesize", "size", 2, 2, 0, ARG_INT|ARG_OFFSET,
-		(void *)offsetof(struct bdb_info,bi_idl_cache_max_size),
+	{ "dncachesize", "size", 2, 2, 0, ARG_UINT|ARG_OFFSET,
+		(void *)offsetof(struct bdb_info, bi_cache.c_eimax),
+		"( OLcfgDbAt:1.12 NAME 'olcDbDNcacheSize' "
+			"DESC 'DN cache size' "
+			"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+	{ "idlcachesize", "size", 2, 2, 0, ARG_UINT|ARG_OFFSET,
+		(void *)offsetof(struct bdb_info, bi_idl_cache_max_size),
 		"( OLcfgDbAt:1.6 NAME 'olcDbIDLcacheSize' "
 		"DESC 'IDL cache size in IDLs' "
 		"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
@@ -114,7 +120,7 @@
 		bdb_cf_gen, "( OLcfgDbAt:1.9 NAME 'olcDbSearchStack' "
 		"DESC 'Depth of search stack in IDLs' "
 		"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-	{ "shm_key", "key", 2, 2, 0, ARG_INT|ARG_OFFSET,
+	{ "shm_key", "key", 2, 2, 0, ARG_LONG|ARG_OFFSET,
 		(void *)offsetof(struct bdb_info, bi_shm_key), 
 		"( OLcfgDbAt:1.10 NAME 'olcDbShmKey' "
 		"DESC 'Key for shared memory region' "
@@ -140,7 +146,7 @@
 		"olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ "
 		"olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ "
 		"olcDbMode $ olcDbSearchStack $ olcDbShmKey $ "
-		" olcDbCacheFree ) )",
+		"olcDbCacheFree $ olcDbDNcacheSize ) )",
 		 	Cft_Database, bdbcfg },
 	{ NULL, 0, NULL }
 };
@@ -179,19 +185,20 @@
 
 	Connection conn = {0};
 	OperationBuffer opbuf;
-	Operation *op = (Operation *) &opbuf;
+	Operation *op;
 
 	DBC *curs;
 	DBT key, data;
 	DB_TXN *txn;
 	DB_LOCK lock;
-	u_int32_t locker;
+	BDB_LOCKER locker;
 	ID id, nid;
 	EntryInfo *ei;
 	int rc, getnext = 1;
 	int i;
 
-	connection_fake_init( &conn, op, ctx );
+	connection_fake_init( &conn, &opbuf, ctx );
+	op = &opbuf.ob_op;
 
 	op->o_bd = be;
 
@@ -319,21 +326,24 @@
 	
 	if ( bdb->bi_flags & BDB_RE_OPEN ) {
 		bdb->bi_flags ^= BDB_RE_OPEN;
-		rc = c->be->bd_info->bi_db_close( c->be );
+		rc = c->be->bd_info->bi_db_close( c->be, NULL );
 		if ( rc == 0 )
-			rc = c->be->bd_info->bi_db_open( c->be );
+			rc = c->be->bd_info->bi_db_open( c->be, NULL );
 		/* If this fails, we need to restart */
 		if ( rc ) {
 			slapd_shutdown = 2;
+			snprintf( c->cr_msg, sizeof( c->cr_msg ),
+				"failed to reopen database, rc=%d", rc );
 			Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_cf_cleanup)
-				": failed to reopen database, rc=%d", rc, 0, 0 );
+				": %s\n", c->cr_msg, 0, 0 );
+			rc = LDAP_OTHER;
 		}
 	}
 	return rc;
 }
 
 static int
-bdb_cf_gen(ConfigArgs *c)
+bdb_cf_gen( ConfigArgs *c )
 {
 	struct bdb_info *bdb = c->be->be_private;
 	int rc;
@@ -342,7 +352,7 @@
 		rc = 0;
 		switch( c->type ) {
 		case BDB_CHKPT:
-			if (bdb->bi_txn_cp ) {
+			if ( bdb->bi_txn_cp ) {
 				char buf[64];
 				struct berval bv;
 				bv.bv_len = sprintf( buf, "%d %d", bdb->bi_txn_cp_kbyte,
@@ -364,7 +374,8 @@
 
 		case BDB_CONFIG:
 			if ( !( bdb->bi_flags & BDB_IS_OPEN )
-				&& !bdb->bi_db_config ) {
+				&& !bdb->bi_db_config )
+			{
 				char	buf[SLAP_TEXT_BUFLEN];
 				FILE *f = fopen( bdb->bi_db_config_path, "r" );
 				struct berval bv;
@@ -442,7 +453,7 @@
 			if ( bdb->bi_txn_cp_task ) {
 				struct re_s *re = bdb->bi_txn_cp_task;
 				bdb->bi_txn_cp_task = NULL;
-				if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ))
+				if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) )
 					ldap_pvt_runqueue_stoptask( &slapd_rq, re );
 				ldap_pvt_runqueue_remove( &slapd_rq, re );
 			}
@@ -489,7 +500,7 @@
 				struct berval bv, def = BER_BVC("default");
 				char *ptr;
 
-				for (ptr = c->line; !isspace( *ptr ); ptr++);
+				for (ptr = c->line; !isspace( (unsigned char) *ptr ); ptr++);
 
 				bv.bv_val = c->line;
 				bv.bv_len = ptr - bv.bv_val;
@@ -577,8 +588,8 @@
 
 		if ( c->op == SLAP_CONFIG_ADD ) {
 			ptr += STRLENOF("dbconfig");
-			while (!isspace(*ptr)) ptr++;
-			while (isspace(*ptr)) ptr++;
+			while (!isspace((unsigned char)*ptr)) ptr++;
+			while (isspace((unsigned char)*ptr)) ptr++;
 		}
 
 		if ( bdb->bi_flags & BDB_IS_OPEN ) {
@@ -607,8 +618,27 @@
 
 	case BDB_DIRECTORY: {
 		FILE *f;
-		char *ptr;
+		char *ptr, *testpath;
+		int len;
 
+		len = strlen( c->value_string );
+		testpath = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DUMMY") + 1 );
+		ptr = lutil_strcopy( testpath, c->value_string );
+		*ptr++ = LDAP_DIRSEP[0];
+		strcpy( ptr, "DUMMY" );
+		f = fopen( testpath, "w" );
+		if ( f ) {
+			fclose( f );
+			unlink( testpath );
+		}
+		ch_free( testpath );
+		if ( !f ) {
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid path: %s",
+				c->log, strerror( errno ));
+			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
+			return -1;
+		}
+
 		if ( bdb->bi_dbenv_home )
 			ch_free( bdb->bi_dbenv_home );
 		bdb->bi_dbenv_home = c->value_string;
@@ -616,7 +646,7 @@
 		/* See if a DB_CONFIG file already exists here */
 		if ( bdb->bi_db_config_path )
 			ch_free( bdb->bi_db_config_path );
-		bdb->bi_db_config_path = ch_malloc( strlen( bdb->bi_dbenv_home ) +
+		bdb->bi_db_config_path = ch_malloc( len +
 			STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG") + 1 );
 		ptr = lutil_strcopy( bdb->bi_db_config_path, bdb->bi_dbenv_home );
 		*ptr++ = LDAP_DIRSEP[0];

Modified: openldap/trunk/servers/slapd/back-bdb/dbcache.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/dbcache.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/dbcache.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* dbcache.c - manage cache of open databases */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/dbcache.c,v 1.38.2.5 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/dbcache.c,v 1.43.2.4 2007/11/26 04:08:37 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -60,7 +60,7 @@
 int
 bdb_db_cache(
 	Backend	*be,
-	const char *name,
+	struct berval *name,
 	DB **dbout )
 {
 	int i, flags;
@@ -72,7 +72,7 @@
 	*dbout = NULL;
 
 	for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) {
-		if( !strcmp( bdb->bi_databases[i]->bdi_name, name) ) {
+		if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) {
 			*dbout = bdb->bi_databases[i]->bdi_db;
 			return 0;
 		}
@@ -82,7 +82,7 @@
 
 	/* check again! may have been added by another thread */
 	for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) {
-		if( !strcmp( bdb->bi_databases[i]->bdi_name, name) ) {
+		if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) {
 			*dbout = bdb->bi_databases[i]->bdi_db;
 			ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
 			return 0;
@@ -96,7 +96,7 @@
 
 	db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));
 
-	db->bdi_name = ch_strdup( name );
+	ber_dupbv( &db->bdi_name, name );
 
 	rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 );
 	if( rc != 0 ) {
@@ -113,8 +113,9 @@
 #endif
 	rc = db->bdi_db->set_flags( db->bdi_db, DB_DUP | DB_DUPSORT );
 
-	file = ch_malloc( strlen( name ) + sizeof(BDB_SUFFIX) );
-	sprintf( file, "%s" BDB_SUFFIX, name );
+	file = ch_malloc( db->bdi_name.bv_len + sizeof(BDB_SUFFIX) );
+	strcpy( file, db->bdi_name.bv_val );
+	strcpy( file+db->bdi_name.bv_len, BDB_SUFFIX );
 
 #ifdef HAVE_EBCDIC
 	__atoe( file );
@@ -138,7 +139,7 @@
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
 			"bdb_db_cache: db_open(%s) failed: %s (%d)\n",
-			name, db_strerror(rc), rc );
+			name->bv_val, db_strerror(rc), rc );
 		ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
 		return rc;
 	}

Modified: openldap/trunk/servers/slapd/back-bdb/delete.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/delete.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/delete.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* delete.c - bdb backend delete routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/delete.c,v 1.132.2.10 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/delete.c,v 1.155.2.5 2007/12/06 05:43:27 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -38,7 +38,7 @@
 	struct bdb_op_info opinfo = {0};
 	ID	eid;
 
-	u_int32_t	locker = 0;
+	BDB_LOCKER	locker = 0;
 	DB_LOCK		lock, plock;
 
 	int		num_retries = 0;
@@ -52,13 +52,55 @@
 	int	parent_is_glue = 0;
 	int parent_is_leaf = 0;
 
-	ctrls[num_ctrls] = 0;
+#ifdef LDAP_X_TXN
+	int settle = 0;
+#endif
 
 	Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n",
 		op->o_req_dn.bv_val, 0, 0 );
 
+#ifdef LDAP_X_TXN
+	if( op->o_txnSpec ) {
+		/* acquire connection lock */
+		ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
+		if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
+			rs->sr_text = "invalid transaction identifier";
+			rs->sr_err = LDAP_X_TXN_ID_INVALID;
+			goto txnReturn;
+		} else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+			settle=1;
+			goto txnReturn;
+		}
+
+		if( op->o_conn->c_txn_backend == NULL ) {
+			op->o_conn->c_txn_backend = op->o_bd;
+
+		} else if( op->o_conn->c_txn_backend != op->o_bd ) {
+			rs->sr_text = "transaction cannot span multiple database contexts";
+			rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS;
+			goto txnReturn;
+		}
+
+		/* insert operation into transaction */
+
+		rs->sr_text = "transaction specified";
+		rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY;
+
+txnReturn:
+		/* release connection lock */
+		ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
+
+		if( !settle ) {
+			send_ldap_result( op, rs );
+			return rs->sr_err;
+		}
+	}
+#endif
+
+	ctrls[num_ctrls] = 0;
+
 	/* allocate CSN */
-	if ( BER_BVISEMPTY( &op->o_csn )) {
+	if ( BER_BVISNULL( &op->o_csn ) ) {
 		struct berval csn;
 		char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
 
@@ -309,7 +351,11 @@
 			Debug( LDAP_DEBUG_TRACE,
 				"<=- " LDAP_XSTRING(bdb_delete) ": pre-read "
 				"failed!\n", 0, 0, 0 );
-			goto return_results;
+			if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
+				/* FIXME: is it correct to abort
+				 * operation if control fails? */
+				goto return_results;
+			}
 		}
 	}
 
@@ -326,6 +372,9 @@
 		goto return_results;
 	}
 
+	BDB_LOG_PRINTF( bdb->bi_dbenv, lt2, "slapd Starting delete %s(%d)",
+		e->e_nname.bv_val, e->e_id );
+
 	/* Can't do it if we have kids */
 	rs->sr_err = bdb_cache_children( op, lt2, e );
 	if( rs->sr_err != DB_NOTFOUND ) {
@@ -387,8 +436,10 @@
 	/* fixup delete CSN */
 	if ( !SLAP_SHADOW( op->o_bd )) {
 		struct berval vals[2];
+
+		assert( !BER_BVISNULL( &op->o_csn ) );
 		vals[0] = op->o_csn;
-		BER_BVZERO( vals+1 );
+		BER_BVZERO( &vals[1] );
 		rs->sr_err = bdb_index_values( op, lt2, slap_schema.si_ad_entryCSN,
 			vals, 0, SLAP_INDEX_ADD_OP );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -444,6 +495,9 @@
 		p = NULL;
 	}
 
+	BDB_LOG_PRINTF( bdb->bi_dbenv, lt2, "slapd Commit1 delete %s(%d)",
+		e->e_nname.bv_val, e->e_id );
+
 	if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
 		rs->sr_err = LDAP_OTHER;
 		rs->sr_text = "txn_commit(2) failed";
@@ -469,8 +523,11 @@
 			goto return_results;
 		}
 	} else {
-		rc = bdb_cache_delete( &bdb->bi_cache, e, bdb->bi_dbenv,
-			locker, &lock );
+
+		BDB_LOG_PRINTF( bdb->bi_dbenv, ltid, "slapd Cache delete %s(%d)",
+			e->e_nname.bv_val, e->e_id );
+
+		rc = bdb_cache_delete( bdb, e, locker, &lock );
 		switch( rc ) {
 		case DB_LOCK_DEADLOCK:
 		case DB_LOCK_NOTGRANTED:
@@ -482,6 +539,9 @@
 	ltid = NULL;
 	op->o_private = NULL;
 
+	BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Committed delete %s(%d)",
+		e->e_nname.bv_val, e->e_id );
+
 	if( rs->sr_err != 0 ) {
 		Debug( LDAP_DEBUG_TRACE,
 			LDAP_XSTRING(bdb_delete) ": txn_%s failed: %s (%d)\n",
@@ -532,7 +592,7 @@
 		slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
 	}
 
-	if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+	if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) {
 		TXN_CHECKPOINT( bdb->bi_dbenv,
 			bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
 	}

Modified: openldap/trunk/servers/slapd/back-bdb/dn2entry.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/dn2entry.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/dn2entry.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* dn2entry.c - routines to deal with the dn2id / id2entry glue */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/dn2entry.c,v 1.25.2.5 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/dn2entry.c,v 1.28.2.6 2007/12/06 05:43:27 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -34,7 +34,7 @@
 	struct berval *dn,
 	EntryInfo **e,
 	int matched,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	DB_LOCK *lock )
 {
 	EntryInfo *ei = NULL;
@@ -45,7 +45,7 @@
 
 	*e = NULL;
 
-	rc = bdb_cache_find_ndn( op, tid, dn, &ei );
+	rc = bdb_cache_find_ndn( op, locker, dn, &ei );
 	if ( rc ) {
 		if ( matched && rc == DB_NOTFOUND ) {
 			/* Set the return value, whether we have its entry
@@ -54,7 +54,7 @@
 			*e = ei;
 			if ( ei && ei->bei_id ) {
 				rc2 = bdb_cache_find_id( op, tid, ei->bei_id,
-					&ei, 1, locker, lock );
+					&ei, ID_LOCKED, locker, lock );
 				if ( rc2 ) rc = rc2;
 			} else if ( ei ) {
 				bdb_cache_entryinfo_unlock( ei );
@@ -65,7 +65,7 @@
 			bdb_cache_entryinfo_unlock( ei );
 		}
 	} else {
-		rc = bdb_cache_find_id( op, tid, ei->bei_id, &ei, 1,
+		rc = bdb_cache_find_id( op, tid, ei->bei_id, &ei, ID_LOCKED,
 			locker, lock );
 		if ( rc == 0 ) {
 			*e = ei;
@@ -73,7 +73,7 @@
 			/* always return EntryInfo */
 			if ( ei->bei_parent ) {
 				ei = ei->bei_parent;
-				rc2 = bdb_cache_find_id( op, tid, ei->bei_id, &ei, 1,
+				rc2 = bdb_cache_find_id( op, tid, ei->bei_id, &ei, 0,
 					locker, lock );
 				if ( rc2 ) rc = rc2;
 			}

Modified: openldap/trunk/servers/slapd/back-bdb/dn2id.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/dn2id.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/dn2id.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* dn2id.c - routines to deal with the dn2id index */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/dn2id.c,v 1.106.2.15 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/dn2id.c,v 1.137.2.6 2007/12/13 07:05:24 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -23,6 +23,32 @@
 #include "idl.h"
 #include "lutil.h"
 
+#define bdb_dn2id_lock					BDB_SYMBOL(dn2id_lock)
+
+static int
+bdb_dn2id_lock( struct bdb_info *bdb, struct berval *dn,
+	int rw, BDB_LOCKER locker, DB_LOCK *lock )
+{
+	int       rc;
+	DBT       lockobj;
+	int       db_rw;
+
+	if (!locker)
+		return 0;
+
+	if (rw)
+		db_rw = DB_LOCK_WRITE;
+	else
+		db_rw = DB_LOCK_READ;
+
+	lockobj.data = dn->bv_val;
+	lockobj.size = dn->bv_len;
+
+	rc = LOCK_GET(bdb->bi_dbenv, BDB_LOCKID(locker), DB_LOCK_NOWAIT,
+					&lockobj, db_rw, lock);
+	return rc;
+}
+
 #ifndef BDB_HIER
 int
 bdb_dn2id_add(
@@ -39,8 +65,8 @@
 	char		*buf;
 	struct berval	ptr, pdn;
 
-	Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_add( \"%s\", 0x%08lx )\n",
-		e->e_ndn, (long) e->e_id, 0 );
+	Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_add 0x%lx: \"%s\"\n",
+		e->e_id, e->e_ndn, 0 );
 	assert( e->e_id != NOID );
 
 	DBTzero( &key );
@@ -63,8 +89,8 @@
 	/* store it -- don't override */
 	rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
 	if( rc != 0 ) {
-		Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_add: put failed: %s %d\n",
-			db_strerror(rc), rc, 0 );
+		Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_add 0x%lx: put failed: %s %d\n",
+			e->e_id, db_strerror(rc), rc );
 		goto done;
 	}
 
@@ -76,8 +102,8 @@
 		rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-			"=> bdb_dn2id_add: subtree (%s) put failed: %d\n",
-			ptr.bv_val, rc, 0 );
+			"=> bdb_dn2id_add 0x%lx: subtree (%s) put failed: %d\n",
+			e->e_id, ptr.bv_val, rc );
 			goto done;
 		}
 		
@@ -97,8 +123,8 @@
 
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-				"=> bdb_dn2id_add: parent (%s) insert failed: %d\n",
-					ptr.bv_val, rc, 0 );
+				"=> bdb_dn2id_add 0x%lx: parent (%s) insert failed: %d\n",
+					e->e_id, ptr.bv_val, rc );
 			goto done;
 		}
 	}
@@ -115,8 +141,8 @@
 
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-				"=> bdb_dn2id_add: subtree (%s) insert failed: %d\n",
-					ptr.bv_val, rc, 0 );
+				"=> bdb_dn2id_add 0x%lx: subtree (%s) insert failed: %d\n",
+					e->e_id, ptr.bv_val, rc );
 			break;
 		}
 #ifdef BDB_MULTIPLE_SUFFIXES
@@ -133,7 +159,7 @@
 
 done:
 	op->o_tmpfree( buf, op->o_tmpmemctx );
-	Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add: %d\n", rc, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 );
 	return rc;
 }
 
@@ -146,13 +172,14 @@
 {
 	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
 	DB *db = bdb->bi_dn2id->bdi_db;
-	int		rc;
+	char		*buf;
 	DBT		key;
-	char		*buf;
+	DB_LOCK	lock;
 	struct berval	pdn, ptr;
+	int		rc;
 
-	Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete( \"%s\", 0x%08lx )\n",
-		e->e_ndn, e->e_id, 0 );
+	Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete 0x%lx: \"%s\"\n",
+		e->e_id, e->e_ndn, 0 );
 
 	DBTzero( &key );
 	key.size = e->e_nname.bv_len + 2;
@@ -165,11 +192,15 @@
 	AC_MEMCPY( ptr.bv_val, e->e_nname.bv_val, e->e_nname.bv_len );
 	ptr.bv_val[ptr.bv_len] = '\0';
 
+	/* We hold this lock until the TXN completes */
+	rc = bdb_dn2id_lock( bdb, &e->e_nname, 1, TXN_ID( txn ), &lock );
+	if ( rc ) goto done;
+
 	/* delete it */
 	rc = db->del( db, txn, &key, 0 );
 	if( rc != 0 ) {
-		Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_delete: delete failed: %s %d\n",
-			db_strerror(rc), rc, 0 );
+		Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_delete 0x%lx: delete failed: %s %d\n",
+			e->e_id, db_strerror(rc), rc );
 		goto done;
 	}
 
@@ -181,8 +212,8 @@
 		rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id );
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-			"=> bdb_dn2id_delete: subtree (%s) delete failed: %d\n",
-			ptr.bv_val, rc, 0 );
+			"=> bdb_dn2id_delete 0x%lx: subtree (%s) delete failed: %d\n",
+			e->e_id, ptr.bv_val, rc );
 			goto done;
 		}
 
@@ -202,8 +233,8 @@
 
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-				"=> bdb_dn2id_delete: parent (%s) delete failed: %d\n",
-				ptr.bv_val, rc, 0 );
+				"=> bdb_dn2id_delete 0x%lx: parent (%s) delete failed: %d\n",
+				e->e_id, ptr.bv_val, rc );
 			goto done;
 		}
 	}
@@ -219,8 +250,8 @@
 		rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id );
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-				"=> bdb_dn2id_delete: subtree (%s) delete failed: %d\n",
-				ptr.bv_val, rc, 0 );
+				"=> bdb_dn2id_delete 0x%lx: subtree (%s) delete failed: %d\n",
+				e->e_id, ptr.bv_val, rc );
 			goto done;
 		}
 #ifdef BDB_MULTIPLE_SUFFIXES
@@ -237,24 +268,27 @@
 
 done:
 	op->o_tmpfree( buf, op->o_tmpmemctx );
-	Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_delete %d\n", rc, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 );
 	return rc;
 }
 
 int
 bdb_dn2id(
 	Operation *op,
-	DB_TXN *txn,
 	struct berval	*dn,
-	EntryInfo *ei )
+	EntryInfo *ei,
+	BDB_LOCKER locker,
+	DB_LOCK *lock )
 {
 	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
 	DB *db = bdb->bi_dn2id->bdi_db;
+	DBC	*cursor;
 	int		rc;
 	DBT		key, data;
 	ID		nid;
 
 	Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id(\"%s\")\n", dn->bv_val, 0, 0 );
+
 	DBTzero( &key );
 	key.size = dn->bv_len + 2;
 	key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx );
@@ -267,18 +301,31 @@
 	data.ulen = sizeof(ID);
 	data.flags = DB_DBT_USERMEM;
 
+	rc = db->cursor( db, NULL, &cursor, bdb->bi_db_opflags );
+	if ( rc ) goto leave;
+
+	rc = bdb_dn2id_lock( bdb, dn, 0, locker, lock );
+	if ( rc ) goto nolock;
+
+	if ( locker ) {
+		CURSOR_SETLOCKER(cursor, locker);
+	}
+
 	/* fetch it */
-	rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags );
+	rc = cursor->c_get( cursor, &key, &data, DB_SET );
 
+nolock:
+	cursor->c_close( cursor );
+leave:
+
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: get failed: %s (%d)\n",
 			db_strerror( rc ), rc, 0 );
 	} else {
 		BDB_DISK2ID( &nid, &ei->bei_id );
-		Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: got id=0x%08lx\n",
+		Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: got id=0x%lx\n",
 			ei->bei_id, 0, 0 );
 	}
-
 	op->o_tmpfree( key.data, op->o_tmpmemctx );
 	return rc;
 }
@@ -332,7 +379,9 @@
 int
 bdb_dn2idl(
 	Operation *op,
-	Entry *e,
+	BDB_LOCKER locker,
+	struct berval *ndn,
+	EntryInfo *ei,
 	ID *ids,
 	ID *stack )
 {
@@ -344,25 +393,26 @@
 		? DN_ONE_PREFIX : DN_SUBTREE_PREFIX;
 
 	Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2idl(\"%s\")\n",
-		e->e_nname.bv_val, 0, 0 );
+		ndn->bv_val, 0, 0 );
 
 #ifndef	BDB_MULTIPLE_SUFFIXES
-	if ( prefix == DN_SUBTREE_PREFIX && BEI(e)->bei_parent->bei_id == 0 ) {
+	if ( prefix == DN_SUBTREE_PREFIX
+		&& ( ei->bei_id == 0 || ei->bei_parent->bei_id == 0 )) {
 		BDB_IDL_ALL(bdb, ids);
 		return 0;
 	}
 #endif
 
 	DBTzero( &key );
-	key.size = e->e_nname.bv_len + 2;
+	key.size = ndn->bv_len + 2;
 	key.ulen = key.size;
 	key.flags = DB_DBT_USERMEM;
 	key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx );
 	((char *)key.data)[0] = prefix;
-	AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 );
+	AC_MEMCPY( &((char *)key.data)[1], ndn->bv_val, key.size - 1 );
 
 	BDB_IDL_ZERO( ids );
-	rc = bdb_idl_fetch_key( op->o_bd, db, NULL, &key, ids, NULL, 0 );
+	rc = bdb_idl_fetch_key( op->o_bd, db, locker, &key, ids, NULL, 0 );
 
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_TRACE,
@@ -404,6 +454,31 @@
 	unsigned char entryID[sizeof(ID)];  /* variable placement */
 } diskNode;
 
+/* Sort function for the sorted duplicate data items of a dn2id key.
+ * Sorts based on normalized RDN, in length order.
+ */
+int
+hdb_dup_compare(
+	DB *db, 
+	const DBT *usrkey,
+	const DBT *curkey
+)
+{
+	diskNode *un, *cn;
+	int rc, ul, cl;
+
+	un = (diskNode *)usrkey->data;
+	cn = (diskNode *)curkey->data;
+
+	/* data is not aligned, cannot compare directly */
+	rc = un->nrdnlen[0] - cn->nrdnlen[0];
+	if ( rc ) return rc;
+	rc = un->nrdnlen[1] - cn->nrdnlen[1];
+	if ( rc ) return rc;
+
+	return strcmp( un->nrdn, cn->nrdn );
+}
+
 /* This function constructs a full DN for a given entry.
  */
 int hdb_fix_dn(
@@ -479,6 +554,9 @@
 	diskNode *d;
 	char *ptr;
 
+	Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id_add 0x%lx: \"%s\"\n",
+		e->e_id, e->e_ndn, 0 );
+
 	nrlen = dn_rdnlen( op->o_bd, &e->e_nname );
 	if (nrlen) {
 		rlen = dn_rdnlen( op->o_bd, &e->e_name );
@@ -545,7 +623,10 @@
 			bdb_idl_cache_add_id( bdb, db, &key, e->e_id );
 		}
 	}
+
+leave:
 	op->o_tmpfree( d, op->o_tmpmemctx );
+	Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 );
 
 	return rc;
 }
@@ -565,7 +646,11 @@
 	int rc;
 	ID	nid;
 	unsigned char dlen[2];
+	DB_LOCK	lock;
 
+	Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id_delete 0x%lx: \"%s\"\n",
+		e->e_id, e->e_ndn, 0 );
+
 	DBTzero(&key);
 	key.size = sizeof(ID);
 	key.ulen = key.size;
@@ -579,8 +664,6 @@
 	data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
 
 	key.data = &nid;
-	rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
-	if ( rc ) return rc;
 
 	d = op->o_tmpalloc( data.size, op->o_tmpmemctx );
 	d->nrdnlen[1] = BEI(e)->bei_nrdn.bv_len & 0xff;
@@ -590,6 +673,13 @@
 	strcpy( d->nrdn, BEI(e)->bei_nrdn.bv_val );
 	data.data = d;
 
+	rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
+	if ( rc ) goto leave;
+
+	/* We hold this lock until the TXN completes */
+	rc = bdb_dn2id_lock( bdb, &e->e_nname, 1, TXN_ID( txn ), &lock );
+	if ( rc ) goto nolock;
+
 	/* Delete our ID from the parent's list */
 	rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE );
 	if ( rc == 0 ) {
@@ -610,7 +700,10 @@
 		if ( rc == 0 )
 			rc = cursor->c_del( cursor, 0 );
 	}
+
+nolock:
 	cursor->c_close( cursor );
+leave:
 	op->o_tmpfree( d, op->o_tmpmemctx );
 
 	/* Delete IDL cache entries */
@@ -628,6 +721,7 @@
 			bdb_idl_cache_del_id( bdb, db, &key, e->e_id );
 		}
 	}
+	Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 );
 	return rc;
 }
 
@@ -635,9 +729,10 @@
 int
 hdb_dn2id(
 	Operation	*op,
-	DB_TXN *txn,
 	struct berval	*in,
-	EntryInfo	*ei )
+	EntryInfo	*ei,
+	BDB_LOCKER locker,
+	DB_LOCK *lock )
 {
 	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
 	DB *db = bdb->bi_dn2id->bdi_db;
@@ -649,6 +744,8 @@
 	unsigned char dlen[2];
 	ID idp, parentID;
 
+	Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id(\"%s\")\n", in->bv_val, 0, 0 );
+
 	nrlen = dn_rdnlen( op->o_bd, in );
 	if (!nrlen) nrlen = in->bv_len;
 
@@ -666,8 +763,11 @@
 	data.dlen = data.ulen;
 	data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
 
-	rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
+	rc = db->cursor( db, NULL, &cursor, bdb->bi_db_opflags );
 	if ( rc ) return rc;
+	if ( locker ) {
+		CURSOR_SETLOCKER( cursor, locker );
+	}
 
 	d = op->o_tmpalloc( data.size * 3, op->o_tmpmemctx );
 	d->nrdnlen[1] = nrlen & 0xff;
@@ -678,6 +778,9 @@
 	*ptr = '\0';
 	data.data = d;
 
+	rc = bdb_dn2id_lock( bdb, in, 0, locker, lock );
+	if ( rc ) goto leave;
+
 	rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE );
 	if ( rc == 0 && (dlen[1] != d->nrdnlen[1] || dlen[0] != d->nrdnlen[0] ||
 		strncmp( d->nrdn, in->bv_val, nrlen ))) {
@@ -699,8 +802,17 @@
 			ei->bei_parent->bei_dkids = dkids;
 		}
 	}
+
+leave:
 	cursor->c_close( cursor );
 	op->o_tmpfree( d, op->o_tmpmemctx );
+	if( rc != 0 ) {
+		Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: get failed: %s (%d)\n",
+			db_strerror( rc ), rc, 0 );
+	} else {
+		Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: got id=0x%lx\n",
+			ei->bei_id, 0, 0 );
+	}
 
 	return rc;
 }
@@ -708,8 +820,7 @@
 int
 hdb_dn2id_parent(
 	Operation *op,
-	DB_TXN *txn,
-	u_int32_t	locker,
+	BDB_LOCKER	locker,
 	EntryInfo *ei,
 	ID *idp )
 {
@@ -732,10 +843,10 @@
 	DBTzero(&data);
 	data.flags = DB_DBT_USERMEM;
 
-	rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
+	rc = db->cursor( db, NULL, &cursor, bdb->bi_db_opflags );
 	if ( rc ) return rc;
-	if ( !txn && locker ) {
-		cursor->locker = locker;
+	if ( locker ) {
+		CURSOR_SETLOCKER(cursor, locker);
 	}
 
 	data.ulen = sizeof(diskNode) + (SLAP_LDAPDN_MAXLEN * 2);
@@ -830,6 +941,7 @@
 struct dn2id_cookie {
 	struct bdb_info *bdb;
 	Operation *op;
+	BDB_LOCKER locker;
 	EntryInfo *ei;
 	ID *ids;
 	ID *tmp;
@@ -1060,7 +1172,9 @@
 int
 hdb_dn2idl(
 	Operation	*op,
-	Entry		*e,
+	BDB_LOCKER locker,
+	struct berval *ndn,
+	EntryInfo	*ei,
 	ID *ids,
 	ID *stack )
 {
@@ -1068,20 +1182,21 @@
 	struct dn2id_cookie cx;
 
 	Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2idl(\"%s\")\n",
-		e->e_nname.bv_val, 0, 0 );
+		ndn->bv_val, 0, 0 );
 
 #ifndef BDB_MULTIPLE_SUFFIXES
 	if ( op->ors_scope != LDAP_SCOPE_ONELEVEL && 
-		BEI(e)->bei_parent->bei_id == 0 )
+		( ei->bei_id == 0 ||
+		ei->bei_parent->bei_id == 0 ))
 	{
 		BDB_IDL_ALL( bdb, ids );
 		return 0;
 	}
 #endif
 
-	cx.id = e->e_id;
+	cx.id = ei->bei_id;
 	BDB_ID2DISK( cx.id, &cx.nid );
-	cx.ei = e->e_id ? BEI(e) : &bdb->bi_cache.c_dntree;
+	cx.ei = ei;
 	cx.bdb = bdb;
 	cx.db = cx.bdb->bi_dn2id->bdi_db;
 	cx.prefix = (op->ors_scope == LDAP_SCOPE_ONELEVEL) ?
@@ -1090,6 +1205,7 @@
 	cx.tmp = stack;
 	cx.buf = stack + BDB_IDL_UM_SIZE;
 	cx.op = op;
+	cx.locker = locker;
 	cx.need_sort = 0;
 	cx.depth = 0;
 
@@ -1117,8 +1233,9 @@
 		cx.key.data = ptr;
 		cx.key.size = sizeof(ID)+1;
 		*ptr = cx.prefix;
-		cx.id = e->e_id;
-		bdb_idl_cache_put( cx.bdb, cx.db, &cx.key, cx.ids, cx.rc );
+		cx.id = ei->bei_id;
+		if ( cx.bdb->bi_idl_cache_max_size )
+			bdb_idl_cache_put( cx.bdb, cx.db, &cx.key, cx.ids, cx.rc );
 	}
 
 	if ( cx.rc == DB_NOTFOUND )

Modified: openldap/trunk/servers/slapd/back-bdb/error.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/error.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/error.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* error.c - BDB errcall routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/error.c,v 1.15.2.4 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/error.c,v 1.18.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-bdb/extended.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/extended.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/extended.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* extended.c - bdb backend extended routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/extended.c,v 1.16.2.3 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/extended.c,v 1.18.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-bdb/filterindex.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/filterindex.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/filterindex.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* filterindex.c - generate the list of candidate entries from a filter */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/filterindex.c,v 1.51.2.11 2007/07/22 15:20:16 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/filterindex.c,v 1.64.2.4 2007/12/06 05:43:27 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -27,51 +27,59 @@
 
 static int presence_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	AttributeDescription *desc,
 	ID *ids );
 
 static int equality_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	AttributeAssertion *ava,
 	ID *ids,
 	ID *tmp );
 static int inequality_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	AttributeAssertion *ava,
 	ID *ids,
 	ID *tmp,
 	int gtorlt );
 static int approx_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	AttributeAssertion *ava,
 	ID *ids,
 	ID *tmp );
 static int substring_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	SubstringsAssertion *sub,
 	ID *ids,
 	ID *tmp );
 
 static int list_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	Filter *flist,
 	int ftype,
 	ID *ids,
 	ID *tmp,
 	ID *stack );
 
-#ifdef LDAP_COMP_MATCH
 static int
 ext_candidates(
         Operation *op,
+		BDB_LOCKER locker,
         MatchingRuleAssertion *mra,
         ID *ids,
         ID *tmp,
         ID *stack);
 
+#ifdef LDAP_COMP_MATCH
 static int
 comp_candidates (
 	Operation *op,
+	BDB_LOCKER locker,
 	MatchingRuleAssertion *mra,
 	ComponentFilter *f,
 	ID *ids,
@@ -81,6 +89,7 @@
 static int
 ava_comp_candidates (
 		Operation *op,
+		BDB_LOCKER locker,
 		AttributeAssertion *ava,
 		AttributeAliasing *aa,
 		ID *ids,
@@ -91,6 +100,7 @@
 int
 bdb_filter_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	Filter	*f,
 	ID *ids,
 	ID *tmp,
@@ -102,6 +112,11 @@
 #endif
 	Debug( LDAP_DEBUG_FILTER, "=> bdb_filter_candidates\n", 0, 0, 0 );
 
+	if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) {
+		BDB_IDL_ZERO( ids );
+		goto out;
+	}
+
 	switch ( f->f_choice ) {
 	case SLAPD_FILTER_COMPUTED:
 		switch( f->f_result ) {
@@ -124,30 +139,30 @@
 		break;
 	case LDAP_FILTER_PRESENT:
 		Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
-		rc = presence_candidates( op, f->f_desc, ids );
+		rc = presence_candidates( op, locker, f->f_desc, ids );
 		break;
 
 	case LDAP_FILTER_EQUALITY:
 		Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
 #ifdef LDAP_COMP_MATCH
 		if ( is_aliased_attribute && ( aa = is_aliased_attribute ( f->f_ava->aa_desc ) ) ) {
-			rc = ava_comp_candidates ( op, f->f_ava, aa, ids, tmp, stack );
+			rc = ava_comp_candidates ( op, locker, f->f_ava, aa, ids, tmp, stack );
 		}
 		else
 #endif
 		{
-			rc = equality_candidates( op, f->f_ava, ids, tmp );
+			rc = equality_candidates( op, locker, f->f_ava, ids, tmp );
 		}
 		break;
 
 	case LDAP_FILTER_APPROX:
 		Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
-		rc = approx_candidates( op, f->f_ava, ids, tmp );
+		rc = approx_candidates( op, locker, f->f_ava, ids, tmp );
 		break;
 
 	case LDAP_FILTER_SUBSTRINGS:
 		Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 );
-		rc = substring_candidates( op, f->f_sub, ids, tmp );
+		rc = substring_candidates( op, locker, f->f_sub, ids, tmp );
 		break;
 
 	case LDAP_FILTER_GE:
@@ -155,9 +170,9 @@
 		Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
 		if( f->f_ava->aa_desc->ad_type->sat_ordering &&
 			( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
-			rc = inequality_candidates( op, f->f_ava, ids, tmp, LDAP_FILTER_GE );
+			rc = inequality_candidates( op, locker, f->f_ava, ids, tmp, LDAP_FILTER_GE );
 		else
-			rc = presence_candidates( op, f->f_ava->aa_desc, ids );
+			rc = presence_candidates( op, locker, f->f_ava->aa_desc, ids );
 		break;
 
 	case LDAP_FILTER_LE:
@@ -165,9 +180,9 @@
 		Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
 		if( f->f_ava->aa_desc->ad_type->sat_ordering &&
 			( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
-			rc = inequality_candidates( op, f->f_ava, ids, tmp, LDAP_FILTER_LE );
+			rc = inequality_candidates( op, locker, f->f_ava, ids, tmp, LDAP_FILTER_LE );
 		else
-			rc = presence_candidates( op, f->f_ava->aa_desc, ids );
+			rc = presence_candidates( op, locker, f->f_ava->aa_desc, ids );
 		break;
 
 	case LDAP_FILTER_NOT:
@@ -180,21 +195,19 @@
 
 	case LDAP_FILTER_AND:
 		Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
-		rc = list_candidates( op, 
+		rc = list_candidates( op, locker, 
 			f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
 		break;
 
 	case LDAP_FILTER_OR:
 		Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
-		rc = list_candidates( op, 
+		rc = list_candidates( op, locker,
 			f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
 		break;
-#ifdef LDAP_COMP_MATCH
 	case LDAP_FILTER_EXT:
                 Debug( LDAP_DEBUG_FILTER, "\tEXT\n", 0, 0, 0 );
-                rc = ext_candidates( op, f->f_mra, ids, tmp, stack );
+                rc = ext_candidates( op, locker, f->f_mra, ids, tmp, stack );
                 break;
-#endif
 	default:
 		Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN %lu\n",
 			(unsigned long) f->f_choice, 0, 0 );
@@ -204,6 +217,7 @@
 		}
 	}
 
+out:
 	Debug( LDAP_DEBUG_FILTER,
 		"<= bdb_filter_candidates: id=%ld first=%ld last=%ld\n",
 		(long) ids[0],
@@ -217,6 +231,7 @@
 static int
 comp_list_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	MatchingRuleAssertion* mra,
 	ComponentFilter	*flist,
 	int	ftype,
@@ -235,7 +250,7 @@
 			continue;
 		}
 		BDB_IDL_ZERO( save );
-		rc = comp_candidates( op, mra, f, save, tmp, save+BDB_IDL_UM_SIZE );
+		rc = comp_candidates( op, locker, mra, f, save, tmp, save+BDB_IDL_UM_SIZE );
 
 		if ( rc != 0 ) {
 			if ( ftype == LDAP_COMP_FILTER_AND ) {
@@ -281,6 +296,7 @@
 static int
 comp_equality_candidates (
         Operation *op,
+	BDB_LOCKER locker,
         MatchingRuleAssertion *mra,
 	ComponentAssertion *ca,
         ID *ids,
@@ -354,7 +370,7 @@
                 return 0;
         }
         for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-                rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
+                rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
 
                 if( rc == DB_NOTFOUND ) {
                         BDB_IDL_ZERO( ids );
@@ -391,6 +407,7 @@
 static int
 ava_comp_candidates (
 	Operation *op,
+	BDB_LOCKER locker,
 	AttributeAssertion *ava,
 	AttributeAliasing *aa,
 	ID *ids,
@@ -408,12 +425,13 @@
 	mra.ma_desc = aa->aa_aliased_ad;
 	mra.ma_rule = ava->aa_desc->ad_type->sat_equality;
 	
-	return comp_candidates ( op, &mra, ava->aa_cf, ids, tmp, stack );
+	return comp_candidates ( op, locker, &mra, ava->aa_cf, ids, tmp, stack );
 }
 
 static int
 comp_candidates (
 	Operation *op,
+	BDB_LOCKER locker,
 	MatchingRuleAssertion *mra,
 	ComponentFilter *f,
 	ID *ids,
@@ -430,10 +448,10 @@
 		rc = f->cf_result;
 		break;
 	case LDAP_COMP_FILTER_AND:
-		rc = comp_list_candidates( op, mra, f->cf_and, LDAP_COMP_FILTER_AND, ids, tmp, stack );
+		rc = comp_list_candidates( op, locker, mra, f->cf_and, LDAP_COMP_FILTER_AND, ids, tmp, stack );
 		break;
 	case LDAP_COMP_FILTER_OR:
-		rc = comp_list_candidates( op, mra, f->cf_or, LDAP_COMP_FILTER_OR, ids, tmp, stack );
+		rc = comp_list_candidates( op, locker, mra, f->cf_or, LDAP_COMP_FILTER_OR, ids, tmp, stack );
 		break;
 	case LDAP_COMP_FILTER_NOT:
 		/* No component indexing supported for NOT filter */
@@ -445,7 +463,7 @@
 		rc = LDAP_PROTOCOL_ERROR;
 		break;
 	case LDAP_COMP_FILTER_ITEM:
-		rc = comp_equality_candidates( op, mra, f->cf_ca, ids, tmp, stack );
+		rc = comp_equality_candidates( op, locker, mra, f->cf_ca, ids, tmp, stack );
 		break;
 	default:
 		{
@@ -457,32 +475,92 @@
 
 	return( rc );
 }
+#endif
 
 static int
 ext_candidates(
         Operation *op,
+		BDB_LOCKER locker,
         MatchingRuleAssertion *mra,
         ID *ids,
         ID *tmp,
         ID *stack)
 {
+	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
+
+#ifdef LDAP_COMP_MATCH
 	/*
 	 * Currently Only Component Indexing for componentFilterMatch is supported
 	 * Indexing for an extensible filter is not supported yet
 	 */
-	if ( !mra->ma_cf ) {
-		struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-		BDB_IDL_ALL( bdb, ids );
-		return 0;
+	if ( mra->ma_cf ) {
+		return comp_candidates ( op, locker, mra, mra->ma_cf, ids, tmp, stack);
 	}
+#endif
+	if ( mra->ma_desc == slap_schema.si_ad_entryDN ) {
+		int rc;
+		EntryInfo *ei;
 
-	return comp_candidates ( op, mra, mra->ma_cf, ids, tmp, stack);
+		BDB_IDL_ZERO( ids );
+		if ( mra->ma_rule == slap_schema.si_mr_distinguishedNameMatch ) {
+			ei = NULL;
+			rc = bdb_cache_find_ndn( op, locker, &mra->ma_value, &ei );
+			if ( rc == LDAP_SUCCESS )
+				bdb_idl_insert( ids, ei->bei_id );
+			if ( ei )
+				bdb_cache_entryinfo_unlock( ei );
+			return 0;
+		} else if ( mra->ma_rule && mra->ma_rule->smr_match ==
+			dnRelativeMatch && dnIsSuffix( &mra->ma_value,
+				op->o_bd->be_nsuffix )) {
+			int scope;
+			if ( mra->ma_rule == slap_schema.si_mr_dnSuperiorMatch ) {
+				struct berval pdn;
+				ei = NULL;
+				dnParent( &mra->ma_value, &pdn );
+				bdb_cache_find_ndn( op, locker, &pdn, &ei );
+				if ( ei ) {
+					bdb_cache_entryinfo_unlock( ei );
+					while ( ei && ei->bei_id ) {
+						bdb_idl_insert( ids, ei->bei_id );
+						ei = ei->bei_parent;
+					}
+				}
+				return 0;
+			}
+			if ( mra->ma_rule == slap_schema.si_mr_dnSubtreeMatch )
+				scope = LDAP_SCOPE_SUBTREE;
+			else if ( mra->ma_rule == slap_schema.si_mr_dnOneLevelMatch )
+				scope = LDAP_SCOPE_ONELEVEL;
+			else if ( mra->ma_rule == slap_schema.si_mr_dnSubordinateMatch )
+				scope = LDAP_SCOPE_SUBORDINATE;
+			else
+				scope = LDAP_SCOPE_BASE;
+			if ( scope > LDAP_SCOPE_BASE ) {
+				ei = NULL;
+				rc = bdb_cache_find_ndn( op, locker, &mra->ma_value, &ei );
+				if ( ei )
+					bdb_cache_entryinfo_unlock( ei );
+				if ( rc == LDAP_SUCCESS ) {
+					int sc = op->ors_scope;
+					op->ors_scope = scope;
+					rc = bdb_dn2idl( op, locker, &mra->ma_value, ei, ids,
+						stack );
+					op->ors_scope = sc;
+				}
+				return 0;
+			}
+		}
+	}
+
+	BDB_IDL_ALL( bdb, ids );
+	return 0;
 }
-#endif
 
 static int
 list_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	Filter	*flist,
 	int		ftype,
 	ID *ids,
@@ -500,7 +578,7 @@
 			continue;
 		}
 		BDB_IDL_ZERO( save );
-		rc = bdb_filter_candidates( op, f, save, tmp,
+		rc = bdb_filter_candidates( op, locker, f, save, tmp,
 			save+BDB_IDL_UM_SIZE );
 
 		if ( rc != 0 ) {
@@ -548,6 +626,7 @@
 static int
 presence_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	AttributeDescription *desc,
 	ID *ids )
 {
@@ -592,7 +671,7 @@
 		return -1;
 	}
 
-	rc = bdb_key_read( op->o_bd, db, NULL, &prefix, ids, NULL, 0 );
+	rc = bdb_key_read( op->o_bd, db, locker, &prefix, ids, NULL, 0 );
 
 	if( rc == DB_NOTFOUND ) {
 		BDB_IDL_ZERO( ids );
@@ -618,6 +697,7 @@
 static int
 equality_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	AttributeAssertion *ava,
 	ID *ids,
 	ID *tmp )
@@ -688,7 +768,7 @@
 	}
 
 	for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-		rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
+		rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
 
 		if( rc == DB_NOTFOUND ) {
 			BDB_IDL_ZERO( ids );
@@ -734,6 +814,7 @@
 static int
 approx_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	AttributeAssertion *ava,
 	ID *ids,
 	ID *tmp )
@@ -809,7 +890,7 @@
 	}
 
 	for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-		rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
+		rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
 
 		if( rc == DB_NOTFOUND ) {
 			BDB_IDL_ZERO( ids );
@@ -853,6 +934,7 @@
 static int
 substring_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	SubstringsAssertion	*sub,
 	ID *ids,
 	ID *tmp )
@@ -924,7 +1006,7 @@
 	}
 
 	for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-		rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
+		rc = bdb_key_read( op->o_bd, db, locker, &keys[i], tmp, NULL, 0 );
 
 		if( rc == DB_NOTFOUND ) {
 			BDB_IDL_ZERO( ids );
@@ -968,6 +1050,7 @@
 static int
 inequality_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	AttributeAssertion *ava,
 	ID *ids,
 	ID *tmp,
@@ -1040,7 +1123,7 @@
 
 	BDB_IDL_ZERO( ids );
 	while(1) {
-		rc = bdb_key_read( op->o_bd, db, NULL, &keys[0], tmp, &cursor, gtorlt );
+		rc = bdb_key_read( op->o_bd, db, locker, &keys[0], tmp, &cursor, gtorlt );
 
 		if( rc == DB_NOTFOUND ) {
 			rc = 0;

Modified: openldap/trunk/servers/slapd/back-bdb/id2entry.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/id2entry.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/id2entry.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* id2entry.c - routines to deal with the id2entry database */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/id2entry.c,v 1.62.2.10 2007/01/25 12:39:23 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/id2entry.c,v 1.72.2.3 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -18,6 +18,7 @@
 
 #include <stdio.h>
 #include <ac/string.h>
+#include <ac/errno.h>
 
 #include "back-bdb.h"
 
@@ -92,7 +93,7 @@
 int bdb_id2entry(
 	BackendDB *be,
 	DB_TXN *tid,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	ID id,
 	Entry **e )
 {
@@ -100,8 +101,9 @@
 	DB *db = bdb->bi_id2entry->bdi_db;
 	DBT key, data;
 	DBC *cursor;
-	struct berval bv;
-	int rc = 0;
+	EntryHeader eh;
+	char buf[16];
+	int rc = 0, off;
 	ID nid;
 
 	*e = NULL;
@@ -112,29 +114,59 @@
 	BDB_ID2DISK( id, &nid );
 
 	DBTzero( &data );
-	data.flags = DB_DBT_MALLOC;
+	data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
 
 	/* fetch it */
 	rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
 	if ( rc ) return rc;
 
 	/* Use our own locker if needed */
-	if ( !tid && locker )
-		cursor->locker = locker;
+	if ( !tid && locker ) {
+		CURSOR_SETLOCKER( cursor, locker );
+	}
 
+	/* Get the nattrs / nvals counts first */
+	data.ulen = data.dlen = sizeof(buf);
+	data.data = buf;
 	rc = cursor->c_get( cursor, &key, &data, DB_SET );
+	if ( rc ) goto finish;
+
+
+	eh.bv.bv_val = buf;
+	eh.bv.bv_len = data.size;
+	rc = entry_header( &eh );
+	if ( rc ) goto finish;
+
+	/* Get the size */
+	data.flags ^= DB_DBT_PARTIAL;
+	data.ulen = 0;
+	rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
+	if ( rc != DB_BUFFER_SMALL ) goto finish;
+
+	/* Allocate a block and retrieve the data */
+	off = eh.data - eh.bv.bv_val;
+	eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size;
+	eh.bv.bv_val = ch_malloc( eh.bv.bv_len );
+	eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval );
+	data.data = eh.data;
+	data.ulen = data.size;
+
+	/* skip past already parsed nattr/nvals */
+	eh.data += off;
+
+	rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
+
+finish:
 	cursor->c_close( cursor );
 
 	if( rc != 0 ) {
 		return rc;
 	}
 
-	DBT2bv( &data, &bv );
-
 #ifdef SLAP_ZONE_ALLOC
-	rc = entry_decode(&bv, e, bdb->bi_cache.c_zctx);
+	rc = entry_decode(&eh, e, bdb->bi_cache.c_zctx);
 #else
-	rc = entry_decode(&bv, e);
+	rc = entry_decode(&eh, e);
 #endif
 
 	if( rc == 0 ) {
@@ -144,11 +176,11 @@
 		 * decoded in place.
 		 */
 #ifndef SLAP_ZONE_ALLOC
-		ch_free(data.data);
+		ch_free(eh.bv.bv_val);
 #endif
 	}
 #ifdef SLAP_ZONE_ALLOC
-	ch_free(data.data);
+	ch_free(eh.bv.bv_val);
 #endif
 
 	return rc;
@@ -176,64 +208,31 @@
 	return rc;
 }
 
-#ifdef SLAP_ZONE_ALLOC
 int bdb_entry_return(
-	struct bdb_info *bdb,
-	Entry *e,
-	int zseq
-)
-#else
-int bdb_entry_return(
 	Entry *e
 )
-#endif
 {
-#ifdef SLAP_ZONE_ALLOC
-	if (!slap_zn_validate(bdb->bi_cache.c_zctx, e, zseq)) {
-		return 0;
-	}
-#endif
 	/* Our entries are allocated in two blocks; the data comes from
 	 * the db itself and the Entry structure and associated pointers
 	 * are allocated in entry_decode. The db data pointer is saved
-	 * in e_bv. Since the Entry structure is allocated as a single
-	 * block, e_attrs is always a fixed offset from e. The exception
-	 * is when an entry has been modified, in which case we also need
-	 * to free e_attrs.
+	 * in e_bv.
 	 */
-
-#ifdef LDAP_COMP_MATCH
-	comp_tree_free( e->e_attrs );
-#endif
-	if( !e->e_bv.bv_val ) {	/* Entry added by do_add */
-		entry_free( e );
-		return 0;
-	}
-	if( (void *) e->e_attrs != (void *) (e+1)) {
-		attrs_free( e->e_attrs );
-	}
-
-	/* See if the DNs were changed by modrdn */
-	if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val >
-		e->e_bv.bv_val + e->e_bv.bv_len ) {
-		ch_free(e->e_name.bv_val);
-		ch_free(e->e_nname.bv_val);
+	if ( e->e_bv.bv_val ) {
+		/* See if the DNs were changed by modrdn */
+		if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val >
+			e->e_bv.bv_val + e->e_bv.bv_len ) {
+			ch_free(e->e_name.bv_val);
+			ch_free(e->e_nname.bv_val);
+		}
 		e->e_name.bv_val = NULL;
 		e->e_nname.bv_val = NULL;
+		/* In tool mode the e_bv buffer is realloc'd, leave it alone */
+		if( !(slapMode & SLAP_TOOL_MODE) ) {
+			free( e->e_bv.bv_val );
+		}
+		BER_BVZERO( &e->e_bv );
 	}
-#ifndef SLAP_ZONE_ALLOC
-	/* In tool mode the e_bv buffer is realloc'd, leave it alone */
-	if( !(slapMode & SLAP_TOOL_MODE) ) {
-		free( e->e_bv.bv_val );
-	}
-#endif /* !SLAP_ZONE_ALLOC */
-
-#ifdef SLAP_ZONE_ALLOC
-	slap_zn_free( e, bdb->bi_cache.c_zctx );
-#else
-	free( e );
-#endif
-
+	entry_free( e );
 	return 0;
 }
 
@@ -262,14 +261,13 @@
 
 		/* lock is freed with txn */
 		if ( !boi || boi->boi_txn ) {
-			bdb_unlocked_cache_return_entry_rw( &bdb->bi_cache, e, rw );
+			bdb_unlocked_cache_return_entry_rw( bdb, e, rw );
 		} else {
 			struct bdb_lock_info *bli, *prev;
 			for ( prev=(struct bdb_lock_info *)&boi->boi_locks,
 				bli = boi->boi_locks; bli; prev=bli, bli=bli->bli_next ) {
 				if ( bli->bli_id == e->e_id ) {
-					bdb_cache_return_entry_rw( bdb->bi_dbenv, &bdb->bi_cache,
-						e, rw, &bli->bli_lock );
+					bdb_cache_return_entry_rw( bdb, e, rw, &bli->bli_lock );
 					prev->bli_next = bli->bli_next;
 					op->o_tmpfree( bli, op->o_tmpmemctx );
 					break;
@@ -320,7 +318,7 @@
 	int	rc;
 	const char *at_name = at ? at->ad_cname.bv_val : "(null)";
 
-	u_int32_t	locker = 0;
+	BDB_LOCKER	locker = 0;
 	DB_LOCK		lock;
 	int		free_lock_id = 0;
 
@@ -398,7 +396,7 @@
 return_results:
 	if( rc != LDAP_SUCCESS ) {
 		/* free entry */
-		bdb_cache_return_entry_rw(bdb->bi_dbenv, &bdb->bi_cache, e, rw, &lock);
+		bdb_cache_return_entry_rw(bdb, e, rw, &lock);
 
 	} else {
 		if ( slapMode == SLAP_SERVER_MODE ) {
@@ -425,7 +423,7 @@
 			}
 		} else {
 			*ent = entry_dup( e );
-			bdb_cache_return_entry_rw(bdb->bi_dbenv, &bdb->bi_cache, e, rw, &lock);
+			bdb_cache_return_entry_rw(bdb, e, rw, &lock);
 		}
 	}
 

Modified: openldap/trunk/servers/slapd/back-bdb/idl.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/idl.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/idl.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* idl.c - ldap id list handling routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/idl.c,v 1.94.2.15 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/idl.c,v 1.124.2.5 2007/09/26 20:41:38 ando Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -27,31 +27,26 @@
 
 #define IDL_CMP(x,y)	( x < y ? -1 : ( x > y ? 1 : 0 ) )
 
-#define IDL_LRU_DELETE( bdb, e ) do { 					\
-	if ( e->idl_lru_prev != NULL ) {				\
-		e->idl_lru_prev->idl_lru_next = e->idl_lru_next; 	\
-	} else {							\
-		bdb->bi_idl_lru_head = e->idl_lru_next;			\
-	}								\
-	if ( e->idl_lru_next != NULL ) {				\
-		e->idl_lru_next->idl_lru_prev = e->idl_lru_prev;	\
-	} else {							\
-		bdb->bi_idl_lru_tail = e->idl_lru_prev;			\
-	}								\
+#define IDL_LRU_DELETE( bdb, e ) do { \
+	if ( (e) == (bdb)->bi_idl_lru_head ) { \
+		if ( (e)->idl_lru_next == (bdb)->bi_idl_lru_head ) { \
+			(bdb)->bi_idl_lru_head = NULL; \
+		} else { \
+			(bdb)->bi_idl_lru_head = (e)->idl_lru_next; \
+		} \
+	} \
+	if ( (e) == (bdb)->bi_idl_lru_tail ) { \
+		if ( (e)->idl_lru_prev == (bdb)->bi_idl_lru_tail ) { \
+			assert( (bdb)->bi_idl_lru_head == NULL ); \
+			(bdb)->bi_idl_lru_tail = NULL; \
+		} else { \
+			(bdb)->bi_idl_lru_tail = (e)->idl_lru_prev; \
+		} \
+	} \
+	(e)->idl_lru_next->idl_lru_prev = (e)->idl_lru_prev; \
+	(e)->idl_lru_prev->idl_lru_next = (e)->idl_lru_next; \
 } while ( 0 )
 
-#define IDL_LRU_ADD( bdb, e ) do {					\
-	e->idl_lru_next = bdb->bi_idl_lru_head;				\
-	if ( e->idl_lru_next != NULL ) {				\
-		e->idl_lru_next->idl_lru_prev = (e);			\
-	}								\
-	(bdb)->bi_idl_lru_head = (e);					\
-	e->idl_lru_prev = NULL;						\
-	if ( (bdb)->bi_idl_lru_tail == NULL ) {				\
-		(bdb)->bi_idl_lru_tail = (e);				\
-	}								\
-} while ( 0 )
-
 static int
 bdb_idl_entry_cmp( const void *v_idl1, const void *v_idl2 )
 {
@@ -317,10 +312,7 @@
 	if ( matched_idl_entry != NULL ) {
 		if ( matched_idl_entry->idl && ids )
 			BDB_IDL_CPY( ids, matched_idl_entry->idl );
-		ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-		IDL_LRU_DELETE( bdb, matched_idl_entry );
-		IDL_LRU_ADD( bdb, matched_idl_entry );
-		ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+		matched_idl_entry->idl_flags |= CACHE_ENTRY_REFERENCED;
 		if ( matched_idl_entry->idl )
 			rc = LDAP_SUCCESS;
 		else
@@ -340,7 +332,7 @@
 	int			rc )
 {
 	bdb_idl_cache_entry_t idl_tmp;
-	bdb_idl_cache_entry_t *ee;
+	bdb_idl_cache_entry_t *ee, *eprev;
 
 	if ( rc == DB_NOTFOUND || BDB_IDL_IS_ZERO( ids ))
 		return;
@@ -355,6 +347,7 @@
 
 	ee->idl_lru_prev = NULL;
 	ee->idl_lru_next = NULL;
+	ee->idl_flags = 0;
 	ber_dupbv( &ee->kstr, &idl_tmp.kstr );
 	ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
 	if ( avl_insert( &bdb->bi_idl_tree, (caddr_t) ee,
@@ -367,11 +360,34 @@
 		return;
 	}
 	ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-	IDL_LRU_ADD( bdb, ee );
+	/* LRU_ADD */
+	if ( bdb->bi_idl_lru_head ) {
+		assert( bdb->bi_idl_lru_tail != NULL );
+		assert( bdb->bi_idl_lru_head->idl_lru_prev != NULL );
+		assert( bdb->bi_idl_lru_head->idl_lru_next != NULL );
+
+		ee->idl_lru_next = bdb->bi_idl_lru_head;
+		ee->idl_lru_prev = bdb->bi_idl_lru_head->idl_lru_prev;
+		bdb->bi_idl_lru_head->idl_lru_prev->idl_lru_next = ee;
+		bdb->bi_idl_lru_head->idl_lru_prev = ee;
+	} else {
+		ee->idl_lru_next = ee->idl_lru_prev = ee;
+		bdb->bi_idl_lru_tail = ee;
+	}
+	bdb->bi_idl_lru_head = ee;
+
 	if ( ++bdb->bi_idl_cache_size > bdb->bi_idl_cache_max_size ) {
-		int i = 0;
-		while ( bdb->bi_idl_lru_tail != NULL && i < 10 ) {
-			ee = bdb->bi_idl_lru_tail;
+		int i;
+		ee = bdb->bi_idl_lru_tail;
+		for ( i = 0; ee != NULL && i < 10; i++, ee = eprev ) {
+			eprev = ee->idl_lru_prev;
+			if ( eprev == ee ) {
+				eprev = NULL;
+			}
+			if ( ee->idl_flags & CACHE_ENTRY_REFERENCED ) {
+				ee->idl_flags ^= CACHE_ENTRY_REFERENCED;
+				continue;
+			}
 			if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) ee,
 				    bdb_idl_entry_cmp ) == NULL ) {
 				Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_put: "
@@ -385,8 +401,10 @@
 			ch_free( ee->idl );
 			ch_free( ee );
 		}
+		bdb->bi_idl_lru_tail = eprev;
+		assert( bdb->bi_idl_lru_tail != NULL
+			|| bdb->bi_idl_lru_head == NULL );
 	}
-
 	ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
 	ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
 }
@@ -484,7 +502,7 @@
 bdb_idl_fetch_key(
 	BackendDB	*be,
 	DB			*db,
-	DB_TXN		*tid,
+	BDB_LOCKER locker,
 	DBT			*key,
 	ID			*ids,
 	DBC                     **saved_cursor,
@@ -557,12 +575,13 @@
 
 	/* If we're not reusing an existing cursor, get a new one */
 	if( opflag != DB_NEXT ) {
-		rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
+		rc = db->cursor( db, NULL, &cursor, bdb->bi_db_opflags );
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
 				"cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 );
 			return rc;
 		}
+		CURSOR_SETLOCKER( cursor, locker );
 	} else {
 		cursor = *saved_cursor;
 	}

Modified: openldap/trunk/servers/slapd/back-bdb/idl.h
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/idl.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/idl.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* idl.h - ldap bdb back-end ID list header file */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/idl.h,v 1.16.2.4 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/idl.h,v 1.19.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-bdb/index.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/index.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/index.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* index.c - routines for dealing with attribute indexes */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/index.c,v 1.46.2.11 2007/07/22 15:54:14 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/index.c,v 1.61.2.4 2007/12/01 18:10:47 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -25,10 +25,10 @@
 #include "back-bdb.h"
 #include "lutil_hash.h"
 
-static char presence_keyval[LUTIL_HASH_BYTES] = {0,0,0,1};
-static struct berval presence_key = {LUTIL_HASH_BYTES, presence_keyval};
+static char presence_keyval[] = {0,0};
+static struct berval presence_key = BER_BVC(presence_keyval);
 
-static AttrInfo *index_mask(
+AttrInfo *bdb_index_mask(
 	Backend *be,
 	AttributeDescription *desc,
 	struct berval *atname )
@@ -70,21 +70,6 @@
 	return 0;
 }
 
-int bdb_index_is_indexed(
-	Backend *be,
-	AttributeDescription *desc )
-{
-	AttrInfo *ai;
-	struct berval prefix;
-
-	ai = index_mask( be, desc, &prefix );
-
-	if( !ai )
-		return LDAP_INAPPROPRIATE_MATCHING;
-
-	return LDAP_SUCCESS;
-}
-
 /* This function is only called when evaluating search filters.
  */
 int bdb_index_param(
@@ -97,17 +82,37 @@
 {
 	AttrInfo *ai;
 	int rc;
-	slap_mask_t mask;
+	slap_mask_t mask, type = 0;
 	DB *db;
 
-	ai = index_mask( be, desc, prefixp );
+	ai = bdb_index_mask( be, desc, prefixp );
 
-	if( !ai ) {
+	if ( !ai ) {
+#ifdef BDB_MONITOR_IDX
+		switch ( ftype ) {
+		case LDAP_FILTER_PRESENT:
+			type = SLAP_INDEX_PRESENT;
+			break;
+		case LDAP_FILTER_APPROX:
+			type = SLAP_INDEX_APPROX;
+			break;
+		case LDAP_FILTER_EQUALITY:
+			type = SLAP_INDEX_EQUALITY;
+			break;
+		case LDAP_FILTER_SUBSTRINGS:
+			type = SLAP_INDEX_SUBSTR;
+			break;
+		default:
+			return LDAP_INAPPROPRIATE_MATCHING;
+		}
+		bdb_monitor_idx_add( be->be_private, desc, type );
+#endif /* BDB_MONITOR_IDX */
+
 		return LDAP_INAPPROPRIATE_MATCHING;
 	}
 	mask = ai->ai_indexmask;
 
-	rc = bdb_db_cache( be, prefixp->bv_val, &db );
+	rc = bdb_db_cache( be, prefixp, &db );
 
 	if( rc != LDAP_SUCCESS ) {
 		return rc;
@@ -115,6 +120,7 @@
 
 	switch( ftype ) {
 	case LDAP_FILTER_PRESENT:
+		type = SLAP_INDEX_PRESENT;
 		if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
 			*prefixp = presence_key;
 			goto done;
@@ -122,6 +128,7 @@
 		break;
 
 	case LDAP_FILTER_APPROX:
+		type = SLAP_INDEX_APPROX;
 		if ( desc->ad_type->sat_approx ) {
 			if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
 				goto done;
@@ -133,12 +140,14 @@
 		/* fall thru */
 
 	case LDAP_FILTER_EQUALITY:
+		type = SLAP_INDEX_EQUALITY;
 		if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
 			goto done;
 		}
 		break;
 
 	case LDAP_FILTER_SUBSTRINGS:
+		type = SLAP_INDEX_SUBSTR;
 		if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
 			goto done;
 		}
@@ -148,6 +157,10 @@
 		return LDAP_OTHER;
 	}
 
+#ifdef BDB_MONITOR_IDX
+	bdb_monitor_idx_add( be->be_private, desc, type );
+#endif /* BDB_MONITOR_IDX */
+
 	return LDAP_INAPPROPRIATE_MATCHING;
 
 done:
@@ -172,7 +185,7 @@
 
 	assert( mask != 0 );
 
-	rc = bdb_db_cache( op->o_bd, atname->bv_val, &db );
+	rc = bdb_db_cache( op->o_bd, atname, &db );
 	
 	if ( rc != LDAP_SUCCESS ) {
 		Debug( LDAP_DEBUG_ANY,
@@ -490,8 +503,8 @@
 		AttrInfo *ai;
 		/* see if attribute has components to be indexed */
 		ai = bdb_attr_mask( op->o_bd->be_private, ap->a_desc->ad_type->sat_ad );
-		if ( ai ) cr_list = ai->ai_cr;
-		else cr_list = NULL;
+		if ( !ai ) continue;
+		cr_list = ai->ai_cr;
 		if ( attr_converter && cr_list ) {
 			syn = ap->a_desc->ad_type->sat_syntax;
 			ap->a_comp_data = op->o_tmpalloc( sizeof( ComponentData ), op->o_tmpmemctx );

Modified: openldap/trunk/servers/slapd/back-bdb/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* init.c - initialize bdb backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/init.c,v 1.177.2.29 2007/08/06 12:32:51 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/init.c,v 1.247.2.8 2007/12/06 15:13:57 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -26,29 +26,31 @@
 #include <lutil.h>
 #include <ldap_rq.h>
 #include "alock.h"
+#include "config.h"
 
 static const struct bdbi_database {
 	char *file;
-	char *name;
+	struct berval name;
 	int type;
 	int flags;
 } bdbi_databases[] = {
-	{ "id2entry" BDB_SUFFIX, "id2entry", DB_BTREE, 0 },
-	{ "dn2id" BDB_SUFFIX, "dn2id", DB_BTREE, 0 },
-	{ NULL, NULL, 0, 0 }
+	{ "id2entry" BDB_SUFFIX, BER_BVC("id2entry"), DB_BTREE, 0 },
+	{ "dn2id" BDB_SUFFIX, BER_BVC("dn2id"), DB_BTREE, 0 },
+	{ NULL, BER_BVNULL, 0, 0 }
 };
 
 typedef void * db_malloc(size_t);
 typedef void * db_realloc(void *, size_t);
 
 #define bdb_db_init	BDB_SYMBOL(db_init)
-#define bdb_db_open	BDB_SYMBOL(db_open)
-#define bdb_db_close	BDB_SYMBOL(db_close)
+#define bdb_db_open BDB_SYMBOL(db_open)
+#define bdb_db_close BDB_SYMBOL(db_close)
 
 static int
-bdb_db_init( BackendDB *be )
+bdb_db_init( BackendDB *be, ConfigReply *cr )
 {
 	struct bdb_info	*bdb;
+	int rc;
 
 	Debug( LDAP_DEBUG_TRACE,
 		LDAP_XSTRING(bdb_db_init) ": Initializing " BDB_UCTYPE " database\n",
@@ -74,8 +76,9 @@
 #ifdef BDB_HIER
 	ldap_pvt_thread_mutex_init( &bdb->bi_modrdns_mutex );
 #endif
-	ldap_pvt_thread_mutex_init( &bdb->bi_cache.lru_head_mutex );
-	ldap_pvt_thread_mutex_init( &bdb->bi_cache.lru_tail_mutex );
+	ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_lru_mutex );
+	ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_count_mutex );
+	ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_eifree_mutex );
 	ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_dntree.bei_kids_mutex );
 	ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock );
 	ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock );
@@ -84,14 +87,20 @@
 	be->be_private = bdb;
 	be->be_cf_ocs = be->bd_info->bi_cf_ocs;
 
-	return 0;
+#ifndef BDB_MULTIPLE_SUFFIXES
+	SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_ONE_SUFFIX;
+#endif
+
+	rc = bdb_monitor_db_init( be );
+
+	return rc;
 }
 
 static int
-bdb_db_close( BackendDB *be );
+bdb_db_close( BackendDB *be, ConfigReply *cr );
 
 static int
-bdb_db_open( BackendDB *be )
+bdb_db_open( BackendDB *be, ConfigReply *cr )
 {
 	int rc, i;
 	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
@@ -99,35 +108,29 @@
 	u_int32_t flags;
 	char path[MAXPATHLEN];
 	char *dbhome;
-	int do_recover = 0, do_alock_recover = 0, open_env = 1;
+	Entry *e = NULL;
+	int do_recover = 0, do_alock_recover = 0;
 	int alockt, quick = 0;
 
 	if ( be->be_suffix == NULL ) {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": need suffix\n",
-			0, 0, 0 );
+			LDAP_XSTRING(bdb_db_open) ": need suffix.\n",
+			1, 0, 0 );
 		return -1;
 	}
 
 	Debug( LDAP_DEBUG_ARGS,
-		LDAP_XSTRING(bdb_db_open) ": %s\n",
+		LDAP_XSTRING(bdb_db_open) ": \"%s\"\n",
 		be->be_suffix[0].bv_val, 0, 0 );
 
-#ifndef BDB_MULTIPLE_SUFFIXES
-	if ( be->be_suffix[1].bv_val ) {
-	Debug( LDAP_DEBUG_ANY,
-		LDAP_XSTRING(bdb_db_open) ": only one suffix allowed\n", 0, 0, 0 );
-		return -1;
-	}
-#endif
-
 	/* Check existence of dbenv_home. Any error means trouble */
 	rc = stat( bdb->bi_dbenv_home, &stat1 );
-	if( rc !=0 ) {
+	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": Cannot access database directory %s (%d)\n",
-			bdb->bi_dbenv_home, errno, 0 );
-			return -1;
+			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+			"cannot access database directory \"%s\" (%d).\n",
+			be->be_suffix[0].bv_val, bdb->bi_dbenv_home, errno );
+		return -1;
 	}
 
 	/* Perform database use arbitration/recovery logic */
@@ -147,20 +150,22 @@
 
 	if( rc == ALOCK_RECOVER ) {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": unclean shutdown detected;"
-			" attempting recovery.\n", 
-			0, 0, 0 );
+			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+			"unclean shutdown detected; attempting recovery.\n", 
+			be->be_suffix[0].bv_val, 0, 0 );
 		do_alock_recover = 1;
 		do_recover = DB_RECOVER;
 	} else if( rc == ALOCK_BUSY ) {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": database already in use\n", 
-			0, 0, 0 );
+			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+			"database already in use.\n", 
+			be->be_suffix[0].bv_val, 0, 0 );
 		return -1;
 	} else if( rc != ALOCK_CLEAN ) {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": alock package is unstable\n", 
-			0, 0, 0 );
+			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+			"alock package is unstable.\n", 
+			be->be_suffix[0].bv_val, 0, 0 );
 		return -1;
 	}
 
@@ -177,9 +182,20 @@
 			if( stat( path, &stat2 ) == 0 ) {
 				if( stat2.st_mtime < stat1.st_mtime ) {
 					Debug( LDAP_DEBUG_ANY,
-						LDAP_XSTRING(bdb_db_open) ": DB_CONFIG for suffix %s has changed.\n"
-						"Performing database recovery to activate new settings.\n",
-						be->be_suffix[0].bv_val, 0, 0 );
+						LDAP_XSTRING(bdb_db_open) ": DB_CONFIG for suffix \"%s\" has changed.\n",
+							be->be_suffix[0].bv_val, 0, 0 );
+					if ( quick ) {
+						Debug( LDAP_DEBUG_ANY,
+							"Cannot use Quick mode; perform manual recovery first.\n",
+							0, 0, 0 );
+						slapMode ^= SLAP_TOOL_QUICK;
+						rc = -1;
+						goto fail;
+					} else {
+						Debug( LDAP_DEBUG_ANY,
+							"Performing database recovery to activate new settings.\n",
+							0, 0, 0 );
+					}
 					do_recover = DB_RECOVER;
 				}
 			}
@@ -187,9 +203,9 @@
 	}
 	else {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": Warning - No DB_CONFIG file found "
-			"in directory %s: (%d)\n"
-			"Expect poor performance for suffix %s.\n",
+			LDAP_XSTRING(bdb_db_open) ": warning - no DB_CONFIG file found "
+			"in directory %s: (%d).\n"
+			"Expect poor performance for suffix \"%s\".\n",
 			bdb->bi_dbenv_home, errno, be->be_suffix[0].bv_val );
 	}
 
@@ -199,9 +215,10 @@
 	 */
 	if ( do_recover && ( slapMode & SLAP_TOOL_READONLY )) {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": Recovery skipped in read-only mode. "
+			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+			"recovery skipped in read-only mode. "
 			"Run manual recovery if errors are encountered.\n",
-			0, 0, 0 );
+			be->be_suffix[0].bv_val, 0, 0 );
 		do_recover = 0;
 		quick = alockt;
 	}
@@ -209,8 +226,9 @@
 	/* An existing environment in Quick mode has nothing to recover. */
 	if ( alockt && do_recover ) {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": cannot recover, database must be reinitialized.\n", 
-			0, 0, 0 );
+			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+			"cannot recover, database must be reinitialized.\n", 
+			be->be_suffix[0].bv_val, 0, 0 );
 		rc = -1;
 		goto fail;
 	}
@@ -218,8 +236,9 @@
 	rc = db_env_create( &bdb->bi_dbenv, 0 );
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": db_env_create failed: %s (%d)\n",
-			db_strerror(rc), rc, 0 );
+			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+			"db_env_create failed: %s (%d).\n",
+			be->be_suffix[0].bv_val, db_strerror(rc), rc );
 		goto fail;
 	}
 
@@ -239,16 +258,18 @@
 		rc = bdb->bi_dbenv->remove( bdb->bi_dbenv, dbhome, DB_FORCE );
 		if ( rc ) {
 			Debug( LDAP_DEBUG_ANY,
-				LDAP_XSTRING(bdb_db_open) ": dbenv remove failed: %s (%d)\n",
-				db_strerror(rc), rc, 0 );
+				LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+				"dbenv remove failed: %s (%d).\n",
+				be->be_suffix[0].bv_val, db_strerror(rc), rc );
 			bdb->bi_dbenv = NULL;
 			goto fail;
 		}
 		rc = db_env_create( &bdb->bi_dbenv, 0 );
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-				LDAP_XSTRING(bdb_db_open) ": db_env_create failed: %s (%d)\n",
-				db_strerror(rc), rc, 0 );
+				LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+				"db_env_create failed: %s (%d).\n",
+				be->be_suffix[0].bv_val, db_strerror(rc), rc );
 			goto fail;
 		}
 	}
@@ -266,8 +287,9 @@
 			bdb->bi_dbenv_xflags, 1);
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-				LDAP_XSTRING(bdb_db_open) ": dbenv_set_flags failed: %s (%d)\n",
-				db_strerror(rc), rc, 0 );
+				LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+				"dbenv_set_flags failed: %s (%d).\n",
+				be->be_suffix[0].bv_val, db_strerror(rc), rc );
 			goto fail;
 		}
 	}
@@ -275,8 +297,9 @@
 #define	BDB_TXN_FLAGS	(DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN)
 
 	Debug( LDAP_DEBUG_TRACE,
-		LDAP_XSTRING(bdb_db_open) ": dbenv_open(%s)\n",
-		bdb->bi_dbenv_home, 0, 0);
+		LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+		"dbenv_open(%s).\n",
+		be->be_suffix[0].bv_val, bdb->bi_dbenv_home, 0);
 
 	flags = DB_INIT_MPOOL | DB_CREATE | DB_THREAD;
 
@@ -300,22 +323,23 @@
 			rc = db_env_create( &bdb->bi_dbenv, 0 );
 			if( rc == 0 ) {
 				Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_db_open)
-					": Shared memory env open failed, assuming stale env\n",
-					0, 0, 0 );
+					": database \"%s\": "
+					"shared memory env open failed, assuming stale env.\n",
+					be->be_suffix[0].bv_val, 0, 0 );
 				goto shm_retry;
 			}
 		}
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": Database cannot be %s, err %d. "
+			LDAP_XSTRING(bdb_db_open) ": database \"%s\" cannot be %s, err %d. "
 			"Restore from backup!\n",
-				do_recover ? "recovered" : "opened", rc, 0);
+			be->be_suffix[0].bv_val, do_recover ? "recovered" : "opened", rc );
 		goto fail;
 	}
 
 	if ( do_alock_recover && alock_recover (&bdb->bi_alock_info) != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": alock_recover failed\n",
-			0, 0, 0 );
+			LDAP_XSTRING(bdb_db_open) ": database \"%s\": alock_recover failed\n",
+			be->be_suffix[0].bv_val, 0, 0 );
 		rc = -1;
 		goto fail;
 	}
@@ -323,13 +347,16 @@
 #ifdef SLAP_ZONE_ALLOC
 	if ( bdb->bi_cache.c_maxsize ) {
 		bdb->bi_cache.c_zctx = slap_zn_mem_create(
-								SLAP_ZONE_INITSIZE,
-								SLAP_ZONE_MAXSIZE,
-								SLAP_ZONE_DELTA,
-								SLAP_ZONE_SIZE);
+			SLAP_ZONE_INITSIZE, SLAP_ZONE_MAXSIZE,
+			SLAP_ZONE_DELTA, SLAP_ZONE_SIZE);
 	}
 #endif
 
+	/* Default dncache to 2x entrycache */
+	if ( bdb->bi_cache.c_maxsize && !bdb->bi_cache.c_eimax ) {
+		bdb->bi_cache.c_eimax = bdb->bi_cache.c_maxsize * 2;
+	}
+
 	if ( bdb->bi_idl_cache_max_size ) {
 		bdb->bi_idl_tree = NULL;
 		bdb->bi_idl_cache_size = 0;
@@ -346,16 +373,20 @@
 		BDB_INDICES * sizeof(struct bdb_db_info *) );
 
 	/* open (and create) main database */
-	for( i = 0; bdbi_databases[i].name; i++ ) {
+	for( i = 0; bdbi_databases[i].name.bv_val; i++ ) {
 		struct bdb_db_info *db;
 
 		db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));
 
 		rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 );
 		if( rc != 0 ) {
+			snprintf(cr->msg, sizeof(cr->msg),
+				"database \"%s\": db_create(%s) failed: %s (%d).",
+				be->be_suffix[0].bv_val, 
+				bdb->bi_dbenv_home, db_strerror(rc), rc );
 			Debug( LDAP_DEBUG_ANY,
-				LDAP_XSTRING(bdb_db_open) ": db_create(%s) failed: %s (%d)\n",
-				bdb->bi_dbenv_home, db_strerror(rc), rc );
+				LDAP_XSTRING(bdb_db_open) ": %s\n",
+				cr->msg, 0, 0 );
 			goto fail;
 		}
 
@@ -381,6 +412,8 @@
 				flags |= DB_CREATE;
 			}
 #else
+			rc = db->bdi_db->set_dup_compare( db->bdi_db,
+				bdb_dup_compare );
 			if ( slapMode & (SLAP_TOOL_READONLY|SLAP_TOOL_READMAIN) ) {
 				flags |= DB_RDONLY;
 			} else {
@@ -410,13 +443,14 @@
 #endif
 
 		if ( rc != 0 ) {
-			char	buf[SLAP_TEXT_BUFLEN];
-
-			snprintf( buf, sizeof(buf), "%s/%s", 
-				bdb->bi_dbenv_home, bdbi_databases[i].file );
+			snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
+				"db_open(%s/%s) failed: %s (%d).", 
+				be->be_suffix[0].bv_val, 
+				bdb->bi_dbenv_home, bdbi_databases[i].file,
+				db_strerror(rc), rc );
 			Debug( LDAP_DEBUG_ANY,
-				LDAP_XSTRING(bdb_db_open) ": db_open(%s) failed: %s (%d)\n",
-				buf, db_strerror(rc), rc );
+				LDAP_XSTRING(bdb_db_open) ": %s\n",
+				cr->msg, 0, 0 );
 			db->bdi_db->close( db->bdi_db, 0 );
 			goto fail;
 		}
@@ -432,33 +466,78 @@
 	/* get nextid */
 	rc = bdb_last_id( be, NULL );
 	if( rc != 0 ) {
+		snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
+			"last_id(%s) failed: %s (%d).",
+			be->be_suffix[0].bv_val, bdb->bi_dbenv_home,
+			db_strerror(rc), rc );
 		Debug( LDAP_DEBUG_ANY,
-			LDAP_XSTRING(bdb_db_open) ": last_id(%s) failed: %s (%d)\n",
-			bdb->bi_dbenv_home, db_strerror(rc), rc );
+			LDAP_XSTRING(bdb_db_open) ": %s\n",
+			cr->msg, 0, 0 );
 		goto fail;
 	}
 
 	if ( !quick ) {
+#if DB_VERSION_FULL >= 0x04060012
+		u_int32_t lid;
+		XLOCK_ID(bdb->bi_dbenv, &lid);
+		__lock_getlocker(bdb->bi_dbenv->lk_handle, lid, 0, &bdb->bi_cache.c_locker);
+#else
 		XLOCK_ID(bdb->bi_dbenv, &bdb->bi_cache.c_locker);
+#endif
 	}
 
+	entry_prealloc( bdb->bi_cache.c_maxsize );
+	attr_prealloc( bdb->bi_cache.c_maxsize * 20 );
+
+	/* setup for empty-DN contexts */
+	if ( BER_BVISEMPTY( &be->be_nsuffix[0] )) {
+		rc = bdb_id2entry( be, NULL, 0, 0, &e );
+	}
+	if ( !e ) {
+		e = entry_alloc();
+		e->e_id = 0;
+		ber_dupbv( &e->e_name, (struct berval *)&slap_empty_bv );
+		ber_dupbv( &e->e_nname, (struct berval *)&slap_empty_bv );
+	}
+	e->e_ocflags = SLAP_OC_GLUE|SLAP_OC__END;
+	e->e_private = &bdb->bi_cache.c_dntree;
+	bdb->bi_cache.c_dntree.bei_e = e;
+
+	/* monitor setup */
+	rc = bdb_monitor_db_open( be );
+	if ( rc != 0 ) {
+		goto fail;
+	}
+
 	bdb->bi_flags |= BDB_IS_OPEN;
 
 	return 0;
 
 fail:
-	bdb_db_close( be );
+	bdb_db_close( be, NULL );
 	return rc;
 }
 
 static int
-bdb_db_close( BackendDB *be )
+bdb_db_close( BackendDB *be, ConfigReply *cr )
 {
 	int rc;
 	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
 	struct bdb_db_info *db;
 	bdb_idl_cache_entry_t *entry, *next_entry;
 
+	/* monitor handling */
+	(void)bdb_monitor_db_close( be );
+
+	{
+		Entry *e = bdb->bi_cache.c_dntree.bei_e;
+		if ( e ) {
+			bdb->bi_cache.c_dntree.bei_e = NULL;
+			e->e_private = NULL;
+			bdb_entry_return( e );
+		}
+	}
+
 	bdb->bi_flags &= ~BDB_IS_OPEN;
 
 	ber_bvarray_free( bdb->bi_db_config );
@@ -469,7 +548,7 @@
 		rc = db->bdi_db->close( db->bdi_db, 0 );
 		/* Lower numbered names are not strdup'd */
 		if( bdb->bi_ndatabases >= BDB_NDB )
-			free( db->bdi_name );
+			free( db->bdi_name.bv_val );
 		free( db );
 	}
 	free( bdb->bi_databases );
@@ -477,18 +556,18 @@
 
 	bdb_cache_release_all (&bdb->bi_cache);
 
-	if ( bdb->bi_idl_cache_max_size ) {
+	if ( bdb->bi_idl_cache_size ) {
 		avl_free( bdb->bi_idl_tree, NULL );
 		bdb->bi_idl_tree = NULL;
 		entry = bdb->bi_idl_lru_head;
-		while ( entry != NULL ) {
+		do {
 			next_entry = entry->idl_lru_next;
 			if ( entry->idl )
 				free( entry->idl );
 			free( entry->kstr.bv_val );
 			free( entry );
 			entry = next_entry;
-		}
+		} while ( entry != bdb->bi_idl_lru_head );
 		bdb->bi_idl_lru_head = bdb->bi_idl_lru_tail = NULL;
 	}
 
@@ -496,7 +575,11 @@
 	if( bdb->bi_dbenv ) {
 		/* Free cache locker if we enabled locking */
 		if ( !( slapMode & SLAP_TOOL_QUICK )) {
+#if DB_VERSION_FULL >= 0x04060012
+			XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker->id);
+#else
 			XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker);
+#endif
 			bdb->bi_cache.c_locker = 0;
 		}
 #ifdef BDB_REUSE_LOCKERS
@@ -509,8 +592,9 @@
 			rc = TXN_CHECKPOINT( bdb->bi_dbenv, 0, 0, DB_FORCE );
 			if( rc != 0 ) {
 				Debug( LDAP_DEBUG_ANY,
-					"bdb_db_close: txn_checkpoint failed: %s (%d)\n",
-					db_strerror(rc), rc, 0 );
+					"bdb_db_close: database \"%s\": "
+					"txn_checkpoint failed: %s (%d).\n",
+					be->be_suffix[0].bv_val, db_strerror(rc), rc );
 			}
 		}
 
@@ -518,16 +602,18 @@
 		bdb->bi_dbenv = NULL;
 		if( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-				"bdb_db_close: close failed: %s (%d)\n",
-				db_strerror(rc), rc, 0 );
+				"bdb_db_close: database \"%s\": "
+				"close failed: %s (%d)\n",
+				be->be_suffix[0].bv_val, db_strerror(rc), rc );
 			return rc;
 		}
 	}
 
-	rc = alock_close( &bdb->bi_alock_info );
+	rc = alock_close( &bdb->bi_alock_info, slapMode & SLAP_TOOL_QUICK );
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			"bdb_db_close: alock_close failed\n", 0, 0, 0 );
+			"bdb_db_close: database \"%s\": alock_close failed\n",
+			be->be_suffix[0].bv_val, 0, 0 );
 		return -1;
 	}
 
@@ -535,18 +621,22 @@
 }
 
 static int
-bdb_db_destroy( BackendDB *be )
+bdb_db_destroy( BackendDB *be, ConfigReply *cr )
 {
 	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
 
+	/* monitor handling */
+	(void)bdb_monitor_db_destroy( be );
+
 	if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home );
 	if( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path );
 
 	bdb_attr_index_destroy( bdb );
 
 	ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
-	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_head_mutex );
-	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_tail_mutex );
+	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_lru_mutex );
+	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_count_mutex );
+	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_eifree_mutex );
 	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_dntree.bei_kids_mutex );
 #ifdef BDB_HIER
 	ldap_pvt_thread_mutex_destroy( &bdb->bi_modrdns_mutex );
@@ -577,6 +667,9 @@
 		LDAP_CONTROL_POST_READ,
 		LDAP_CONTROL_SUBENTRIES,
 		LDAP_CONTROL_X_PERMISSIVE_MODIFY,
+#ifdef LDAP_X_TXN
+		LDAP_CONTROL_X_TXN_SPEC,
+#endif
 		NULL
 	};
 
@@ -674,7 +767,6 @@
 	bi->bi_tool_entry_reindex = bdb_tool_entry_reindex;
 	bi->bi_tool_sync = 0;
 	bi->bi_tool_dn2id_get = bdb_tool_dn2id_get;
-	bi->bi_tool_id2entry_get = bdb_tool_id2entry_get;
 	bi->bi_tool_entry_modify = bdb_tool_entry_modify;
 
 	bi->bi_connection_init = 0;

Modified: openldap/trunk/servers/slapd/back-bdb/key.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/key.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/key.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* index.c - routines for dealing with attribute indexes */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/key.c,v 1.16.2.4 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/key.c,v 1.20.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -30,7 +30,7 @@
 bdb_key_read(
 	Backend	*be,
 	DB *db,
-	DB_TXN *txn,
+	BDB_LOCKER locker,
 	struct berval *k,
 	ID *ids,
 	DBC **saved_cursor,
@@ -47,7 +47,7 @@
 	key.ulen = key.size;
 	key.flags = DB_DBT_USERMEM;
 
-	rc = bdb_idl_fetch_key( be, db, txn, &key, ids, saved_cursor, get_flag );
+	rc = bdb_idl_fetch_key( be, db, locker, &key, ids, saved_cursor, get_flag );
 
 	if( rc != LDAP_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE, "<= bdb_index_read: failed (%d)\n",

Modified: openldap/trunk/servers/slapd/back-bdb/modify.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/modify.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/modify.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* modify.c - bdb backend modify routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/modify.c,v 1.124.2.17 2007/04/11 18:32:24 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/modify.c,v 1.156.2.6 2007/12/10 17:54:46 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -42,6 +42,8 @@
 	Attribute	*save_attrs;
 	Attribute 	*ap;
 	int			glue_attr_delete = 0;
+	int			got_delete;
+	AttrInfo *ai;
 
 	Debug( LDAP_DEBUG_TRACE, "bdb_modify_internal: 0x%08lx: %s\n",
 		e->e_id, e->e_dn, 0);
@@ -87,7 +89,9 @@
 	}
 
 	for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
+		struct berval ix_at;
 		mod = &ml->sml_mod;
+		got_delete = 0;
 
 		switch ( mod->sm_op ) {
 		case LDAP_MOD_ADD:
@@ -117,6 +121,8 @@
 			if( err != LDAP_SUCCESS ) {
 				Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
 					err, *text, 0);
+			} else {
+				got_delete = 1;
 			}
 			break;
 
@@ -129,6 +135,8 @@
 			if( err != LDAP_SUCCESS ) {
 				Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
 					err, *text, 0);
+			} else {
+				got_delete = 1;
 			}
 			break;
 
@@ -142,6 +150,8 @@
 				Debug(LDAP_DEBUG_ARGS,
 					"bdb_modify_internal: %d %s\n",
 					err, *text, 0);
+			} else {
+				got_delete = 1;
 			}
 			break;
 
@@ -194,24 +204,35 @@
 
 		/* check if modified attribute was indexed
 		 * but not in case of NOOP... */
-		err = bdb_index_is_indexed( op->o_bd, mod->sm_desc );
-		if ( err == LDAP_SUCCESS && !op->o_noop ) {
-			ap = attr_find( save_attrs, mod->sm_desc );
-			if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL;
+		ai = bdb_index_mask( op->o_bd, mod->sm_desc, &ix_at );
+		if ( ai && !op->o_noop ) {
+			if ( got_delete ) {
+				struct berval ix2;
 
-			ap = attr_find( e->e_attrs, mod->sm_desc );
-			if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD;
+				ap = attr_find( save_attrs, mod->sm_desc );
+				if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL;
+
+				/* Find all other attrs that index to same slot */
+				for ( ap = e->e_attrs; ap; ap=ap->a_next ) {
+					ai = bdb_index_mask( op->o_bd, ap->a_desc, &ix2 );
+					if ( ai && ix2.bv_val == ix_at.bv_val )
+						ap->a_flags |= SLAP_ATTR_IXADD;
+				}
+			} else {
+				ap = attr_find( e->e_attrs, mod->sm_desc );
+				if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD;
+			}
 		}
 	}
 
 	/* check that the entry still obeys the schema */
-	rc = entry_schema_check( op, e, save_attrs, get_manageDIT(op),
+	rc = entry_schema_check( op, e, save_attrs, get_relax(op), 0,
 		text, textbuf, textlen );
 	if ( rc != LDAP_SUCCESS || op->o_noop ) {
 		attrs_free( e->e_attrs );
 		/* clear the indexing flags */
 		for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) {
-			ap->a_flags = 0;
+			ap->a_flags &= ~(SLAP_ATTR_IXADD|SLAP_ATTR_IXDEL);
 		}
 		e->e_attrs = save_attrs;
 
@@ -230,24 +251,57 @@
 	/* start with deleting the old index entries */
 	for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) {
 		if ( ap->a_flags & SLAP_ATTR_IXDEL ) {
-			rc = bdb_index_values( op, tid, ap->a_desc,
-				ap->a_nvals,
-				e->e_id, SLAP_INDEX_DELETE_OP );
-			if ( rc != LDAP_SUCCESS ) {
-				attrs_free( e->e_attrs );
-				e->e_attrs = save_attrs;
-				Debug( LDAP_DEBUG_ANY,
-				       "Attribute index delete failure",
-				       0, 0, 0 );
-				return rc;
+			struct berval *vals;
+			Attribute *a2;
+			ap->a_flags &= ~SLAP_ATTR_IXDEL;
+			a2 = attr_find( e->e_attrs, ap->a_desc );
+			if ( a2 ) {
+				/* need to detect which values were deleted */
+				int i, j;
+				struct berval tmp;
+				j = ap->a_numvals;
+				for ( i=0; i<j; ) {
+					rc = attr_valfind( a2, SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
+						&ap->a_nvals[i], NULL, op->o_tmpmemctx );
+					/* Move deleted values to end of array */
+					if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) {
+						j--;
+						if ( i != j ) {
+							tmp = ap->a_nvals[j];
+							ap->a_nvals[j] = ap->a_nvals[i];
+							ap->a_nvals[i] = tmp;
+							tmp = ap->a_vals[j];
+							ap->a_vals[j] = ap->a_vals[i];
+							ap->a_vals[i] = tmp;
+						}
+						continue;
+					}
+					i++;
+				}
+				vals = &ap->a_nvals[j];
+			} else {
+				/* attribute was completely deleted */
+				vals = ap->a_nvals;
 			}
-			ap->a_flags &= ~SLAP_ATTR_IXDEL;
+			if ( !BER_BVISEMPTY( vals )) {
+				rc = bdb_index_values( op, tid, ap->a_desc,
+					vals, e->e_id, SLAP_INDEX_DELETE_OP );
+				if ( rc != LDAP_SUCCESS ) {
+					attrs_free( e->e_attrs );
+					e->e_attrs = save_attrs;
+					Debug( LDAP_DEBUG_ANY,
+						   "Attribute index delete failure",
+						   0, 0, 0 );
+					return rc;
+				}
+			}
 		}
 	}
 
 	/* add the new index entries */
 	for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
 		if (ap->a_flags & SLAP_ATTR_IXADD) {
+			ap->a_flags &= ~SLAP_ATTR_IXADD;
 			rc = bdb_index_values( op, tid, ap->a_desc,
 				ap->a_nvals,
 				e->e_id, SLAP_INDEX_ADD_OP );
@@ -259,7 +313,6 @@
 				       0, 0, 0 );
 				return rc;
 			}
-			ap->a_flags &= ~SLAP_ATTR_IXADD;
 		}
 	}
 
@@ -281,7 +334,7 @@
 	Entry		dummy = {0};
 	int			fakeroot = 0;
 
-	u_int32_t	locker = 0;
+	BDB_LOCKER	locker = 0;
 	DB_LOCK		lock;
 
 	int		num_retries = 0;
@@ -293,9 +346,51 @@
 
 	int rc;
 
+#ifdef LDAP_X_TXN
+	int settle = 0;
+#endif
+
 	Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(bdb_modify) ": %s\n",
 		op->o_req_dn.bv_val, 0, 0 );
 
+#ifdef LDAP_X_TXN
+	if( op->o_txnSpec ) {
+		/* acquire connection lock */
+		ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
+		if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
+			rs->sr_text = "invalid transaction identifier";
+			rs->sr_err = LDAP_X_TXN_ID_INVALID;
+			goto txnReturn;
+		} else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+			settle=1;
+			goto txnReturn;
+		}
+
+		if( op->o_conn->c_txn_backend == NULL ) {
+			op->o_conn->c_txn_backend = op->o_bd;
+
+		} else if( op->o_conn->c_txn_backend != op->o_bd ) {
+			rs->sr_text = "transaction cannot span multiple database contexts";
+			rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS;
+			goto txnReturn;
+		}
+
+		/* insert operation into transaction */
+
+		rs->sr_text = "transaction specified";
+		rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY;
+
+txnReturn:
+		/* release connection lock */
+		ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
+
+		if( !settle ) {
+			send_ldap_result( op, rs );
+			return rs->sr_err;
+		}
+	}
+#endif
+
 	ctrls[num_ctrls] = NULL;
 
 	slap_mods_opattrs( op, &op->orm_modlist, 1 );
@@ -457,9 +552,13 @@
 			&slap_pre_read_bv, preread_ctrl ) )
 		{
 			Debug( LDAP_DEBUG_TRACE,
-				"<=- " LDAP_XSTRING(bdb_modify) ": pre-read failed!\n",
-				0, 0, 0 );
-			goto return_results;
+				"<=- " LDAP_XSTRING(bdb_modify) ": pre-read "
+				"failed!\n", 0, 0, 0 );
+			if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
+				/* FIXME: is it correct to abort
+				 * operation if control fails? */
+				goto return_results;
+			}
 		}
 	}
 
@@ -476,7 +575,7 @@
 	}
 	/* Modify the entry */
 	dummy = *e;
-	rs->sr_err = bdb_modify_internal( op, lt2, op->oq_modify.rs_modlist,
+	rs->sr_err = bdb_modify_internal( op, lt2, op->orm_modlist,
 		&dummy, &rs->sr_text, textbuf, textlen );
 
 	if( rs->sr_err != LDAP_SUCCESS ) {
@@ -528,7 +627,11 @@
 			Debug( LDAP_DEBUG_TRACE,
 				"<=- " LDAP_XSTRING(bdb_modify)
 				": post-read failed!\n", 0, 0, 0 );
-			goto return_results;
+			if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
+				/* FIXME: is it correct to abort
+				 * operation if control fails? */
+				goto return_results;
+			}
 		}
 	}
 
@@ -552,7 +655,7 @@
 			attrs_free( dummy.e_attrs );
 
 		} else {
-			rc = bdb_cache_modify( e, dummy.e_attrs, bdb->bi_dbenv, locker, &lock );
+			rc = bdb_cache_modify( bdb, e, dummy.e_attrs, locker, &lock );
 			switch( rc ) {
 			case DB_LOCK_DEADLOCK:
 			case DB_LOCK_NOTGRANTED:
@@ -592,7 +695,7 @@
 	}
 	send_ldap_result( op, rs );
 
-	if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+	if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) {
 		TXN_CHECKPOINT( bdb->bi_dbenv,
 			bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
 	}

Modified: openldap/trunk/servers/slapd/back-bdb/modrdn.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/modrdn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/modrdn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* modrdn.c - bdb backend modrdn routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/modrdn.c,v 1.160.2.12 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/modrdn.c,v 1.185.2.6 2007/12/06 05:43:27 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -33,8 +33,6 @@
 	Entry		*p = NULL;
 	EntryInfo	*ei = NULL, *eip = NULL, *nei = NULL, *neip = NULL;
 	/* LDAP v2 supporting correct attribute handling. */
-	LDAPRDN		new_rdn = NULL;
-	LDAPRDN		old_rdn = NULL;
 	char textbuf[SLAP_TEXT_BUFLEN];
 	size_t textlen = sizeof textbuf;
 	DB_TXN		*ltid = NULL, *lt2;
@@ -46,12 +44,9 @@
 	struct berval	*np_ndn = NULL;			/* newSuperior ndn */
 	struct berval	*new_parent_dn = NULL;	/* np_dn, p_dn, or NULL */
 
-	/* Used to interface with bdb_modify_internal() */
-	Modifications	*mod = NULL;		/* Used to delete old rdn */
-
 	int		manageDSAit = get_manageDSAit( op );
 
-	u_int32_t	locker = 0;
+	BDB_LOCKER	locker = 0;
 	DB_LOCK		lock, plock, nplock;
 
 	int		num_retries = 0;
@@ -66,12 +61,56 @@
 	int parent_is_glue = 0;
 	int parent_is_leaf = 0;
 
-	ctrls[num_ctrls] = NULL;
+#ifdef LDAP_X_TXN
+	int settle = 0;
+#endif
 
 	Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) "(%s,%s,%s)\n",
 		op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,
 		op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" );
 
+#ifdef LDAP_X_TXN
+	if( op->o_txnSpec ) {
+		/* acquire connection lock */
+		ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
+		if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
+			rs->sr_text = "invalid transaction identifier";
+			rs->sr_err = LDAP_X_TXN_ID_INVALID;
+			goto txnReturn;
+		} else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+			settle=1;
+			goto txnReturn;
+		}
+
+		if( op->o_conn->c_txn_backend == NULL ) {
+			op->o_conn->c_txn_backend = op->o_bd;
+
+		} else if( op->o_conn->c_txn_backend != op->o_bd ) {
+			rs->sr_text = "transaction cannot span multiple database contexts";
+			rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS;
+			goto txnReturn;
+		}
+
+		/* insert operation into transaction */
+
+		rs->sr_text = "transaction specified";
+		rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY;
+
+txnReturn:
+		/* release connection lock */
+		ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
+
+		if( !settle ) {
+			send_ldap_result( op, rs );
+			return rs->sr_err;
+		}
+	}
+#endif
+
+	ctrls[num_ctrls] = NULL;
+
+	slap_mods_opattrs( op, &op->orr_modlist, 1 );
+
 	if( 0 ) {
 retry:	/* transaction retry */
 		if ( dummy.e_attrs ) {
@@ -264,11 +303,11 @@
 		dnParent( &e->e_nname, &p_ndn );
 	}
 	np_ndn = &p_ndn;
-	if ( p_ndn.bv_len != 0 ) {
+	eip = ei->bei_parent;
+	if ( eip && eip->bei_id ) {
 		/* Make sure parent entry exist and we can write its 
 		 * children.
 		 */
-		eip = ei->bei_parent;
 		rs->sr_err = bdb_cache_find_id( op, ltid,
 			eip->bei_id, &eip, 0, locker, &plock );
 
@@ -503,6 +542,8 @@
 		struct berval bv = {0, NULL};
 		dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx );
 		ber_dupbv( &new_ndn, &bv );
+		/* FIXME: why not call dnNormalize() w/o ctx? */
+		op->o_tmpfree( bv.bv_val, op->o_tmpmemctx );
 	}
 
 	Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": new ndn=%s\n",
@@ -510,7 +551,7 @@
 
 	/* Shortcut the search */
 	nei = neip ? neip : eip;
-	rs->sr_err = bdb_cache_find_ndn ( op, ltid, &new_ndn, &nei );
+	rs->sr_err = bdb_cache_find_ndn ( op, locker, &new_ndn, &nei );
 	if ( nei ) bdb_cache_entryinfo_unlock( nei );
 	switch( rs->sr_err ) {
 	case DB_LOCK_DEADLOCK:
@@ -527,49 +568,8 @@
 		goto return_results;
 	}
 
-	/* Get attribute type and attribute value of our new rdn, we will
-	 * need to add that to our new entry
-	 */
-	if ( !new_rdn && ldap_bv2rdn_x( &op->oq_modrdn.rs_newrdn, &new_rdn,
-		(char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) )
-	{
-		Debug( LDAP_DEBUG_TRACE,
-			LDAP_XSTRING(bdb_modrdn) ": can't figure out "
-			"type(s)/values(s) of newrdn\n", 
-			0, 0, 0 );
-		rs->sr_err = LDAP_INVALID_DN_SYNTAX;
-		rs->sr_text = "unknown type(s) used in RDN";
-		goto return_results;
-	}
+	assert( op->orr_modlist != NULL );
 
-	Debug( LDAP_DEBUG_TRACE,
-		LDAP_XSTRING(bdb_modrdn)
-		": new_rdn_type=\"%s\", new_rdn_val=\"%s\"\n",
-		new_rdn[ 0 ]->la_attr.bv_val,
-		new_rdn[ 0 ]->la_value.bv_val, 0 );
-
-	if ( op->oq_modrdn.rs_deleteoldrdn ) {
-		if ( !old_rdn && ldap_bv2rdn_x( &op->o_req_dn, &old_rdn,
-			(char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) )
-		{
-			Debug( LDAP_DEBUG_TRACE,
-				LDAP_XSTRING(bdb_modrdn) ": can't figure out "
-				"the old_rdn type(s)/value(s)\n", 
-				0, 0, 0 );
-			rs->sr_err = LDAP_OTHER;
-			rs->sr_text = "cannot parse RDN from old DN";
-			goto return_results;		
-		}
-	}
-
-	/* prepare modlist of modifications from old/new rdn */
-	if (!mod) {
-		rs->sr_err = slap_modrdn2mods( op, rs, e, old_rdn, new_rdn, &mod );
-		if ( rs->sr_err != LDAP_SUCCESS ) {
-			goto return_results;
-		}
-	}
-
 	if( op->o_preread ) {
 		if( preread_ctrl == NULL ) {
 			preread_ctrl = &ctrls[num_ctrls++];
@@ -580,8 +580,12 @@
 		{
 			Debug( LDAP_DEBUG_TRACE,        
 				"<=- " LDAP_XSTRING(bdb_modrdn)
-				": post-read failed!\n", 0, 0, 0 );
-			goto return_results;
+				": pre-read failed!\n", 0, 0, 0 );
+			if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
+				/* FIXME: is it correct to abort
+				 * operation if control fails? */
+				goto return_results;
+			}
 		}                   
 	}
 
@@ -641,7 +645,7 @@
 	dummy.e_attrs = e->e_attrs;
 
 	/* modify entry */
-	rs->sr_err = bdb_modify_internal( op, lt2, &mod[0], &dummy,
+	rs->sr_err = bdb_modify_internal( op, lt2, op->orr_modlist, &dummy,
 		&rs->sr_text, textbuf, textlen );
 	if( rs->sr_err != LDAP_SUCCESS ) {
 		Debug(LDAP_DEBUG_TRACE,
@@ -719,7 +723,11 @@
 			Debug( LDAP_DEBUG_TRACE,        
 				"<=- " LDAP_XSTRING(bdb_modrdn)
 				": post-read failed!\n", 0, 0, 0 );
-			goto return_results;
+			if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
+				/* FIXME: is it correct to abort
+				 * operation if control fails? */
+				goto return_results;
+			}
 		}                   
 	}
 
@@ -777,7 +785,7 @@
 	}
 	send_ldap_result( op, rs );
 
-	if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+	if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) {
 		TXN_CHECKPOINT( bdb->bi_dbenv,
 			bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
 	}
@@ -792,19 +800,6 @@
 	if( new_dn.bv_val != NULL ) free( new_dn.bv_val );
 	if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val );
 
-	/* LDAP v2 supporting correct attribute handling. */
-	if ( new_rdn != NULL ) {
-		ldap_rdnfree_x( new_rdn, op->o_tmpmemctx );
-	}
-
-	if ( old_rdn != NULL ) {
-		ldap_rdnfree_x( old_rdn, op->o_tmpmemctx );
-	}
-
-	if( mod != NULL ) {
-		slap_modrdn2mods_free( mod );
-	}
-
 	/* LDAP v3 Support */
 	if( np != NULL ) {
 		/* free new parent and reader lock */

Copied: openldap/trunk/servers/slapd/back-bdb/monitor.c (from rev 891, openldap/vendor/openldap-2.4.7/servers/slapd/back-bdb/monitor.c)
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/monitor.c	                        (rev 0)
+++ openldap/trunk/servers/slapd/back-bdb/monitor.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,734 @@
+/* monitor.c - monitor bdb backend */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/monitor.c,v 1.19.2.7 2007/11/15 00:59:10 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2000-2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+#include <ac/stdlib.h>
+#include <ac/errno.h>
+#include <sys/stat.h>
+#include "lutil.h"
+#include "back-bdb.h"
+
+#include "../back-monitor/back-monitor.h"
+
+#include "config.h"
+
+static ObjectClass		*oc_olmBDBDatabase;
+
+static AttributeDescription	*ad_olmBDBEntryCache,
+	*ad_olmBDBDNCache, *ad_olmBDBIDLCache,
+	*ad_olmDbDirectory;
+
+#ifdef BDB_MONITOR_IDX
+static int
+bdb_monitor_idx_entry_add(
+	struct bdb_info	*bdb,
+	Entry		*e );
+
+static AttributeDescription	*ad_olmBDBNotIndexed;
+#endif /* BDB_MONITOR_IDX */
+
+/*
+ * NOTE: there's some confusion in monitor OID arc;
+ * by now, let's consider:
+ * 
+ * Subsystems monitor attributes	1.3.6.1.4.1.4203.666.1.55.0
+ * Databases monitor attributes		1.3.6.1.4.1.4203.666.1.55.0.1
+ * BDB database monitor attributes	1.3.6.1.4.1.4203.666.1.55.0.1.1
+ *
+ * Subsystems monitor objectclasses	1.3.6.1.4.1.4203.666.3.16.0
+ * Databases monitor objectclasses	1.3.6.1.4.1.4203.666.3.16.0.1
+ * BDB database monitor objectclasses	1.3.6.1.4.1.4203.666.3.16.0.1.1
+ */
+
+static struct {
+	char			*name;
+	char			*oid;
+}		s_oid[] = {
+	{ "olmBDBAttributes",			"olmDatabaseAttributes:1" },
+	{ "olmBDBObjectClasses",		"olmDatabaseObjectClasses:1" },
+
+	{ NULL }
+};
+
+static struct {
+	char			*desc;
+	AttributeDescription	**ad;
+}		s_at[] = {
+	{ "( olmBDBAttributes:1 "
+		"NAME ( 'olmBDBEntryCache' ) "
+		"DESC 'Number of items in Entry Cache' "
+		"SUP monitorCounter "
+		"NO-USER-MODIFICATION "
+		"USAGE dSAOperation )",
+		&ad_olmBDBEntryCache },
+
+	{ "( olmBDBAttributes:2 "
+		"NAME ( 'olmBDBDNCache' ) "
+		"DESC 'Number of items in DN Cache' "
+		"SUP monitorCounter "
+		"NO-USER-MODIFICATION "
+		"USAGE dSAOperation )",
+		&ad_olmBDBDNCache },
+
+	{ "( olmBDBAttributes:3 "
+		"NAME ( 'olmBDBIDLCache' ) "
+		"DESC 'Number of items in IDL Cache' "
+		"SUP monitorCounter "
+		"NO-USER-MODIFICATION "
+		"USAGE dSAOperation )",
+		&ad_olmBDBIDLCache },
+
+	{ "( olmBDBAttributes:4 "
+		"NAME ( 'olmDbDirectory' ) "
+		"DESC 'Path name of the directory "
+			"where the database environment resides' "
+		"SUP monitoredInfo "
+		"NO-USER-MODIFICATION "
+		"USAGE dSAOperation )",
+		&ad_olmDbDirectory },
+
+#ifdef BDB_MONITOR_IDX
+	{ "( olmBDBAttributes:5 "
+		"NAME ( 'olmBDBNotIndexed' ) "
+		"DESC 'Missing indexes resulting from candidate selection' "
+		"SUP monitoredInfo "
+		"NO-USER-MODIFICATION "
+		"USAGE dSAOperation )",
+		&ad_olmBDBNotIndexed },
+#endif /* BDB_MONITOR_IDX */
+
+	{ NULL }
+};
+
+static struct {
+	char		*desc;
+	ObjectClass	**oc;
+}		s_oc[] = {
+	/* augments an existing object, so it must be AUXILIARY
+	 * FIXME: derive from some ABSTRACT "monitoredEntity"? */
+	{ "( olmBDBObjectClasses:1 "
+		"NAME ( 'olmBDBDatabase' ) "
+		"SUP top AUXILIARY "
+		"MAY ( "
+			"olmBDBEntryCache "
+			"$ olmBDBDNCache "
+			"$ olmBDBIDLCache "
+			"$ olmDbDirectory "
+#ifdef BDB_MONITOR_IDX
+			"$ olmBDBNotIndexed "
+#endif /* BDB_MONITOR_IDX */
+			") )",
+		&oc_olmBDBDatabase },
+
+	{ NULL }
+};
+
+static int
+bdb_monitor_update(
+	Operation	*op,
+	SlapReply	*rs,
+	Entry		*e,
+	void		*priv )
+{
+	struct bdb_info		*bdb = (struct bdb_info *) priv;
+	Attribute		*a;
+
+	char			buf[ BUFSIZ ];
+	struct berval		bv;
+
+	assert( ad_olmBDBEntryCache != NULL );
+
+	a = attr_find( e->e_attrs, ad_olmBDBEntryCache );
+	assert( a != NULL );
+	bv.bv_val = buf;
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%d", bdb->bi_cache.c_cursize );
+	ber_bvreplace( &a->a_vals[ 0 ], &bv );
+
+	a = attr_find( e->e_attrs, ad_olmBDBDNCache );
+	assert( a != NULL );
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%d", bdb->bi_cache.c_eiused );
+	ber_bvreplace( &a->a_vals[ 0 ], &bv );
+
+	a = attr_find( e->e_attrs, ad_olmBDBIDLCache );
+	assert( a != NULL );
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%d", bdb->bi_idl_cache_size );
+	ber_bvreplace( &a->a_vals[ 0 ], &bv );
+	
+#ifdef BDB_MONITOR_IDX
+	bdb_monitor_idx_entry_add( bdb, e );
+#endif /* BDB_MONITOR_IDX */
+
+	return SLAP_CB_CONTINUE;
+}
+
+#if 0	/* uncomment if required */
+static int
+bdb_monitor_modify(
+	Operation	*op,
+	SlapReply	*rs,
+	Entry		*e,
+	void		*priv )
+{
+	return SLAP_CB_CONTINUE;
+}
+#endif
+
+static int
+bdb_monitor_free(
+	Entry		*e,
+	void		**priv )
+{
+	struct berval	values[ 2 ];
+	Modification	mod = { 0 };
+
+	const char	*text;
+	char		textbuf[ SLAP_TEXT_BUFLEN ];
+
+	int		i, rc;
+
+	/* NOTE: if slap_shutdown != 0, priv might have already been freed */
+	*priv = NULL;
+
+	/* Remove objectClass */
+	mod.sm_op = LDAP_MOD_DELETE;
+	mod.sm_desc = slap_schema.si_ad_objectClass;
+	mod.sm_values = values;
+	mod.sm_numvals = 1;
+	values[ 0 ] = oc_olmBDBDatabase->soc_cname;
+	BER_BVZERO( &values[ 1 ] );
+
+	rc = modify_delete_values( e, &mod, 1, &text,
+		textbuf, sizeof( textbuf ) );
+	/* don't care too much about return code... */
+
+	/* remove attrs */
+	mod.sm_values = NULL;
+	mod.sm_numvals = 0;
+	for ( i = 0; s_at[ i ].desc != NULL; i++ ) {
+		mod.sm_desc = *s_at[ i ].ad;
+		rc = modify_delete_values( e, &mod, 1, &text,
+			textbuf, sizeof( textbuf ) );
+		/* don't care too much about return code... */
+	}
+	
+	return SLAP_CB_CONTINUE;
+}
+
+#define	bdb_monitor_initialize	BDB_SYMBOL(monitor_initialize)
+
+/*
+ * call from within bdb_initialize()
+ */
+static int
+bdb_monitor_initialize( void )
+{
+	int		i, code;
+	ConfigArgs c;
+	char	*argv[ 3 ];
+
+	static int	bdb_monitor_initialized = 0;
+
+	if ( backend_info( "monitor" ) == NULL ) {
+		return -1;
+	}
+
+	if ( bdb_monitor_initialized++ ) {
+		return 0;
+	}
+
+	/* register schema here */
+
+	argv[ 0 ] = "back-bdb/back-hdb monitor";
+	c.argv = argv;
+	c.argc = 3;
+	c.fname = argv[0];
+
+	for ( i = 0; s_oid[ i ].name; i++ ) {
+		c.lineno = i;
+		argv[ 1 ] = s_oid[ i ].name;
+		argv[ 2 ] = s_oid[ i ].oid;
+
+		if ( parse_oidm( &c, 0, NULL ) != 0 ) {
+			Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize)
+				": unable to add "
+				"objectIdentifier \"%s=%s\"\n",
+				s_oid[ i ].name, s_oid[ i ].oid, 0 );
+			return 1;
+		}
+	}
+
+	for ( i = 0; s_at[ i ].desc != NULL; i++ ) {
+		code = register_at( s_at[ i ].desc, s_at[ i ].ad, 1 );
+		if ( code != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize)
+				": register_at failed\n",
+				0, 0, 0 );
+		}
+		(*s_at[ i ].ad)->ad_type->sat_flags |= SLAP_AT_HIDE;
+	}
+
+	for ( i = 0; s_oc[ i ].desc != NULL; i++ ) {
+		code = register_oc( s_oc[ i ].desc, s_oc[ i ].oc, 1 );
+		if ( code != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize)
+				": register_oc failed\n",
+				0, 0, 0 );
+		}
+		(*s_oc[ i ].oc)->soc_flags |= SLAP_OC_HIDE;
+	}
+
+	return 0;
+}
+
+/*
+ * call from within bdb_db_init()
+ */
+int
+bdb_monitor_db_init( BackendDB *be )
+{
+	struct bdb_info		*bdb = (struct bdb_info *) be->be_private;
+
+	if ( SLAP_GLUE_SUBORDINATE( be ) ) {
+		return 0;
+	}
+
+	if ( bdb_monitor_initialize() == LDAP_SUCCESS ) {
+		/* monitoring in back-bdb is on by default */
+		SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_MONITORING;
+	}
+
+#ifdef BDB_MONITOR_IDX
+	bdb->bi_idx = NULL;
+	ldap_pvt_thread_mutex_init( &bdb->bi_idx_mutex );
+#endif /* BDB_MONITOR_IDX */
+
+	return 0;
+}
+
+/*
+ * call from within bdb_db_open()
+ */
+int
+bdb_monitor_db_open( BackendDB *be )
+{
+	struct bdb_info		*bdb = (struct bdb_info *) be->be_private;
+	Attribute		*a, *next;
+	monitor_callback_t	*cb = NULL;
+	int			rc = 0;
+	BackendInfo		*mi;
+	monitor_extra_t		*mbe;
+	struct berval dummy = BER_BVC("");
+
+	if ( !SLAP_DBMONITORING( be ) ) {
+		return 0;
+	}
+
+	if ( SLAP_GLUE_SUBORDINATE( be ) ) {
+		return 0;
+	}
+
+	mi = backend_info( "monitor" );
+	if ( !mi || !mi->bi_extra ) {
+		SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING;
+		return 0;
+	}
+	mbe = mi->bi_extra;
+
+	/* don't bother if monitor is not configured */
+	if ( !mbe->is_configured() ) {
+		static int warning = 0;
+
+		if ( warning++ == 0 ) {
+			Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_db_open)
+				": monitoring disabled; "
+				"configure monitor database to enable\n",
+				0, 0, 0 );
+		}
+
+		return 0;
+	}
+
+	/* alloc as many as required (plus 1 for objectClass) */
+	a = attrs_alloc( 1 + 4 );
+	if ( a == NULL ) {
+		rc = 1;
+		goto cleanup;
+	}
+
+	a->a_desc = slap_schema.si_ad_objectClass;
+	attr_valadd( a, &oc_olmBDBDatabase->soc_cname, NULL, 1 );
+	next = a->a_next;
+
+	{
+		struct berval	bv = BER_BVC( "0" );
+
+		next->a_desc = ad_olmBDBEntryCache;
+		attr_valadd( next, &bv, NULL, 1 );
+		next = next->a_next;
+
+		next->a_desc = ad_olmBDBDNCache;
+		attr_valadd( next, &bv, NULL, 1 );
+		next = next->a_next;
+
+		next->a_desc = ad_olmBDBIDLCache;
+		attr_valadd( next, &bv, NULL, 1 );
+		next = next->a_next;
+	}
+
+	{
+		struct berval	bv, nbv;
+		ber_len_t	pathlen = 0, len = 0;
+		char		path[ PATH_MAX ] = { '\0' };
+		char		*fname = bdb->bi_dbenv_home,
+				*ptr;
+
+		len = strlen( fname );
+		if ( fname[ 0 ] != '/' ) {
+			/* get full path name */
+			getcwd( path, sizeof( path ) );
+			pathlen = strlen( path );
+
+			if ( fname[ 0 ] == '.' && fname[ 1 ] == '/' ) {
+				fname += 2;
+				len -= 2;
+			}
+		}
+
+		bv.bv_len = pathlen + STRLENOF( "/" ) + len;
+		ptr = bv.bv_val = ch_malloc( bv.bv_len + STRLENOF( "/" ) + 1 );
+		if ( pathlen ) {
+			ptr = lutil_strncopy( ptr, path, pathlen );
+			ptr[ 0 ] = '/';
+			ptr++;
+		}
+		ptr = lutil_strncopy( ptr, fname, len );
+		if ( ptr[ -1 ] != '/' ) {
+			ptr[ 0 ] = '/';
+			ptr++;
+		}
+		ptr[ 0 ] = '\0';
+		
+		attr_normalize_one( ad_olmDbDirectory, &bv, &nbv, NULL );
+
+		next->a_desc = ad_olmDbDirectory;
+		next->a_vals = ch_calloc( sizeof( struct berval ), 2 );
+		next->a_vals[ 0 ] = bv;
+		next->a_numvals = 1;
+
+		if ( BER_BVISNULL( &nbv ) ) {
+			next->a_nvals = next->a_vals;
+
+		} else {
+			next->a_nvals = ch_calloc( sizeof( struct berval ), 2 );
+			next->a_nvals[ 0 ] = nbv;
+		}
+
+		next = next->a_next;
+	}
+
+	cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
+	cb->mc_update = bdb_monitor_update;
+#if 0	/* uncomment if required */
+	cb->mc_modify = bdb_monitor_modify;
+#endif
+	cb->mc_free = bdb_monitor_free;
+	cb->mc_private = (void *)bdb;
+
+	/* make sure the database is registered; then add monitor attributes */
+	rc = mbe->register_database( be, &bdb->bi_monitor.bdm_ndn );
+	if ( rc == 0 ) {
+		rc = mbe->register_entry_attrs( &bdb->bi_monitor.bdm_ndn, a, cb,
+			&dummy, 0, &dummy );
+	}
+
+cleanup:;
+	if ( rc != 0 ) {
+		if ( cb != NULL ) {
+			ch_free( cb );
+			cb = NULL;
+		}
+
+		if ( a != NULL ) {
+			attrs_free( a );
+			a = NULL;
+		}
+	}
+
+	/* store for cleanup */
+	bdb->bi_monitor.bdm_cb = (void *)cb;
+
+	/* we don't need to keep track of the attributes, because
+	 * bdb_monitor_free() takes care of everything */
+	if ( a != NULL ) {
+		attrs_free( a );
+	}
+
+	return rc;
+}
+
+/*
+ * call from within bdb_db_close()
+ */
+int
+bdb_monitor_db_close( BackendDB *be )
+{
+	struct bdb_info		*bdb = (struct bdb_info *) be->be_private;
+
+	if ( SLAP_GLUE_SUBORDINATE( be ) ) {
+		return 0;
+	}
+
+	if ( !BER_BVISNULL( &bdb->bi_monitor.bdm_ndn ) ) {
+		BackendInfo		*mi = backend_info( "monitor" );
+		monitor_extra_t		*mbe;
+
+		if ( mi && &mi->bi_extra ) {
+			mbe = mi->bi_extra;
+			mbe->unregister_entry_callback( &bdb->bi_monitor.bdm_ndn,
+				(monitor_callback_t *)bdb->bi_monitor.bdm_cb,
+				NULL, 0, NULL );
+		}
+
+		memset( &bdb->bi_monitor, 0, sizeof( bdb->bi_monitor ) );
+	}
+
+	return 0;
+}
+
+/*
+ * call from within bdb_db_destroy()
+ */
+int
+bdb_monitor_db_destroy( BackendDB *be )
+{
+	if ( SLAP_GLUE_SUBORDINATE( be ) ) {
+		return 0;
+	}
+
+#ifdef BDB_MONITOR_IDX
+	{
+		struct bdb_info		*bdb = (struct bdb_info *) be->be_private;
+
+		/* TODO: free tree */
+		ldap_pvt_thread_mutex_destroy( &bdb->bi_idx_mutex );
+		avl_free( bdb->bi_idx, ch_free );
+	}
+#endif /* BDB_MONITOR_IDX */
+
+	return 0;
+}
+
+#ifdef BDB_MONITOR_IDX
+
+#define BDB_MONITOR_IDX_TYPES	(4)
+
+typedef struct monitor_idx_t monitor_idx_t;
+
+struct monitor_idx_t {
+	AttributeDescription	*idx_ad;
+	unsigned long		idx_count[BDB_MONITOR_IDX_TYPES];
+};
+
+static int
+bdb_monitor_bitmask2key( slap_mask_t bitmask )
+{
+	int	key;
+
+	for ( key = 0; key < 8*sizeof(slap_mask_t) && !( bitmask & 0x1U ); key++ ) {
+		bitmask >>= 1;
+	}
+
+	return key;
+}
+
+static struct berval idxbv[] = {
+	BER_BVC( "present=" ),
+	BER_BVC( "equality=" ),
+	BER_BVC( "approx=" ),
+	BER_BVC( "substr=" ),
+	BER_BVNULL
+};
+
+static ber_len_t
+bdb_monitor_idx2len( monitor_idx_t *idx )
+{
+	int		i;
+	ber_len_t	len = 0;
+
+	for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) {
+		if ( idx->idx_count[ i ] != 0 ) {
+			len += idxbv[i].bv_len;
+		}
+	}
+
+	return len;
+}
+
+static int
+monitor_idx_cmp( const void *p1, const void *p2 )
+{
+	const monitor_idx_t	*idx1 = (const monitor_idx_t *)p1;
+	const monitor_idx_t	*idx2 = (const monitor_idx_t *)p2;
+
+	return SLAP_PTRCMP( idx1->idx_ad, idx2->idx_ad );
+}
+
+static int
+monitor_idx_dup( void *p1, void *p2 )
+{
+	monitor_idx_t	*idx1 = (monitor_idx_t *)p1;
+	monitor_idx_t	*idx2 = (monitor_idx_t *)p2;
+
+	return SLAP_PTRCMP( idx1->idx_ad, idx2->idx_ad ) == 0 ? -1 : 0;
+}
+
+int
+bdb_monitor_idx_add(
+	struct bdb_info		*bdb,
+	AttributeDescription	*desc,
+	slap_mask_t		type )
+{
+	monitor_idx_t		idx_dummy = { 0 },
+				*idx;
+	int			rc = 0, key;
+
+	idx_dummy.idx_ad = desc;
+	key = bdb_monitor_bitmask2key( type ) - 1;
+	if ( key >= BDB_MONITOR_IDX_TYPES ) {
+		/* invalid index type */
+		return -1;
+	}
+
+	ldap_pvt_thread_mutex_lock( &bdb->bi_idx_mutex );
+
+	idx = (monitor_idx_t *)avl_find( bdb->bi_idx,
+		(caddr_t)&idx_dummy, monitor_idx_cmp );
+	if ( idx == NULL ) {
+		idx = (monitor_idx_t *)ch_calloc( sizeof( monitor_idx_t ), 1 );
+		idx->idx_ad = desc;
+		idx->idx_count[ key ] = 1;
+
+		switch ( avl_insert( &bdb->bi_idx, (caddr_t)idx, 
+			monitor_idx_cmp, monitor_idx_dup ) )
+		{
+		case 0:
+			break;
+
+		default:
+			ch_free( idx );
+			rc = -1;
+		}
+
+	} else {
+		idx->idx_count[ key ]++;
+	}
+
+	ldap_pvt_thread_mutex_unlock( &bdb->bi_idx_mutex );
+
+	return rc;
+}
+
+static int
+bdb_monitor_idx_apply( void *v_idx, void *v_valp )
+{
+	monitor_idx_t	*idx = (monitor_idx_t *)v_idx;
+	BerVarray	*valp = (BerVarray *)v_valp;
+
+	struct berval	bv;
+	char		*ptr;
+	char		count_buf[ BDB_MONITOR_IDX_TYPES ][ SLAP_TEXT_BUFLEN ];
+	ber_len_t	count_len[ BDB_MONITOR_IDX_TYPES ],
+			idx_len;
+	int		i, num = 0;
+
+	idx_len = bdb_monitor_idx2len( idx );
+
+	bv.bv_len = 0;
+	for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) {
+		if ( idx->idx_count[ i ] == 0 ) {
+			continue;
+		}
+
+		count_len[ i ] = snprintf( count_buf[ i ],
+			sizeof( count_buf[ i ] ), "%lu", idx->idx_count[ i ] );
+		bv.bv_len += count_len[ i ];
+		num++;
+	}
+
+	bv.bv_len += idx->idx_ad->ad_cname.bv_len
+		+ num
+		+ idx_len;
+	ptr = bv.bv_val = ch_malloc( bv.bv_len + 1 );
+	ptr = lutil_strcopy( ptr, idx->idx_ad->ad_cname.bv_val );
+	for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) {
+		if ( idx->idx_count[ i ] == 0 ) {
+			continue;
+		}
+
+		ptr[ 0 ] = '#';
+		++ptr;
+		ptr = lutil_strcopy( ptr, idxbv[ i ].bv_val );
+		ptr = lutil_strcopy( ptr, count_buf[ i ] );
+	}
+
+	ber_bvarray_add( valp, &bv );
+
+	return 0;
+}
+
+static int
+bdb_monitor_idx_entry_add(
+	struct bdb_info	*bdb,
+	Entry		*e )
+{
+	BerVarray	vals = NULL;
+	Attribute	*a;
+
+	a = attr_find( e->e_attrs, ad_olmBDBNotIndexed );
+
+	ldap_pvt_thread_mutex_lock( &bdb->bi_idx_mutex );
+
+	avl_apply( bdb->bi_idx, bdb_monitor_idx_apply,
+		&vals, -1, AVL_INORDER );
+
+	ldap_pvt_thread_mutex_unlock( &bdb->bi_idx_mutex );
+
+	if ( vals != NULL ) {
+		if ( a != NULL ) {
+			assert( a->a_nvals == a->a_vals );
+
+			ber_bvarray_free( a->a_vals );
+
+		} else {
+			Attribute	**ap;
+
+			for ( ap = &e->e_attrs; *ap != NULL; ap = &(*ap)->a_next )
+				;
+			*ap = attr_alloc( ad_olmBDBNotIndexed );
+			a = *ap;
+		}
+		a->a_vals = vals;
+		a->a_nvals = a->a_vals;
+	}
+
+	return 0;
+}
+
+#endif /* BDB_MONITOR_IDX */

Modified: openldap/trunk/servers/slapd/back-bdb/nextid.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/nextid.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/nextid.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* init.c - initialize bdb backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/nextid.c,v 1.23.2.4 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/nextid.c,v 1.26.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-bdb/operational.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/operational.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/operational.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* operational.c - bdb backend operational attributes function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/operational.c,v 1.24.2.5 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/operational.c,v 1.29.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-bdb/proto-bdb.h
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/proto-bdb.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/proto-bdb.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/proto-bdb.h,v 1.111.2.11 2007/01/25 12:42:38 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/proto-bdb.h,v 1.137.2.7 2007/12/06 15:13:57 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -74,7 +74,7 @@
 int
 bdb_db_cache(
     Backend	*be,
-    const char *name,
+    struct berval *name,
 	DB **db );
 
 /*
@@ -84,7 +84,7 @@
 
 int bdb_dn2entry LDAP_P(( Operation *op, DB_TXN *tid,
 	struct berval *dn, EntryInfo **e, int matched,
-	u_int32_t locker, DB_LOCK *lock ));
+	BDB_LOCKER locker, DB_LOCK *lock ));
 
 /*
  * dn2id.c
@@ -97,9 +97,10 @@
 
 int bdb_dn2id(
 	Operation *op,
-	DB_TXN *tid,
 	struct berval *dn,
-	EntryInfo *ei );
+	EntryInfo *ei,
+	BDB_LOCKER locker,
+	DB_LOCK *lock );
 
 int bdb_dn2id_add(
 	Operation *op,
@@ -120,21 +121,28 @@
 
 int bdb_dn2idl(
 	Operation *op,
-	Entry *e,
+	BDB_LOCKER locker,
+	struct berval *ndn,
+	EntryInfo *ei,
 	ID *ids,
 	ID *stack );
 
 #ifdef BDB_HIER
 #define bdb_dn2id_parent			BDB_SYMBOL(dn2id_parent)
+#define bdb_dup_compare				BDB_SYMBOL(dup_compare)
 #define bdb_fix_dn					BDB_SYMBOL(fix_dn)
 
 int bdb_dn2id_parent(
 	Operation *op,
-	DB_TXN *txn,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	EntryInfo *ei,
 	ID *idp );
 
+int bdb_dup_compare(
+	DB *db,
+	const DBT *usrkey,
+	const DBT *curkey );
+
 int bdb_fix_dn( Entry *e, int checkit );
 #endif
 
@@ -166,6 +174,7 @@
 
 int bdb_filter_candidates(
 	Operation *op,
+	BDB_LOCKER locker,
 	Filter	*f,
 	ID *ids,
 	ID *tmp,
@@ -199,7 +208,7 @@
 int bdb_id2entry(
 	BackendDB *be,
 	DB_TXN *tid,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	ID id,
 	Entry **e);
 #endif
@@ -282,7 +291,7 @@
 int bdb_idl_fetch_key(
 	BackendDB	*be,
 	DB			*db,
-	DB_TXN		*tid,
+	BDB_LOCKER locker,
 	DBT			*key,
 	ID			*ids,
 	DBC                     **saved_cursor,
@@ -325,17 +334,18 @@
 /*
  * index.c
  */
-#define bdb_index_is_indexed		BDB_SYMBOL(index_is_indexed)
+#define bdb_index_mask				BDB_SYMBOL(index_mask)
 #define bdb_index_param				BDB_SYMBOL(index_param)
 #define bdb_index_values			BDB_SYMBOL(index_values)
 #define bdb_index_entry				BDB_SYMBOL(index_entry)
 #define bdb_index_recset			BDB_SYMBOL(index_recset)
 #define bdb_index_recrun			BDB_SYMBOL(index_recrun)
 
-extern int
-bdb_index_is_indexed LDAP_P((
+extern AttrInfo *
+bdb_index_mask LDAP_P((
 	Backend *be,
-	AttributeDescription *desc ));
+	AttributeDescription *desc,
+	struct berval *name ));
 
 extern int
 bdb_index_param LDAP_P((
@@ -388,7 +398,7 @@
 bdb_key_read(
     Backend	*be,
 	DB *db,
-	DB_TXN *txn,
+	BDB_LOCKER locker,
     struct berval *k,
 	ID *ids,
     DBC **saved_cursor,
@@ -426,35 +436,53 @@
 	char *textbuf,
 	size_t textlen );
 
+/*
+ * monitor.c
+ */
 
+#define bdb_monitor_db_init	BDB_SYMBOL(monitor_db_init)
+#define bdb_monitor_db_open	BDB_SYMBOL(monitor_db_open)
+#define bdb_monitor_db_close	BDB_SYMBOL(monitor_db_close)
+#define bdb_monitor_db_destroy	BDB_SYMBOL(monitor_db_destroy)
+
+int bdb_monitor_db_init( BackendDB *be );
+int bdb_monitor_db_open( BackendDB *be );
+int bdb_monitor_db_close( BackendDB *be );
+int bdb_monitor_db_destroy( BackendDB *be );
+
+#ifdef BDB_MONITOR_IDX
+#define bdb_monitor_idx_add	BDB_SYMBOL(monitor_idx_add)
+int
+bdb_monitor_idx_add(
+	struct bdb_info		*bdb,
+	AttributeDescription	*desc,
+	slap_mask_t		type );
+#endif /* BDB_MONITOR_IDX */
+
 /*
  * cache.c
  */
 #define bdb_cache_entry_db_unlock	BDB_SYMBOL(cache_entry_db_unlock)
+#define bdb_cache_return_entry_rw	BDB_SYMBOL(cache_return_entry_rw)
 
 #define	bdb_cache_entryinfo_lock(e) \
 	ldap_pvt_thread_mutex_lock( &(e)->bei_kids_mutex )
 #define	bdb_cache_entryinfo_unlock(e) \
 	ldap_pvt_thread_mutex_unlock( &(e)->bei_kids_mutex )
+#define	bdb_cache_entryinfo_trylock(e) \
+	ldap_pvt_thread_mutex_trylock( &(e)->bei_kids_mutex )
 
 /* What a mess. Hopefully the current cache scheme will stabilize
  * and we can trim out all of this stuff.
  */
-#if 0
-void bdb_cache_return_entry_rw( DB_ENV *env, Cache *cache, Entry *e,
+void bdb_cache_return_entry_rw( struct bdb_info *bdb, Entry *e,
 	int rw, DB_LOCK *lock );
-#else
-#define bdb_cache_return_entry_rw( env, cache, e, rw, lock ) \
-	bdb_cache_entry_db_unlock( env, lock )
-#define	bdb_cache_return_entry( env, lock ) \
-	bdb_cache_entry_db_unlock( env, lock )
-#endif
-#define bdb_cache_return_entry_r(env, c, e, l) \
-	bdb_cache_return_entry_rw((env), (c), (e), 0, (l))
-#define bdb_cache_return_entry_w(env, c, e, l) \
-	bdb_cache_return_entry_rw((env), (c), (e), 1, (l))
+#define bdb_cache_return_entry_r(bdb, e, l) \
+	bdb_cache_return_entry_rw((bdb), (e), 0, (l))
+#define bdb_cache_return_entry_w(bdb, e, l) \
+	bdb_cache_return_entry_rw((bdb), (e), 1, (l))
 #if 0
-void bdb_unlocked_cache_return_entry_rw( Cache *cache, Entry *e, int rw );
+void bdb_unlocked_cache_return_entry_rw( struct bdb_info *bdb, Entry *e, int rw );
 #else
 #define	bdb_unlocked_cache_return_entry_rw( a, b, c )	((void)0)
 #endif
@@ -486,7 +514,8 @@
 	EntryInfo *pei,
 	Entry   *e,
 	struct berval *nrdn,
-	u_int32_t locker
+	BDB_LOCKER locker,
+	DB_LOCK *lock
 );
 int bdb_cache_modrdn(
 	struct bdb_info *bdb,
@@ -494,19 +523,19 @@
 	struct berval *nrdn,
 	Entry	*new,
 	EntryInfo *ein,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	DB_LOCK *lock
 );
 int bdb_cache_modify(
+	struct bdb_info *bdb,
 	Entry *e,
 	Attribute *newAttrs,
-	DB_ENV *env,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	DB_LOCK *lock
 );
 int bdb_cache_find_ndn(
 	Operation *op,
-	DB_TXN	*txn,
+	BDB_LOCKER	locker,
 	struct berval   *ndn,
 	EntryInfo	**res
 );
@@ -514,28 +543,29 @@
 	struct bdb_info *bdb,
 	ID id
 );
+
+#define	ID_LOCKED	1
+#define	ID_NOCACHE	2
 int bdb_cache_find_id(
 	Operation *op,
 	DB_TXN	*tid,
 	ID		id,
 	EntryInfo **eip,
-	int	islocked,
-	u_int32_t	locker,
+	int	flag,
+	BDB_LOCKER	locker,
 	DB_LOCK		*lock
 );
 int
 bdb_cache_find_parent(
 	Operation *op,
-	DB_TXN *txn,
-	u_int32_t	locker,
+	BDB_LOCKER	locker,
 	ID id,
 	EntryInfo **res
 );
 int bdb_cache_delete(
-	Cache	*cache,
+	struct bdb_info *bdb,
 	Entry	*e,
-	DB_ENV	*env,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	DB_LOCK	*lock
 );
 void bdb_cache_delete_cleanup(
@@ -543,12 +573,6 @@
 	EntryInfo *ei
 );
 void bdb_cache_release_all( Cache *cache );
-void bdb_cache_delete_entry(
-	struct bdb_info *bdb,
-	EntryInfo *ei,
-	u_int32_t locker,
-	DB_LOCK *lock
-);
 
 #ifdef BDB_HIER
 int hdb_cache_load(
@@ -560,22 +584,22 @@
 
 #define bdb_cache_entry_db_relock		BDB_SYMBOL(cache_entry_db_relock)
 int bdb_cache_entry_db_relock(
-	DB_ENV *env,
-	u_int32_t locker,
+	struct bdb_info *bdb,
+	BDB_LOCKER locker,
 	EntryInfo *ei,
 	int rw,
 	int tryOnly,
 	DB_LOCK *lock );
 
 int bdb_cache_entry_db_unlock(
-	DB_ENV *env,
+	struct bdb_info *bdb,
 	DB_LOCK *lock );
 
 #ifdef BDB_REUSE_LOCKERS
 
 #define bdb_locker_id				BDB_SYMBOL(locker_id)
 #define bdb_locker_flush			BDB_SYMBOL(locker_flush)
-int bdb_locker_id( Operation *op, DB_ENV *env, u_int32_t *locker );
+int bdb_locker_id( Operation *op, DB_ENV *env, BDB_LOCKER *locker );
 void bdb_locker_flush( DB_ENV *env );
 
 #define	LOCK_ID_FREE(env, locker)	((void)0)
@@ -620,7 +644,6 @@
 #define bdb_tool_entry_put		BDB_SYMBOL(tool_entry_put)
 #define bdb_tool_entry_reindex		BDB_SYMBOL(tool_entry_reindex)
 #define bdb_tool_dn2id_get		BDB_SYMBOL(tool_dn2id_get)
-#define bdb_tool_id2entry_get		BDB_SYMBOL(tool_id2entry_get)
 #define bdb_tool_entry_modify		BDB_SYMBOL(tool_entry_modify)
 #define bdb_tool_idl_add		BDB_SYMBOL(tool_idl_add)
 
@@ -651,7 +674,6 @@
 extern BI_tool_entry_put		bdb_tool_entry_put;
 extern BI_tool_entry_reindex		bdb_tool_entry_reindex;
 extern BI_tool_dn2id_get		bdb_tool_dn2id_get;
-extern BI_tool_id2entry_get		bdb_tool_id2entry_get;
 extern BI_tool_entry_modify		bdb_tool_entry_modify;
 
 int bdb_tool_idl_add( BackendDB *be, DB *db, DB_TXN *txn, DBT *key, ID id );

Modified: openldap/trunk/servers/slapd/back-bdb/referral.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/referral.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/referral.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* referral.c - BDB backend referral handler */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/referral.c,v 1.36.2.6 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/referral.c,v 1.42.2.3 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -28,7 +28,7 @@
 	EntryInfo *ei;
 	int rc = LDAP_SUCCESS;
 
-	u_int32_t	locker;
+	BDB_LOCKER	locker;
 	DB_LOCK		lock;
 
 	if( op->o_tag == LDAP_REQ_SEARCH ) {
@@ -87,8 +87,8 @@
 		if ( e != NULL ) {
 			Debug( LDAP_DEBUG_TRACE,
 				LDAP_XSTRING(bdb_referrals)
-				": op=%ld target=\"%s\" matched=\"%s\"\n",
-				(long) op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
+				": tag=%lu target=\"%s\" matched=\"%s\"\n",
+				(unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
 
 			if( is_entry_referral( e ) ) {
 				BerVarray ref = get_entry_referrals( op, e );
@@ -102,7 +102,7 @@
 				}
 			}
 
-			bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+			bdb_cache_return_entry_r (bdb, e, &lock);
 			e = NULL;
 		} else if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) && default_referral != NULL ) {
 			rc = LDAP_OTHER;
@@ -138,8 +138,8 @@
 
 		Debug( LDAP_DEBUG_TRACE,
 			LDAP_XSTRING(bdb_referrals)
-			": op=%ld target=\"%s\" matched=\"%s\"\n",
-			(long) op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
+			": tag=%lu target=\"%s\" matched=\"%s\"\n",
+			(unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
 
 		rs->sr_matched = e->e_name.bv_val;
 		if( rs->sr_ref != NULL ) {
@@ -156,7 +156,7 @@
 		ber_bvarray_free( refs );
 	}
 
-	bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+	bdb_cache_return_entry_r(bdb, e, &lock);
 	LOCK_ID_FREE ( bdb->bi_dbenv, locker );
 	return rc;
 }

Modified: openldap/trunk/servers/slapd/back-bdb/search.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* search.c - search operation */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/search.c,v 1.221.2.16 2007/07/20 22:42:26 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/search.c,v 1.246.2.9 2007/11/20 18:46:34 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -31,7 +31,7 @@
 	Operation *op,
 	SlapReply *rs,
 	Entry *e,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	ID	*ids,
 	ID	*scopes );
 
@@ -51,7 +51,7 @@
 	SlapReply *rs,
 	Entry *e,
 	Entry **matched,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	DB_LOCK *lock,
 	ID	*tmp,
 	ID	*visited )
@@ -119,8 +119,7 @@
 		/* Free the previous entry, continue to work with the
 		 * one we just retrieved.
 		 */
-		bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache,
-			*matched, lock);
+		bdb_cache_return_entry_r( bdb, *matched, lock);
 		*lock = lockr;
 
 		/* We found a regular entry. Return this to the caller. The
@@ -144,7 +143,7 @@
 	Operation *op,
 	SlapReply *rs,
 	Entry *e,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	ID *ids,
 	ID *scopes,
 	ID *stack )
@@ -155,11 +154,7 @@
 	Entry *matched, *a;
 	EntryInfo *ei;
 	struct berval bv_alias = BER_BVC( "alias" );
-#ifdef LDAP_COMP_MATCH
-	AttributeAssertion aa_alias = { NULL, BER_BVNULL, NULL };
-#else
-	AttributeAssertion aa_alias = { NULL, BER_BVNULL };
-#endif
+	AttributeAssertion aa_alias = ATTRIBUTEASSERTION_INIT;
 	Filter	af;
 	DB_LOCK locka, lockr;
 	int first = 1;
@@ -185,7 +180,7 @@
 
 	/* Find all aliases in database */
 	BDB_IDL_ZERO( aliases );
-	rs->sr_err = bdb_filter_candidates( op, &af, aliases,
+	rs->sr_err = bdb_filter_candidates( op, locker, &af, aliases,
 		curscop, visited );
 	if (rs->sr_err != LDAP_SUCCESS) {
 		return rs->sr_err;
@@ -207,12 +202,12 @@
 		 * to the cumulative list of candidates.
 		 */
 		BDB_IDL_CPY( curscop, aliases );
-		rs->sr_err = bdb_dn2idl( op, e, subscop,
+		rs->sr_err = bdb_dn2idl( op, locker, &e->e_nname, BEI(e), subscop,
 			subscop2+BDB_IDL_DB_SIZE );
 		if (first) {
 			first = 0;
 		} else {
-			bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, e, &locka);
+			bdb_cache_return_entry_r (bdb, e, &locka);
 		}
 		BDB_IDL_CPY(subscop2, subscop);
 		rs->sr_err = bdb_idl_intersection(curscop, subscop);
@@ -238,8 +233,7 @@
 			 * turned into a range that spans IDs indiscriminately
 			 */
 			if (!is_entry_alias(a)) {
-				bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache,
-					a, &lockr);
+				bdb_cache_return_entry_r (bdb, a, &lockr);
 				continue;
 			}
 
@@ -257,15 +251,13 @@
 					bdb_idl_insert(newsubs, a->e_id);
 					bdb_idl_insert(scopes, a->e_id);
 				}
-				bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache,
-					a, &lockr);
+				bdb_cache_return_entry_r( bdb, a, &lockr);
 
 			} else if (matched) {
 				/* Alias could not be dereferenced, or it deref'd to
 				 * an ID we've already seen. Ignore it.
 				 */
-				bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache,
-					matched, &lockr );
+				bdb_cache_return_entry_r( bdb, matched, &lockr );
 				rs->sr_text = NULL;
 			}
 		}
@@ -311,23 +303,22 @@
 bdb_search( Operation *op, SlapReply *rs )
 {
 	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-	time_t		stoptime;
 	ID		id, cursor;
+	ID		lastid = NOID;
 	ID		candidates[BDB_IDL_UM_SIZE];
 	ID		scopes[BDB_IDL_DB_SIZE];
-	Entry		*e = NULL, base, e_root = {0};
+	Entry		*e = NULL, base, *e_root;
 	Entry		*matched = NULL;
-	EntryInfo	*ei, ei_root = {0};
+	EntryInfo	*ei;
+	AttributeName	*attrs;
 	struct berval	realbase = BER_BVNULL;
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 	slap_mask_t	mask;
-#endif
+	time_t		stoptime;
 	int		manageDSAit;
-	int		tentries = 0;
-	ID		lastid = NOID;
-	AttributeName	*attrs;
+	int		tentries = 0, nentries = 0;
+	int		idflag = 0;
 
-	u_int32_t	locker = 0;
+	BDB_LOCKER	locker = 0;
 	DB_LOCK		lock;
 	struct	bdb_op_info	*opinfo = NULL;
 	DB_TXN			*ltid = NULL;
@@ -354,16 +345,10 @@
 		}
 	}
 
+	e_root = bdb->bi_cache.c_dntree.bei_e;
 	if ( op->o_req_ndn.bv_len == 0 ) {
 		/* DIT root special case */
-		ei_root.bei_e = &e_root;
-		ei_root.bei_parent = &ei_root;
-		e_root.e_private = &ei_root;
-		e_root.e_id = 0;
-		e_root.e_ocflags = SLAP_OC_GLUE | SLAP_OC__END;
-		BER_BVSTR( &e_root.e_nname, "" );
-		BER_BVSTR( &e_root.e_name, "" );
-		ei = &ei_root;
+		ei = e_root->e_private;
 		rs->sr_err = LDAP_SUCCESS;
 	} else {
 		if ( op->ors_deref & LDAP_DEREF_FINDING ) {
@@ -408,8 +393,7 @@
 			if ( e ) {
 				build_new_dn( &op->o_req_ndn, &e->e_nname, &stub,
 					op->o_tmpmemctx );
-				bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache,
-					e, &lock);
+				bdb_cache_return_entry_r (bdb, e, &lock);
 				matched = NULL;
 				goto dn2entry_retry;
 			}
@@ -425,7 +409,6 @@
 		if ( matched != NULL ) {
 			BerVarray erefs = NULL;
 
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 			/* return referral only if "disclose"
 			 * is granted on the object */
 			if ( ! access_allowed( op, matched,
@@ -434,9 +417,7 @@
 			{
 				rs->sr_err = LDAP_NO_SUCH_OBJECT;
 
-			} else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-			{
+			} else {
 				ber_dupbv( &matched_dn, &matched->e_name );
 
 				erefs = is_entry_referral( matched )
@@ -450,8 +431,7 @@
 #ifdef SLAP_ZONE_ALLOC
 			slap_zn_runlock(bdb->bi_cache.c_zctx, matched);
 #endif
-			bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache,
-				matched, &lock);
+			bdb_cache_return_entry_r (bdb, matched, &lock);
 			matched = NULL;
 
 			if ( erefs ) {
@@ -484,7 +464,6 @@
 		return rs->sr_err;
 	}
 
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 	/* NOTE: __NEW__ "search" access is required
 	 * on searchBase object */
 	if ( ! access_allowed_mask( op, e, slap_schema.si_ad_entry,
@@ -499,15 +478,14 @@
 #ifdef SLAP_ZONE_ALLOC
 		slap_zn_runlock(bdb->bi_cache.c_zctx, e);
 #endif
-		if ( e != &e_root ) {
-			bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+		if ( e != e_root ) {
+			bdb_cache_return_entry_r(bdb, e, &lock);
 		}
 		send_ldap_result( op, rs );
 		return rs->sr_err;
 	}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 
-	if ( !manageDSAit && e != &e_root && is_entry_referral( e ) ) {
+	if ( !manageDSAit && e != e_root && is_entry_referral( e ) ) {
 		/* entry is a referral, don't allow add */
 		struct berval matched_dn = BER_BVNULL;
 		BerVarray erefs = NULL;
@@ -520,7 +498,7 @@
 #ifdef SLAP_ZONE_ALLOC
 		slap_zn_runlock(bdb->bi_cache.c_zctx, e);
 #endif
-		bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
+		bdb_cache_return_entry_r( bdb, e, &lock );
 		e = NULL;
 
 		if ( erefs ) {
@@ -557,8 +535,8 @@
 #ifdef SLAP_ZONE_ALLOC
 		slap_zn_runlock(bdb->bi_cache.c_zctx, e);
 #endif
-		if ( e != &e_root ) {
-			bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+		if ( e != e_root ) {
+			bdb_cache_return_entry_r(bdb, e, &lock);
 		}
 		send_ldap_result( op, rs );
 		return 1;
@@ -580,8 +558,8 @@
 #ifdef SLAP_ZONE_ALLOC
 	slap_zn_runlock(bdb->bi_cache.c_zctx, e);
 #endif
-	if ( e != &e_root ) {
-		bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+	if ( e != e_root ) {
+		bdb_cache_return_entry_r(bdb, e, &lock);
 	}
 	e = NULL;
 
@@ -634,26 +612,15 @@
 			goto done;
 		}
 
-		if ( (ID)( ps->ps_cookie ) == 0 ) {
-			id = bdb_idl_first( candidates, &cursor );
-
-		} else {
-			if ( ps->ps_size == 0 ) {
-				rs->sr_err = LDAP_SUCCESS;
-				rs->sr_text = "search abandoned by pagedResult size=0";
-				send_ldap_result( op, rs );
-				goto done;
-			}
-			for ( id = bdb_idl_first( candidates, &cursor );
-				id != NOID &&
-					id <= (ID)( ps->ps_cookie );
-				id = bdb_idl_next( candidates, &cursor ) )
-			{
-				/* empty */;
-			}
+		cursor = (ID) ps->ps_cookie;
+		if ( cursor && ps->ps_size == 0 ) {
+			rs->sr_err = LDAP_SUCCESS;
+			rs->sr_text = "search abandoned by pagedResult size=0";
+			send_ldap_result( op, rs );
+			goto done;
 		}
-
-		if ( cursor == NOID ) {
+		id = bdb_idl_first( candidates, &cursor );
+		if ( id == NOID ) {
 			Debug( LDAP_DEBUG_TRACE, 
 				LDAP_XSTRING(bdb_search)
 				": no paged results candidates\n",
@@ -663,6 +630,9 @@
 			rs->sr_err = LDAP_OTHER;
 			goto done;
 		}
+		nentries = ps->ps_count;
+		if ( id == (ID)ps->ps_cookie )
+			id = bdb_idl_next( candidates, &cursor );
 		goto loop_begin;
 	}
 
@@ -679,6 +649,15 @@
 			goto done;
 		}
 
+		/* mostly needed by internal searches,
+		 * e.g. related to syncrepl, for whom
+		 * abandon does not get set... */
+		if ( slapd_shutdown ) {
+			rs->sr_err = LDAP_UNAVAILABLE;
+			send_ldap_disconnect( op, rs );
+			goto done;
+		}
+
 		/* check time limit */
 		if ( op->ors_tlimit != SLAP_NO_LIMIT
 				&& slap_get_time() > stoptime )
@@ -690,11 +669,19 @@
 			goto done;
 		}
 
+		/* If we inspect more entries than will
+		 * fit into the entry cache, stop caching
+		 * any subsequent entries
+		 */
+		nentries++;
+		if ( nentries > bdb->bi_cache.c_maxsize && !idflag )
+			idflag = ID_NOCACHE;
+
 fetch_entry_retry:
 			/* get the entry with reader lock */
 			ei = NULL;
 			rs->sr_err = bdb_cache_find_id( op, ltid,
-				id, &ei, 0, locker, &lock );
+				id, &ei, idflag, locker, &lock );
 
 			if (rs->sr_err == LDAP_BUSY) {
 				rs->sr_text = "ldap server busy";
@@ -705,6 +692,10 @@
 				|| rs->sr_err == DB_LOCK_NOTGRANTED )
 			{
 				goto fetch_entry_retry;
+			} else if ( rs->sr_err == LDAP_OTHER ) {
+				rs->sr_text = "internal error";
+				send_ldap_result( op, rs );
+				goto done;
 			}
 
 			if ( ei && rs->sr_err == LDAP_SUCCESS ) {
@@ -860,8 +851,7 @@
 #ifdef SLAP_ZONE_ALLOC
 					slap_zn_runlock(bdb->bi_cache.c_zctx, e);
 #endif
-					bdb_cache_return_entry_r( bdb->bi_dbenv,
-							&bdb->bi_cache, e, &lock );
+					bdb_cache_return_entry_r( bdb, e, &lock );
 					e = NULL;
 					send_paged_response( op, rs, &lastid, tentries );
 					goto done;
@@ -888,8 +878,7 @@
 #ifdef SLAP_ZONE_ALLOC
 					slap_zn_runlock(bdb->bi_cache.c_zctx, e);
 #endif
-					bdb_cache_return_entry_r(bdb->bi_dbenv,
-						&bdb->bi_cache, e, &lock);
+					bdb_cache_return_entry_r(bdb, e, &lock);
 					e = NULL;
 					rs->sr_entry = NULL;
 					if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) {
@@ -917,8 +906,7 @@
 #ifdef SLAP_ZONE_ALLOC
 			slap_zn_runlock(bdb->bi_cache.c_zctx, e);
 #endif
-			bdb_cache_return_entry_r( bdb->bi_dbenv,
-				&bdb->bi_cache, e , &lock );
+			bdb_cache_return_entry_r( bdb, e , &lock );
 			e = NULL;
 			rs->sr_entry = NULL;
 		}
@@ -1033,7 +1021,7 @@
 	Operation *op,
 	SlapReply *rs,
 	Entry *e,
-	u_int32_t locker,
+	BDB_LOCKER locker,
 	ID	*ids,
 	ID	*scopes )
 {
@@ -1041,17 +1029,9 @@
 	int rc, depth = 1;
 	Filter		f, rf, xf, nf;
 	ID		*stack;
-#ifdef LDAP_COMP_MATCH
-	AttributeAssertion aa_ref = { NULL, BER_BVNULL, NULL };
-#else
-	AttributeAssertion aa_ref = { NULL, BER_BVNULL };
-#endif
+	AttributeAssertion aa_ref = ATTRIBUTEASSERTION_INIT;
 	Filter	sf;
-#ifdef LDAP_COMP_MATCH
-	AttributeAssertion aa_subentry = { NULL, BER_BVNULL, NULL };
-#else
-	AttributeAssertion aa_subentry = { NULL, BER_BVNULL };
-#endif
+	AttributeAssertion aa_subentry = ATTRIBUTEASSERTION_INIT;
 
 	/*
 	 * This routine takes as input a filter (user-filter)
@@ -1117,11 +1097,11 @@
 	if( op->ors_deref & LDAP_DEREF_SEARCHING ) {
 		rc = search_aliases( op, rs, e, locker, ids, scopes, stack );
 	} else {
-		rc = bdb_dn2idl( op, e, ids, stack );
+		rc = bdb_dn2idl( op, locker, &e->e_nname, BEI(e), ids, stack );
 	}
 
 	if ( rc == LDAP_SUCCESS ) {
-		rc = bdb_filter_candidates( op, &f, ids,
+		rc = bdb_filter_candidates( op, locker, &f, ids,
 			stack, stack+BDB_IDL_UM_SIZE );
 	}
 
@@ -1148,12 +1128,7 @@
 static int
 parse_paged_cookie( Operation *op, SlapReply *rs )
 {
-	LDAPControl	**c;
 	int		rc = LDAP_SUCCESS;
-	ber_tag_t	tag;
-	ber_int_t	size;
-	BerElement	*ber;
-	struct berval	cookie = BER_BVNULL;
 	PagedResultsState *ps = op->o_pagedresults_state;
 
 	/* this function must be invoked only if the pagedResults
@@ -1161,53 +1136,17 @@
 	 * by the frontend */
 	assert( get_pagedresults( op ) > SLAP_CONTROL_IGNORED );
 
-	/* look for the appropriate ctrl structure */
-	for ( c = op->o_ctrls; c[0] != NULL; c++ ) {
-		if ( strcmp( c[0]->ldctl_oid, LDAP_CONTROL_PAGEDRESULTS ) == 0 )
-		{
-			break;
-		}
-	}
-
-	if ( c[0] == NULL ) {
-		rs->sr_text = "missing pagedResults control";
-		return LDAP_PROTOCOL_ERROR;
-	}
-
-	/* Tested by frontend */
-	assert( c[0]->ldctl_value.bv_len > 0 );
-
-	/* Parse the control value
-	 *	realSearchControlValue ::= SEQUENCE {
-	 *		size	INTEGER (0..maxInt),
-	 *				-- requested page size from client
-	 *				-- result set size estimate from server
-	 *		cookie	OCTET STRING
-	 * }
-	 */
-	ber = ber_init( &c[0]->ldctl_value );
-	if ( ber == NULL ) {
-		rs->sr_text = "internal error";
-		return LDAP_OTHER;
-	}
-
-	tag = ber_scanf( ber, "{im}", &size, &cookie );
-
-	/* Tested by frontend */
-	assert( tag != LBER_ERROR );
-	assert( size >= 0 );
-
 	/* cookie decoding/checks deferred to backend... */
-	if ( cookie.bv_len ) {
+	if ( ps->ps_cookieval.bv_len ) {
 		PagedResultsCookie reqcookie;
-		if( cookie.bv_len != sizeof( reqcookie ) ) {
+		if( ps->ps_cookieval.bv_len != sizeof( reqcookie ) ) {
 			/* bad cookie */
 			rs->sr_text = "paged results cookie is invalid";
 			rc = LDAP_PROTOCOL_ERROR;
 			goto done;
 		}
 
-		AC_MEMCPY( &reqcookie, cookie.bv_val, sizeof( reqcookie ));
+		AC_MEMCPY( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie ));
 
 		if ( reqcookie > ps->ps_cookie ) {
 			/* bad cookie */
@@ -1223,22 +1162,11 @@
 
 	} else {
 		/* Initial request.  Initialize state. */
-#if 0
-		if ( op->o_conn->c_pagedresults_state.ps_cookie != 0 ) {
-			/* There's another pagedResults control on the
-			 * same connection; reject new pagedResults controls 
-			 * (allowed by RFC2696) */
-			rs->sr_text = "paged results cookie unavailable; try later";
-			rc = LDAP_UNWILLING_TO_PERFORM;
-			goto done;
-		}
-#endif
 		ps->ps_cookie = 0;
 		ps->ps_count = 0;
 	}
 
 done:;
-	(void)ber_free( ber, 1 );
 
 	return rc;
 }

Modified: openldap/trunk/servers/slapd/back-bdb/tools.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/tools.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/tools.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* tools.c - tools for slap tools */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/tools.c,v 1.72.2.17 2007/08/11 00:32:20 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/tools.c,v 1.105.2.8 2007/12/13 07:05:24 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -18,6 +18,7 @@
 
 #include <stdio.h>
 #include <ac/string.h>
+#include <ac/errno.h>
 
 #define AVL_INTERNAL
 #include "back-bdb.h"
@@ -25,6 +26,9 @@
 
 static DBC *cursor = NULL;
 static DBT key, data;
+static EntryHeader eh;
+static ID nid, previd = NOID;
+static char ehbuf[16];
 
 typedef struct dn_id {
 	ID id;
@@ -68,9 +72,14 @@
 static void *bdb_tool_index_rec;
 static struct bdb_info *bdb_tool_info;
 static ldap_pvt_thread_mutex_t bdb_tool_index_mutex;
-static ldap_pvt_thread_cond_t bdb_tool_index_cond;
+static ldap_pvt_thread_cond_t bdb_tool_index_cond_main;
+static ldap_pvt_thread_cond_t bdb_tool_index_cond_work;
 
+static ldap_pvt_thread_mutex_t bdb_tool_trickle_mutex;
+static ldap_pvt_thread_cond_t bdb_tool_trickle_cond;
+
 static void * bdb_tool_index_task( void *ctx, void *ptr );
+static void * bdb_tool_trickle_task( void *ctx, void *ptr );
 
 int bdb_tool_entry_open(
 	BackendDB *be, int mode )
@@ -80,8 +89,10 @@
 	/* initialize key and data thangs */
 	DBTzero( &key );
 	DBTzero( &data );
-	key.flags = DB_DBT_REALLOC;
-	data.flags = DB_DBT_REALLOC;
+	key.flags = DB_DBT_USERMEM;
+	key.data = &nid;
+	key.size = key.ulen = sizeof( nid );
+	data.flags = DB_DBT_USERMEM;
 
 	if (cursor == NULL) {
 		int rc = bdb->bi_id2entry->bdi_db->cursor(
@@ -93,23 +104,29 @@
 	}
 
 	/* Set up for threaded slapindex */
-	if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK
-		&& bdb->bi_nattrs ) {
+	if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK ) {
 		if ( !bdb_tool_info ) {
-			int i;
+			ldap_pvt_thread_mutex_init( &bdb_tool_trickle_mutex );
+			ldap_pvt_thread_cond_init( &bdb_tool_trickle_cond );
+			ldap_pvt_thread_pool_submit( &connection_pool, bdb_tool_trickle_task, bdb->bi_dbenv );
+
 			ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex );
-			ldap_pvt_thread_cond_init( &bdb_tool_index_cond );
-			bdb_tool_index_threads = ch_malloc( slap_tool_thread_max * sizeof( int ));
-			bdb_tool_index_rec = ch_malloc( bdb->bi_nattrs * sizeof( IndexRec ));
-			bdb_tool_index_tcount = slap_tool_thread_max - 1;
-			for (i=1; i<slap_tool_thread_max; i++) {
-				int *ptr = ch_malloc( sizeof( int ));
-				*ptr = i;
-				ldap_pvt_thread_pool_submit( &connection_pool,
-					bdb_tool_index_task, ptr );
+			ldap_pvt_thread_cond_init( &bdb_tool_index_cond_main );
+			ldap_pvt_thread_cond_init( &bdb_tool_index_cond_work );
+			if ( bdb->bi_nattrs ) {
+				int i;
+				bdb_tool_index_threads = ch_malloc( slap_tool_thread_max * sizeof( int ));
+				bdb_tool_index_rec = ch_malloc( bdb->bi_nattrs * sizeof( IndexRec ));
+				bdb_tool_index_tcount = slap_tool_thread_max - 1;
+				for (i=1; i<slap_tool_thread_max; i++) {
+					int *ptr = ch_malloc( sizeof( int ));
+					*ptr = i;
+					ldap_pvt_thread_pool_submit( &connection_pool,
+						bdb_tool_index_task, ptr );
+				}
 			}
+			bdb_tool_info = bdb;
 		}
-		bdb_tool_info = bdb;
 	}
 
 	return 0;
@@ -120,20 +137,19 @@
 {
 	if ( bdb_tool_info ) {
 		slapd_shutdown = 1;
+		ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex );
+		ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond );
+		ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex );
 		ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
 		bdb_tool_index_tcount = slap_tool_thread_max - 1;
-		ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond );
+		ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work );
 		ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
 	}
 
-	if( key.data ) {
-		ch_free( key.data );
-		key.data = NULL;
+	if( eh.bv.bv_val ) {
+		ch_free( eh.bv.bv_val );
+		eh.bv.bv_val = NULL;
 	}
-	if( data.data ) {
-		ch_free( data.data );
-		data.data = NULL;
-	}
 
 	if( cursor ) {
 		cursor->c_close( cursor );
@@ -167,10 +183,14 @@
 	assert( be != NULL );
 	assert( slapMode & SLAP_TOOL_MODE );
 	assert( bdb != NULL );
-	
+
+	/* Get the header */
+	data.ulen = data.dlen = sizeof( ehbuf );
+	data.data = ehbuf;
+	data.flags |= DB_DBT_PARTIAL;
 	rc = cursor->c_get( cursor, &key, &data, DB_NEXT );
 
-	if( rc != 0 ) {
+	if( rc ) {
 		/* If we're doing linear indexing and there are more attrs to
 		 * index, and we're at the end of the database, start over.
 		 */
@@ -188,11 +208,8 @@
 		}
 	}
 
-	if( data.data == NULL ) {
-		return NOID;
-	}
-
 	BDB_DISK2ID( key.data, &id );
+	previd = id;
 	return id;
 }
 
@@ -214,7 +231,7 @@
 	op.o_tmpmemctx = NULL;
 	op.o_tmpmfuncs = &ch_mfuncs;
 
-	rc = bdb_cache_find_ndn( &op, NULL, dn, &ei );
+	rc = bdb_cache_find_ndn( &op, 0, dn, &ei );
 	if ( ei ) bdb_cache_entryinfo_unlock( ei );
 	if ( rc == DB_NOTFOUND )
 		return NOID;
@@ -222,75 +239,86 @@
 	return ei->bei_id;
 }
 
-int bdb_tool_id2entry_get(
-	Backend *be,
-	ID id,
-	Entry **e
-)
+Entry* bdb_tool_entry_get( BackendDB *be, ID id )
 {
-	int rc;
-	ID nid;
+	Entry *e = NULL;
+	char *dptr;
+	int rc, eoff;
 
-	BDB_ID2DISK( id, &nid );
-	key.ulen = key.size = sizeof(ID);
-	key.flags = DB_DBT_USERMEM;
-	key.data = &nid;
+	assert( be != NULL );
+	assert( slapMode & SLAP_TOOL_MODE );
 
-	rc = cursor->c_get( cursor, &key, &data, DB_SET );
-	if ( rc == 0 ) {
-		*e = bdb_tool_entry_get( be, id );
-		if ( *e == NULL )
-			rc = LDAP_OTHER;
+	if ( id != previd ) {
+		data.ulen = data.dlen = sizeof( ehbuf );
+		data.data = ehbuf;
+		data.flags |= DB_DBT_PARTIAL;
+
+		BDB_ID2DISK( id, &nid );
+		rc = cursor->c_get( cursor, &key, &data, DB_SET );
+		if ( rc ) goto done;
 	}
-	key.data = NULL;
 
-	return rc;
-}
+	/* Get the header */
+	dptr = eh.bv.bv_val;
+	eh.bv.bv_val = ehbuf;
+	eh.bv.bv_len = data.size;
+	rc = entry_header( &eh );
+	eoff = eh.data - eh.bv.bv_val;
+	eh.bv.bv_val = dptr;
+	if ( rc ) goto done;
 
-Entry* bdb_tool_entry_get( BackendDB *be, ID id )
-{
-	int rc;
-	Entry *e = NULL;
-	struct berval bv;
+	/* Get the size */
+	data.flags &= ~DB_DBT_PARTIAL;
+	data.ulen = 0;
+    rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
+	if ( rc != DB_BUFFER_SMALL ) goto done;
 
-	assert( be != NULL );
-	assert( slapMode & SLAP_TOOL_MODE );
-	assert( data.data != NULL );
+	/* Allocate a block and retrieve the data */
+	eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size;
+	eh.bv.bv_val = ch_realloc( eh.bv.bv_val, eh.bv.bv_len );
+	eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval );
+	data.data = eh.data;
+	data.ulen = data.size;
 
-	DBT2bv( &data, &bv );
+	/* Skip past already parsed nattr/nvals */
+	eh.data += eoff;
 
+    rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
+	if ( rc ) goto done;
+
 #ifdef SLAP_ZONE_ALLOC
 	/* FIXME: will add ctx later */
-	rc = entry_decode( &bv, &e, NULL );
+	rc = entry_decode( &eh, &e, NULL );
 #else
-	rc = entry_decode( &bv, &e );
+	rc = entry_decode( &eh, &e );
 #endif
 
 	if( rc == LDAP_SUCCESS ) {
 		e->e_id = id;
-	}
 #ifdef BDB_HIER
-	if ( slapMode & SLAP_TOOL_READONLY ) {
-		EntryInfo *ei = NULL;
-		Operation op = {0};
-		Opheader ohdr = {0};
+		if ( slapMode & SLAP_TOOL_READONLY ) {
+			EntryInfo *ei = NULL;
+			Operation op = {0};
+			Opheader ohdr = {0};
 
-		op.o_hdr = &ohdr;
-		op.o_bd = be;
-		op.o_tmpmemctx = NULL;
-		op.o_tmpmfuncs = &ch_mfuncs;
+			op.o_hdr = &ohdr;
+			op.o_bd = be;
+			op.o_tmpmemctx = NULL;
+			op.o_tmpmfuncs = &ch_mfuncs;
 
-		rc = bdb_cache_find_parent( &op, NULL, cursor->locker, id, &ei );
-		if ( rc == LDAP_SUCCESS ) {
-			bdb_cache_entryinfo_unlock( ei );
-			e->e_private = ei;
-			ei->bei_e = e;
-			bdb_fix_dn( e, 0 );
-			ei->bei_e = NULL;
-			e->e_private = NULL;
+			rc = bdb_cache_find_parent( &op, CURSOR_GETLOCKER(cursor), id, &ei );
+			if ( rc == LDAP_SUCCESS ) {
+				bdb_cache_entryinfo_unlock( ei );
+				e->e_private = ei;
+				ei->bei_e = e;
+				bdb_fix_dn( e, 0 );
+				ei->bei_e = NULL;
+				e->e_private = NULL;
+			}
 		}
+#endif
 	}
-#endif
+done:
 	return e;
 }
 
@@ -312,7 +340,7 @@
 		return 0;
 	}
 
-	rc = bdb_cache_find_ndn( op, tid, &ndn, &ei );
+	rc = bdb_cache_find_ndn( op, tid ? TXN_ID( tid ) : 0, &ndn, &ei );
 	if ( ei ) bdb_cache_entryinfo_unlock( ei );
 	if ( rc == DB_NOTFOUND ) {
 		if ( !be_issuffix( op->o_bd, &ndn ) ) {
@@ -394,7 +422,7 @@
 {
 	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
 
-	if (!bdb->bi_nattrs)
+	if ( !bdb->bi_nattrs )
 		return 0;
 
 	if ( slapMode & SLAP_TOOL_QUICK ) {
@@ -416,28 +444,32 @@
 		ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
 		/* Wait for all threads to be ready */
 		while ( bdb_tool_index_tcount ) {
-			ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
-			ldap_pvt_thread_yield();
-			ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
+			ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, 
+				&bdb_tool_index_mutex );
 		}
 		for ( i=1; i<slap_tool_thread_max; i++ )
 			bdb_tool_index_threads[i] = LDAP_BUSY;
 		bdb_tool_index_tcount = slap_tool_thread_max - 1;
-		ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond );
+		ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work );
 		ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
 		rc = bdb_index_recrun( op, bdb, ir, e->e_id, 0 );
 		if ( rc )
 			return rc;
+		ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
 		for ( i=1; i<slap_tool_thread_max; i++ ) {
 			if ( bdb_tool_index_threads[i] == LDAP_BUSY ) {
-				ldap_pvt_thread_yield();
+				ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, 
+					&bdb_tool_index_mutex );
 				i--;
 				continue;
 			}
-			if ( bdb_tool_index_threads[i] )
-				return bdb_tool_index_threads[i];
+			if ( bdb_tool_index_threads[i] ) {
+				rc = bdb_tool_index_threads[i];
+				break;
+			}
 		}
-		return 0;
+		ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
+		return rc;
 	} else {
 		return bdb_index_entry_add( op, txn, e );
 	}
@@ -489,11 +521,18 @@
 		goto done;
 	}
 
+	if (( slapMode & SLAP_TOOL_QUICK ) && (( e->e_id & 0xfff ) == 0xfff )) {
+		ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex );
+		ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond );
+		ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex );
+	}
+
 	if ( !bdb->bi_linear_index )
 		rc = bdb_tool_index_add( &op, tid, e );
 	if( rc != 0 ) {
 		snprintf( text->bv_val, text->bv_len,
 				"index_entry_add failed: %s (%d)",
+				rc == LDAP_OTHER ? "Internal error" :
 				db_strerror(rc), rc );
 		Debug( LDAP_DEBUG_ANY,
 			"=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
@@ -533,6 +572,7 @@
 		TXN_ABORT( tid );
 		snprintf( text->bv_val, text->bv_len,
 			"txn_aborted! %s (%d)",
+			rc == LDAP_OTHER ? "Internal error" :
 			db_strerror(rc), rc );
 		Debug( LDAP_DEBUG_ANY,
 			"=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
@@ -546,7 +586,8 @@
 
 int bdb_tool_entry_reindex(
 	BackendDB *be,
-	ID id )
+	ID id,
+	AttributeDescription **adv )
 {
 	struct bdb_info *bi = (struct bdb_info *) be->be_private;
 	int rc;
@@ -566,6 +607,47 @@
 		return 0;
 	}
 
+	/* Check for explicit list of attrs to index */
+	if ( adv ) {
+		int i, j, n;
+
+		if ( bi->bi_attrs[0]->ai_desc != adv[0] ) {
+			/* count */
+			for ( n = 0; adv[n]; n++ ) ;
+
+			/* insertion sort */
+			for ( i = 0; i < n; i++ ) {
+				AttributeDescription *ad = adv[i];
+				for ( j = i-1; j>=0; j--) {
+					if ( SLAP_PTRCMP( adv[j], ad ) <= 0 ) break;
+					adv[j+1] = adv[j];
+				}
+				adv[j+1] = ad;
+			}
+		}
+
+		for ( i = 0; adv[i]; i++ ) {
+			if ( bi->bi_attrs[i]->ai_desc != adv[i] ) {
+				for ( j = i+1; j < bi->bi_nattrs; j++ ) {
+					if ( bi->bi_attrs[j]->ai_desc == adv[i] ) {
+						AttrInfo *ai = bi->bi_attrs[i];
+						bi->bi_attrs[i] = bi->bi_attrs[j];
+						bi->bi_attrs[j] = ai;
+						break;
+					}
+				}
+				if ( j == bi->bi_nattrs ) {
+					Debug( LDAP_DEBUG_ANY,
+						LDAP_XSTRING(bdb_tool_entry_reindex)
+						": no index configured for %s\n",
+						adv[i]->ad_cname.bv_val, 0, 0 );
+					return -1;
+				}
+			}
+		}
+		bi->bi_nattrs = i;
+	}
+
 	/* Get the first attribute to index */
 	if (bi->bi_linear_index && !index_nattrs) {
 		index_nattrs = bi->bi_nattrs - 1;
@@ -664,18 +746,22 @@
 		(long) e->e_id, e->e_dn, 0 );
 
 	if (! (slapMode & SLAP_TOOL_QUICK)) {
-	rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, 
-		bdb->bi_db_opflags );
-	if( rc != 0 ) {
-		snprintf( text->bv_val, text->bv_len,
-			"txn_begin failed: %s (%d)",
-			db_strerror(rc), rc );
-		Debug( LDAP_DEBUG_ANY,
-			"=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
-			 text->bv_val, 0, 0 );
-		return NOID;
+		if( cursor ) {
+			cursor->c_close( cursor );
+			cursor = NULL;
+		}
+		rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, 
+			bdb->bi_db_opflags );
+		if( rc != 0 ) {
+			snprintf( text->bv_val, text->bv_len,
+				"txn_begin failed: %s (%d)",
+				db_strerror(rc), rc );
+			Debug( LDAP_DEBUG_ANY,
+				"=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
+				 text->bv_val, 0, 0 );
+			return NOID;
+		}
 	}
-	}
 
 	op.o_hdr = &ohdr;
 	op.o_bd = be;
@@ -1013,6 +1099,25 @@
 #endif
 
 static void *
+bdb_tool_trickle_task( void *ctx, void *ptr )
+{
+	DB_ENV *env = ptr;
+	int wrote;
+
+	ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex );
+	while ( 1 ) {
+		ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond,
+			&bdb_tool_trickle_mutex );
+		if ( slapd_shutdown )
+			break;
+		env->memp_trickle( env, 30, &wrote );
+	}
+	ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex );
+
+	return NULL;
+}
+
+static void *
 bdb_tool_index_task( void *ctx, void *ptr )
 {
 	int base = *(int *)ptr;
@@ -1021,7 +1126,9 @@
 	while ( 1 ) {
 		ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
 		bdb_tool_index_tcount--;
-		ldap_pvt_thread_cond_wait( &bdb_tool_index_cond,
+		if ( !bdb_tool_index_tcount )
+			ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main );
+		ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_work,
 			&bdb_tool_index_mutex );
 		ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
 		if ( slapd_shutdown )

Modified: openldap/trunk/servers/slapd/back-bdb/trans.c
===================================================================
--- openldap/trunk/servers/slapd/back-bdb/trans.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-bdb/trans.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* trans.c - bdb backend transaction routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/trans.c,v 1.6.2.3 2007/01/02 21:44:00 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/trans.c,v 1.8.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-dnssrv/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-dnssrv/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-dnssrv/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-dnssrv
-# $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/Makefile.in,v 1.12.2.4 2007/01/02 21:44:01 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/Makefile.in,v 1.14.2.2 2007/08/31 23:14:01 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-dnssrv/bind.c
===================================================================
--- openldap/trunk/servers/slapd/back-dnssrv/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-dnssrv/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* bind.c - DNS SRV backend bind function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/bind.c,v 1.19.2.5 2007/01/02 21:44:01 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/bind.c,v 1.22.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -32,30 +32,42 @@
 
 int
 dnssrv_back_bind(
-    Operation		*op,
-    SlapReply		*rs )
+	Operation	*op,
+	SlapReply	*rs )
 {
-	Debug( LDAP_DEBUG_TRACE, "DNSSRV: bind %s (%d)\n",
-		op->o_req_dn.bv_val == NULL ? "" : op->o_req_dn.bv_val, 
-		op->oq_bind.rb_method, NULL );
-		
-	if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE &&
-		!BER_BVISNULL( &op->oq_bind.rb_cred ) &&
-		!BER_BVISEMPTY( &op->oq_bind.rb_cred ) )
+	Debug( LDAP_DEBUG_TRACE, "DNSSRV: bind dn=\"%s\" (%d)\n",
+		BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, 
+		op->orb_method, 0 );
+
+	/* allow rootdn as a means to auth without the need to actually
+ 	 * contact the proxied DSA */
+	switch ( be_rootdn_bind( op, NULL ) ) {
+	case LDAP_SUCCESS:
+		/* frontend will send result */
+		return rs->sr_err;
+
+	default:
+		/* treat failure and like any other bind, otherwise
+		 * it could reveal the DN of the rootdn */
+		break;
+	}
+
+	if ( !BER_BVISNULL( &op->orb_cred ) &&
+		!BER_BVISEMPTY( &op->orb_cred ) )
 	{
+		/* simple bind */
 		Statslog( LDAP_DEBUG_STATS,
-		   	"%s DNSSRV BIND dn=\"%s\" provided passwd\n",
+		   	"%s DNSSRV BIND dn=\"%s\" provided cleartext passwd\n",
 	   		op->o_log_prefix,
 			BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val , 0, 0, 0 );
 
-		Debug( LDAP_DEBUG_TRACE,
-			"DNSSRV: BIND dn=\"%s\" provided cleartext password\n",
-			BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, 0, 0 );
-
 		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
 			"you shouldn't send strangers your password" );
 
 	} else {
+		/* unauthenticated bind */
+		/* NOTE: we're not going to get here anyway:
+		 * unauthenticated bind is dealt with by the frontend */
 		Debug( LDAP_DEBUG_TRACE, "DNSSRV: BIND dn=\"%s\"\n",
 			BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, 0, 0 );
 

Modified: openldap/trunk/servers/slapd/back-dnssrv/compare.c
===================================================================
--- openldap/trunk/servers/slapd/back-dnssrv/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-dnssrv/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* compare.c - DNS SRV backend compare function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/compare.c,v 1.16.2.4 2007/01/02 21:44:01 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/compare.c,v 1.18.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-dnssrv/config.c
===================================================================
--- openldap/trunk/servers/slapd/back-dnssrv/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-dnssrv/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* config.c - DNS SRV backend configuration file routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/config.c,v 1.13.2.5 2007/01/02 21:44:01 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/config.c,v 1.16.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-dnssrv/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-dnssrv/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-dnssrv/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* init.c - initialize ldap backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/init.c,v 1.24.2.6 2007/01/02 21:44:01 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/init.c,v 1.29.2.3 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -24,8 +24,11 @@
 #include <stdio.h>
 
 #include <ac/socket.h>
+#include <ac/param.h>
+#include <ac/string.h>
 
 #include "slap.h"
+#include "config.h"
 #include "proto-dnssrv.h"
 
 int
@@ -67,9 +70,7 @@
 	bi->bi_connection_init = 0;
 	bi->bi_connection_destroy = 0;
 
-#ifdef SLAP_OVERLAY_ACCESS
 	bi->bi_access_allowed = slap_access_always_allowed;
-#endif /* SLAP_OVERLAY_ACCESS */
 
 	return 0;
 }
@@ -91,14 +92,16 @@
 
 int
 dnssrv_back_db_init(
-    Backend	*be )
+	Backend	*be,
+	ConfigReply *cr)
 {
 	return 0;
 }
 
 int
 dnssrv_back_db_destroy(
-    Backend	*be )
+	Backend	*be,
+	ConfigReply *cr )
 {
 	return 0;
 }

Modified: openldap/trunk/servers/slapd/back-dnssrv/proto-dnssrv.h
===================================================================
--- openldap/trunk/servers/slapd/back-dnssrv/proto-dnssrv.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-dnssrv/proto-dnssrv.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/proto-dnssrv.h,v 1.2.2.5 2007/01/02 21:44:01 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/proto-dnssrv.h,v 1.5.2.2 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-dnssrv/referral.c
===================================================================
--- openldap/trunk/servers/slapd/back-dnssrv/referral.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-dnssrv/referral.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* referral.c - DNS SRV backend referral handler */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/referral.c,v 1.17.2.6 2007/01/02 21:44:01 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/referral.c,v 1.26.2.3 2007/08/31 23:14:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -42,13 +42,11 @@
 	BerVarray urls = NULL;
 
 	if ( BER_BVISEMPTY( &op->o_req_dn ) ) {
-#ifdef LDAP_DEVEL
 		/* FIXME: need some means to determine whether the database
 		 * is a glue instance */
 		if ( SLAP_GLUE_INSTANCE( op->o_bd ) ) {
 			return LDAP_SUCCESS;
 		}
-#endif /* LDAP_DEVEL */
 
 		rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed";
 		return LDAP_UNWILLING_TO_PERFORM;

Modified: openldap/trunk/servers/slapd/back-dnssrv/search.c
===================================================================
--- openldap/trunk/servers/slapd/back-dnssrv/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-dnssrv/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* search.c - DNS SRV backend search function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/search.c,v 1.35.2.6 2007/01/02 21:44:01 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-dnssrv/search.c,v 1.44.2.3 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.
@@ -48,7 +48,6 @@
 	rs->sr_ref = NULL;
 
 	if ( BER_BVISEMPTY( &op->o_req_ndn ) ) {
-#ifdef LDAP_DEVEL
 		/* FIXME: need some means to determine whether the database
 		 * is a glue instance; if we got here with empty DN, then
 		 * we passed this same test in dnssrv_back_referrals() */
@@ -60,7 +59,6 @@
 			rs->sr_err = LDAP_SUCCESS;
 		}
 		goto done;
-#endif /* LDAP_DEVEL */
 	}
 
 	manageDSAit = get_manageDSAit( op );

Modified: openldap/trunk/servers/slapd/back-hdb/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-hdb/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-hdb/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile for back-hdb
-# $OpenLDAP: pkg/ldap/servers/slapd/back-hdb/Makefile.in,v 1.9.2.6 2007/10/23 21:21:38 quanah Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-hdb/Makefile.in,v 1.14.2.5 2007/10/23 21:25:37 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -21,13 +21,15 @@
 	add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
 	extended.c referral.c operational.c \
 	attr.c index.c key.c dbcache.c filterindex.c trans.c \
-	dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c
+	dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c \
+	monitor.c
 SRCS = $(XXSRCS)
 OBJS = init.lo tools.lo config.lo \
 	add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
 	extended.lo referral.lo operational.lo \
 	attr.lo index.lo key.lo dbcache.lo filterindex.lo trans.lo \
-	dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo
+	dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo \
+	monitor.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries
@@ -37,7 +39,7 @@
 
 mod_DEFS = -DSLAPD_IMPORT
 MOD_DEFS = $(@BUILD_HDB at _DEFS)
-MOD_LIBS = $(LDBM_LIBS)
+MOD_LIBS = $(BDB_LIBS)
 
 shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA)
 NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC at _LDAP_LIBS)

Modified: openldap/trunk/servers/slapd/back-hdb/back-bdb.h
===================================================================
--- openldap/trunk/servers/slapd/back-hdb/back-bdb.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-hdb/back-bdb.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* back-bdb.h - hdb back-end header file */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-hdb/back-bdb.h,v 1.3.2.3 2007/01/02 21:44:01 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-hdb/back-bdb.h,v 1.5.2.2 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2000-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-ldap/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-ldap
-# $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/Makefile.in,v 1.26.2.3 2007/01/02 21:44:01 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/Makefile.in,v 1.30.2.3 2007/08/31 23:14:02 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -14,9 +14,11 @@
 ## <http://www.OpenLDAP.org/license.html>.
 
 SRCS	= init.c config.c search.c bind.c unbind.c add.c compare.c \
-		delete.c modify.c modrdn.c extended.c chain.c
+		delete.c modify.c modrdn.c extended.c chain.c \
+		distproc.c monitor.c
 OBJS	= init.lo config.lo search.lo bind.lo unbind.lo add.lo compare.lo \
-		delete.lo modify.lo modrdn.lo extended.lo chain.lo
+		delete.lo modify.lo modrdn.lo extended.lo chain.lo \
+		distproc.lo monitor.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries

Modified: openldap/trunk/servers/slapd/back-ldap/add.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/add.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/add.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* add.c - ldap backend add function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/add.c,v 1.53.2.11 2007/01/13 11:19:06 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/add.c,v 1.61.2.4 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -70,7 +70,7 @@
 
 	isupdate = be_shadow_update( op );
 	for ( i = 0, a = op->oq_add.rs_e->e_attrs; a; a = a->a_next ) {
-		if ( !isupdate && !get_manageDIT( op ) && a->a_desc->ad_type->sat_no_user_mod  )
+		if ( !isupdate && !get_relax( op ) && a->a_desc->ad_type->sat_no_user_mod  )
 		{
 			continue;
 		}
@@ -93,8 +93,7 @@
 
 retry:
 	ctrls = op->o_ctrls;
-	rs->sr_err = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-		li->li_version, &li->li_idassert, op, rs, &ctrls );
+	rs->sr_err = ldap_back_controls_add( op, rs, lc, &ctrls );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		send_ldap_result( op, rs );
 		goto cleanup;
@@ -109,13 +108,13 @@
 		retrying &= ~LDAP_BACK_RETRYING;
 		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	if ( attrs ) {
 		for ( --i; i >= 0; --i ) {

Modified: openldap/trunk/servers/slapd/back-ldap/back-ldap.h
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/back-ldap.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/back-ldap.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* back-ldap.h - ldap backend header file */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/back-ldap.h,v 1.63.2.23 2007/01/27 23:56:43 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/back-ldap.h,v 1.88.2.6 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -24,10 +24,26 @@
 #ifndef SLAPD_LDAP_H
 #define SLAPD_LDAP_H
 
+#include "../back-monitor/back-monitor.h"
+
 LDAP_BEGIN_DECL
 
 struct ldapinfo_t;
 
+/* stuff required for monitoring */
+typedef struct ldap_monitor_info_t {
+	monitor_subsys_t	lmi_mss;
+	struct ldapinfo_t	*lmi_li;
+
+	struct berval		lmi_rdn;
+	struct berval		lmi_nrdn;
+	monitor_callback_t	*lmi_cb;
+	struct berval		lmi_base;
+	int			lmi_scope;
+	struct berval		lmi_filter;
+	struct berval		lmi_more_filter;
+} ldap_monitor_info_t;
+
 enum {
 	/* even numbers are connection types */
 	LDAP_BACK_PCONN_FIRST = 0,
@@ -231,8 +247,12 @@
 	ldap_pvt_thread_mutex_t	li_uri_mutex;
 
 	LDAP_REBIND_PROC	*li_rebind_f;
+	LDAP_URLLIST_PROC	*li_urllist_f;
 	void			*li_urllist_p;
 
+	/* we only care about the TLS options here */
+	slap_bindconf		li_tls;
+
 	slap_bindconf		li_acl;
 #define	li_acl_authcID		li_acl.sb_authcId
 #define	li_acl_authcDN		li_acl.sb_binddn
@@ -290,6 +310,11 @@
 
 #define	LDAP_BACK_F_QUARANTINE		(0x00010000U)
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+#define	LDAP_BACK_F_ST_REQUEST		(0x00020000U)
+#define	LDAP_BACK_F_ST_RESPONSE		(0x00040000U)
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
 #define	LDAP_BACK_ISSET_F(ff,f)		( ( (ff) & (f) ) == (f) )
 #define	LDAP_BACK_ISMASK_F(ff,m,f)	( ( (ff) & (m) ) == (f) )
 
@@ -323,6 +348,11 @@
 
 #define	LDAP_BACK_QUARANTINE(li)	LDAP_BACK_ISSET( (li), LDAP_BACK_F_QUARANTINE )
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+#define	LDAP_BACK_ST_REQUEST(li)	LDAP_BACK_ISSET( (li), LDAP_BACK_F_ST_REQUEST)
+#define	LDAP_BACK_ST_RESPONSE(li)	LDAP_BACK_ISSET( (li), LDAP_BACK_F_ST_RESPONSE)
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
 	int			li_version;
 
 	/* cached connections; 
@@ -339,6 +369,8 @@
 	 * and LDAP_BACK_CONN_PRIV_MAX ! */
 #define	LDAP_BACK_CONN_PRIV_DEFAULT	(16)
 
+	ldap_monitor_info_t	li_monitor_info;
+
 	sig_atomic_t		li_isquarantined;
 #define	LDAP_BACK_FQ_NO		(0)
 #define	LDAP_BACK_FQ_YES	(1)

Modified: openldap/trunk/servers/slapd/back-ldap/bind.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* bind.c - ldap backend bind function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/bind.c,v 1.85.2.37 2007/09/09 20:24:13 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/bind.c,v 1.162.2.14 2007/10/17 00:45:15 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -173,10 +173,23 @@
 	ldapinfo_t		*li = (ldapinfo_t *) op->o_bd->be_private;
 	ldapconn_t		*lc;
 
-	int			rc = 0;
+	LDAPControl		**ctrls = NULL;
+	struct berval		save_o_dn;
+	int			save_o_do_not_cache,
+				rc = 0;
 	ber_int_t		msgid;
 	ldap_back_send_t	retrying = LDAP_BACK_RETRYING;
 
+	/* allow rootdn as a means to auth without the need to actually
+ 	 * contact the proxied DSA */
+	switch ( be_rootdn_bind( op, rs ) ) {
+	case SLAP_CB_CONTINUE:
+		break;
+
+	default:
+		return rs->sr_err;
+	}
+
 	lc = ldap_back_getconn( op, rs, LDAP_BACK_BIND_SERR, NULL, NULL );
 	if ( !lc ) {
 		return rs->sr_err;
@@ -195,11 +208,27 @@
 	}
 	LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
 
+	/* don't add proxyAuthz; set the bindDN */
+	save_o_dn = op->o_dn;
+	save_o_do_not_cache = op->o_do_not_cache;
+	op->o_dn = op->o_req_dn;
+	op->o_do_not_cache = 1;
+
+	ctrls = op->o_ctrls;
+	rc = ldap_back_controls_add( op, rs, lc, &ctrls );
+	op->o_dn = save_o_dn;
+	op->o_do_not_cache = save_o_do_not_cache;
+	if ( rc != LDAP_SUCCESS ) {
+		send_ldap_result( op, rs );
+		ldap_back_release_conn( li, lc );
+		return( rc );
+	}
+
 retry:;
 	/* method is always LDAP_AUTH_SIMPLE if we got here */
 	rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val,
 			LDAP_SASL_SIMPLE,
-			&op->orb_cred, op->o_ctrls, NULL, &msgid );
+			&op->orb_cred, ctrls, NULL, &msgid );
 	/* FIXME: should we always retry, or only when piping the bind
 	 * in the "override" connection pool? */
 	rc = ldap_back_op_result( lc, op, rs, msgid,
@@ -212,6 +241,8 @@
 		}
 	}
 
+	ldap_back_controls_free( op, rs, &ctrls );
+
 	if ( rc == LDAP_SUCCESS ) {
 		/* If defined, proxyAuthz will be used also when
 		 * back-ldap is the authorizing backend; for this
@@ -601,6 +632,7 @@
 #ifdef HAVE_TLS
 	int		is_tls = op->o_conn->c_is_tls;
 	time_t		lc_time = (time_t)(-1);
+	slap_bindconf *sb;
 #endif /* HAVE_TLS */
 
 	ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
@@ -610,6 +642,10 @@
 		goto error_return;
 	}
 
+	if ( li->li_urllist_f ) {
+		ldap_set_urllist_proc( ld, li->li_urllist_f, li->li_urllist_p );
+	}
+
 	/* Set LDAP version. This will always succeed: If the client
 	 * bound with a particular version, then so can we.
 	 */
@@ -638,6 +674,22 @@
 	}
 
 #ifdef HAVE_TLS
+	if ( LDAP_BACK_CONN_ISPRIV( lc ) ) {
+		sb = &li->li_acl;
+
+	} else if ( LDAP_BACK_CONN_ISIDASSERT( lc ) ) {
+		sb = &li->li_idassert.si_bc;
+
+	} else {
+		sb = &li->li_tls;
+	}
+
+	if ( sb->sb_tls_do_init ) {
+		bindconf_tls_set( sb, ld );
+	} else if ( sb->sb_tls_ctx ) {
+		ldap_set_option( ld, LDAP_OPT_X_TLS_CTX, sb->sb_tls_ctx );
+	}
+
 	ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
 	rs->sr_err = ldap_back_start_tls( ld, op->o_protocol, &is_tls,
 			li->li_uri, li->li_flags, li->li_nretries, &rs->sr_text );
@@ -985,7 +1037,7 @@
 	
 		ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 
-		if ( StatslogTest( LDAP_DEBUG_TRACE ) ) {
+		if ( LogTest( LDAP_DEBUG_TRACE ) ) {
 			char	buf[ SLAP_TEXT_BUFLEN ];
 
 			snprintf( buf, sizeof( buf ),
@@ -1054,7 +1106,7 @@
 			ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 		}
 
-		if ( StatslogTest( LDAP_DEBUG_TRACE ) ) {
+		if ( LogTest( LDAP_DEBUG_TRACE ) ) {
 			char	buf[ SLAP_TEXT_BUFLEN ];
 
 			snprintf( buf, sizeof( buf ),
@@ -1168,6 +1220,17 @@
 	ldap_pvt_thread_mutex_unlock( &li->li_quarantine_mutex );
 }
 
+static int
+ldap_back_dobind_cb(
+	Operation *op,
+	SlapReply *rs
+)
+{
+	ber_tag_t *tptr = op->o_callback->sc_private;
+	op->o_tag = *tptr;
+	return SLAP_CB_CONTINUE;
+}
+
 /*
  * ldap_back_dobind_int
  *
@@ -1192,6 +1255,8 @@
 			isbound,
 			binding = 0;
 	ber_int_t	msgid;
+	ber_tag_t	o_tag = op->o_tag;
+	slap_callback cb = {0};
 
 	assert( lcp != NULL );
 	assert( retries >= 0 );
@@ -1263,10 +1328,16 @@
 	 * then bind as the asserting identity and explicitly 
 	 * add the proxyAuthz control to every operation with the
 	 * dn bound to the connection as control value.
-	 * This is done also if this is the authrizing backend,
+	 * This is done also if this is the authorizing backend,
 	 * but the "override" flag is given to idassert.
 	 * It allows to use SASL bind and yet proxyAuthz users
 	 */
+	op->o_tag = LDAP_REQ_BIND;
+	cb.sc_next = op->o_callback;
+	cb.sc_private = &o_tag;
+	cb.sc_response = ldap_back_dobind_cb;
+	op->o_callback = &cb;
+
 	if ( LDAP_BACK_CONN_ISIDASSERT( lc ) ) {
 		if ( BER_BVISEMPTY( &binddn ) && BER_BVISEMPTY( &bindcred ) ) {
 			/* if we got here, it shouldn't return result */
@@ -1302,6 +1373,14 @@
 				li->li_acl_authcID.bv_val,
 				li->li_acl_passwd.bv_val,
 				NULL );
+		if ( defaults == NULL ) {
+			rs->sr_err = LDAP_OTHER;
+			LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
+			if ( sendok & LDAP_BACK_SENDERR ) {
+				send_ldap_result( op, rs );
+			}
+			goto done;
+		}
 
 		rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld,
 				li->li_acl_authcDN.bv_val,
@@ -1380,11 +1459,15 @@
 		if ( rs->sr_err != LDAP_SUCCESS &&
 			( sendok & LDAP_BACK_SENDERR ) )
 		{
-			rs->sr_text = "Internal proxy bind failure";
+			if ( op->o_callback == &cb )
+				op->o_callback = cb.sc_next;
+			op->o_tag = o_tag;
+			rs->sr_text = "Proxy can't contact remote server";
 			send_ldap_result( op, rs );
 		}
 
-		return 0;
+		rc = 0;
+		goto leave;
 	}
 
 	rc = ldap_back_op_result( lc, op, rs, msgid,
@@ -1403,6 +1486,11 @@
 		ldap_set_rebind_proc( lc->lc_ld, li->li_rebind_f, lc );
 	}
 
+leave:;
+	if ( op->o_callback == &cb )
+		op->o_callback = cb.sc_next;
+	op->o_tag = o_tag;
+
 	return rc;
 }
 
@@ -1456,6 +1544,41 @@
 			LDAP_SASL_SIMPLE, &lc->lc_cred, NULL, NULL, NULL );
 }
 
+/*
+ * ldap_back_default_urllist
+ */
+int 
+ldap_back_default_urllist(
+	LDAP		*ld,
+	LDAPURLDesc	**urllist,
+	LDAPURLDesc	**url,
+	void		*params )
+{
+	ldapinfo_t	*li = (ldapinfo_t *)params;
+	LDAPURLDesc	**urltail;
+
+	if ( urllist == url ) {
+		return LDAP_SUCCESS;
+	}
+
+	for ( urltail = &(*url)->lud_next; *urltail; urltail = &(*urltail)->lud_next )
+		/* count */ ;
+
+	*urltail = *urllist;
+	*urllist = *url;
+	*url = NULL;
+
+	ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
+	if ( li->li_uri ) {
+		ch_free( li->li_uri );
+	}
+
+	ldap_get_option( ld, LDAP_OPT_URI, (void *)&li->li_uri );
+	ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
+
+	return LDAP_SUCCESS;
+}
+
 int
 ldap_back_cancel(
 		ldapconn_t		*lc,
@@ -1471,6 +1594,10 @@
 		return ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL );
 	}
 
+	if ( LDAP_BACK_IGNORE( li ) ) {
+		return ldap_pvt_discard( lc->lc_ld, msgid );
+	}
+
 	if ( LDAP_BACK_CANCEL( li ) ) {
 		/* FIXME: asynchronous? */
 		return ldap_cancel_s( lc->lc_ld, msgid, NULL, NULL );
@@ -1993,6 +2120,14 @@
 				li->li_idassert_authcID.bv_val,
 				li->li_idassert_passwd.bv_val,
 				authzID.bv_val );
+		if ( defaults == NULL ) {
+			rs->sr_err = LDAP_OTHER;
+			LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
+			if ( sendok & LDAP_BACK_SENDERR ) {
+				send_ldap_result( op, rs );
+			}
+			goto done;
+		}
 
 		rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld, binddn->bv_val,
 				li->li_idassert_sasl_mech.bv_val, NULL, NULL,
@@ -2096,39 +2231,20 @@
  */
 int
 ldap_back_proxy_authz_ctrl(
+		Operation	*op,
+		SlapReply	*rs,
 		struct berval	*bound_ndn,
 		int		version,
 		slap_idassert_t	*si,
-		Operation	*op,
-		SlapReply	*rs,
-		LDAPControl	***pctrls )
+		LDAPControl	*ctrl )
 {
-	LDAPControl		**ctrls = NULL;
-	int			i = 0;
 	slap_idassert_mode_t	mode;
 	struct berval		assertedID,
 				ndn;
 	int			isroot = 0;
 
-	*pctrls = NULL;
+	rs->sr_err = SLAP_CB_CONTINUE;
 
-	rs->sr_err = LDAP_SUCCESS;
-
-	/* don't proxyAuthz if protocol is not LDAPv3 */
-	switch ( version ) {
-	case LDAP_VERSION3:
-		break;
-
-	case 0:
-		if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
-			break;
-		}
-		/* fall thru */
-
-	default:
-		goto done;
-	}
-
 	/* FIXME: SASL/EXTERNAL over ldapi:// doesn't honor the authcID,
 	 * but if it is not set this test fails.  We need a different
 	 * means to detect if idassert is enabled */
@@ -2201,7 +2317,7 @@
 			authcDN = ndn;
 		}
 		rc = slap_sasl_matches( op, si->si_authz,
-				&authcDN, & authcDN );
+				&authcDN, &authcDN );
 		if ( rc != LDAP_SUCCESS ) {
 			if ( si->si_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
 				/* ndn is not authorized
@@ -2278,33 +2394,25 @@
 		goto done;
 	}
 
-	if ( op->o_ctrls ) {
-		for ( i = 0; op->o_ctrls[ i ]; i++ )
-			/* just count ctrls */ ;
-	}
+	ctrl->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
 
-	ctrls = op->o_tmpalloc( sizeof( LDAPControl * ) * (i + 2) + sizeof( LDAPControl ),
-			op->o_tmpmemctx );
-	ctrls[ 0 ] = (LDAPControl *)&ctrls[ i + 2 ];
-	
-	ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
-	ctrls[ 0 ]->ldctl_iscritical = 1;
-
 	switch ( si->si_mode ) {
 	/* already in u:ID or dn:DN form */
 	case LDAP_BACK_IDASSERT_OTHERID:
 	case LDAP_BACK_IDASSERT_OTHERDN:
-		ber_dupbv_x( &ctrls[ 0 ]->ldctl_value, &assertedID, op->o_tmpmemctx );
+		ber_dupbv_x( &ctrl->ldctl_value, &assertedID, op->o_tmpmemctx );
+		rs->sr_err = LDAP_SUCCESS;
 		break;
 
 	/* needs the dn: prefix */
 	default:
-		ctrls[ 0 ]->ldctl_value.bv_len = assertedID.bv_len + STRLENOF( "dn:" );
-		ctrls[ 0 ]->ldctl_value.bv_val = op->o_tmpalloc( ctrls[ 0 ]->ldctl_value.bv_len + 1,
+		ctrl->ldctl_value.bv_len = assertedID.bv_len + STRLENOF( "dn:" );
+		ctrl->ldctl_value.bv_val = op->o_tmpalloc( ctrl->ldctl_value.bv_len + 1,
 				op->o_tmpmemctx );
-		AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val, "dn:", STRLENOF( "dn:" ) );
-		AC_MEMCPY( &ctrls[ 0 ]->ldctl_value.bv_val[ STRLENOF( "dn:" ) ],
+		AC_MEMCPY( ctrl->ldctl_value.bv_val, "dn:", STRLENOF( "dn:" ) );
+		AC_MEMCPY( &ctrl->ldctl_value.bv_val[ STRLENOF( "dn:" ) ],
 				assertedID.bv_val, assertedID.bv_len + 1 );
+		rs->sr_err = LDAP_SUCCESS;
 		break;
 	}
 
@@ -2313,7 +2421,7 @@
 	 * this hack provides compatibility with those DSAs that
 	 * implement it this way */
 	if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
-		struct berval		authzID = ctrls[ 0 ]->ldctl_value;
+		struct berval		authzID = ctrl->ldctl_value;
 		BerElementBuffer	berbuf;
 		BerElement		*ber = (BerElement *)&berbuf;
 		ber_tag_t		tag;
@@ -2327,32 +2435,29 @@
 			goto free_ber;
 		}
 
-		if ( ber_flatten2( ber, &ctrls[ 0 ]->ldctl_value, 1 ) == -1 ) {
+		if ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) {
 			rs->sr_err = LDAP_OTHER;
 			goto free_ber;
 		}
 
+		rs->sr_err = LDAP_SUCCESS;
+
 free_ber:;
 		op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
 		ber_free_buf( ber );
 
 		if ( rs->sr_err != LDAP_SUCCESS ) {
-			op->o_tmpfree( ctrls, op->o_tmpmemctx );
-			ctrls = NULL;
 			goto done;
 		}
 
 	} else if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
-		struct berval		authzID = ctrls[ 0 ]->ldctl_value,
+		struct berval		authzID = ctrl->ldctl_value,
 					tmp;
 		BerElementBuffer	berbuf;
 		BerElement		*ber = (BerElement *)&berbuf;
 		ber_tag_t		tag;
 
 		if ( strncasecmp( authzID.bv_val, "dn:", STRLENOF( "dn:" ) ) != 0 ) {
-			op->o_tmpfree( ctrls[ 0 ]->ldctl_value.bv_val, op->o_tmpmemctx );
-			op->o_tmpfree( ctrls, op->o_tmpmemctx );
-			ctrls = NULL;
 			rs->sr_err = LDAP_PROTOCOL_ERROR;
 			goto done;
 		}
@@ -2372,31 +2477,155 @@
 			goto free_ber2;
 		}
 
-		if ( ber_flatten2( ber, &ctrls[ 0 ]->ldctl_value, 1 ) == -1 ) {
+		if ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) {
 			rs->sr_err = LDAP_OTHER;
 			goto free_ber2;
 		}
 
+		ctrl->ldctl_oid = LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ;
+		rs->sr_err = LDAP_SUCCESS;
+
 free_ber2:;
 		op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
 		ber_free_buf( ber );
 
 		if ( rs->sr_err != LDAP_SUCCESS ) {
-			op->o_tmpfree( ctrls, op->o_tmpmemctx );
-			ctrls = NULL;
 			goto done;
 		}
+	}
 
-		ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ;
+done:;
+
+	return rs->sr_err;
+}
+
+/*
+ * Add controls;
+ *
+ * if any needs to be added, it is prepended to existing ones,
+ * in a newly allocated array.  The companion function
+ * ldap_back_controls_free() must be used to restore the original
+ * status of op->o_ctrls.
+ */
+int
+ldap_back_controls_add(
+		Operation	*op,
+		SlapReply	*rs,
+		ldapconn_t	*lc,
+		LDAPControl	***pctrls )
+{
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
+
+	LDAPControl	**ctrls = NULL;
+	/* set to the maximum number of controls this backend can add */
+	LDAPControl	c[ 2 ] = { { 0 } };
+	int		n = 0, i, j1 = 0, j2 = 0;
+
+	*pctrls = NULL;
+
+	rs->sr_err = LDAP_SUCCESS;
+
+	/* don't add controls if protocol is not LDAPv3 */
+	switch ( li->li_version ) {
+	case LDAP_VERSION3:
+		break;
+
+	case 0:
+		if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
+			break;
+		}
+		/* fall thru */
+
+	default:
+		goto done;
 	}
 
+	/* put controls that go __before__ existing ones here */
+
+	/* proxyAuthz for identity assertion */
+	switch ( ldap_back_proxy_authz_ctrl( op, rs, &lc->lc_bound_ndn,
+		li->li_version, &li->li_idassert, &c[ j1 ] ) )
+	{
+	case SLAP_CB_CONTINUE:
+		break;
+
+	case LDAP_SUCCESS:
+		j1++;
+		break;
+
+	default:
+		goto done;
+	}
+
+	/* put controls that go __after__ existing ones here */
+
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+	/* FIXME: according to <draft-wahl-ldap-session>, 
+	 * the server should check if the control can be added
+	 * based on the identity of the client and so */
+
+	/* session tracking */
+	if ( LDAP_BACK_ST_REQUEST( li ) ) {
+		switch ( slap_ctrl_session_tracking_request_add( op, rs, &c[ j1 + j2 ] ) ) {
+		case SLAP_CB_CONTINUE:
+			break;
+
+		case LDAP_SUCCESS:
+			j2++;
+			break;
+
+		default:
+			goto done;
+		}
+	}
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
+	if ( rs->sr_err == SLAP_CB_CONTINUE ) {
+		rs->sr_err = LDAP_SUCCESS;
+	}
+
+	/* if nothing to do, just bail out */
+	if ( j1 == 0 && j2 == 0 ) {
+		goto done;
+	}
+
+	assert( j1 + j1 <= sizeof( c )/sizeof(LDAPControl) );
+
 	if ( op->o_ctrls ) {
+		for ( n = 0; op->o_ctrls[ n ]; n++ )
+			/* just count ctrls */ ;
+	}
+
+	ctrls = op->o_tmpalloc( (n + j1 + j2 + 1) * sizeof( LDAPControl * ) + ( j1 + j2 ) * sizeof( LDAPControl ),
+			op->o_tmpmemctx );
+	if ( j1 ) {
+		ctrls[ 0 ] = (LDAPControl *)&ctrls[ n + j1 + j2 + 1 ];
+		*ctrls[ 0 ] = c[ 0 ];
+		for ( i = 1; i < j1; i++ ) {
+			ctrls[ i ] = &ctrls[ 0 ][ i ];
+			*ctrls[ i ] = c[ i ];
+		}
+	}
+
+	i = 0;
+	if ( op->o_ctrls ) {
 		for ( i = 0; op->o_ctrls[ i ]; i++ ) {
-			ctrls[ i + 1 ] = op->o_ctrls[ i ];
+			ctrls[ i + j1 ] = op->o_ctrls[ i ];
 		}
 	}
-	ctrls[ i + 1 ] = NULL;
 
+	n += j1;
+	if ( j2 ) {
+		ctrls[ n ] = (LDAPControl *)&ctrls[ n + j2 + 1 ] + j1;
+		*ctrls[ n ] = c[ j1 ];
+		for ( i = 1; i < j2; i++ ) {
+			ctrls[ n + i ] = &ctrls[ n ][ i ];
+			*ctrls[ n + i ] = c[ i ];
+		}
+	}
+
+	ctrls[ n + j2 ] = NULL;
+
 done:;
 	if ( ctrls == NULL ) {
 		ctrls = op->o_ctrls;
@@ -2408,20 +2637,41 @@
 }
 
 int
-ldap_back_proxy_authz_ctrl_free( Operation *op, LDAPControl ***pctrls )
+ldap_back_controls_free( Operation *op, SlapReply *rs, LDAPControl ***pctrls )
 {
 	LDAPControl	**ctrls = *pctrls;
 
-	/* we assume that the first control is the proxyAuthz
-	 * added by back-ldap, so it's the only one we explicitly 
-	 * free */
+	/* we assume that the controls added by the proxy come first,
+	 * so as soon as we find op->o_ctrls[ 0 ] we can stop */
 	if ( ctrls && ctrls != op->o_ctrls ) {
+		int		i = 0, n = 0, n_added;
+		LDAPControl	*lower, *upper;
+
 		assert( ctrls[ 0 ] != NULL );
 
-		if ( !BER_BVISNULL( &ctrls[ 0 ]->ldctl_value ) ) {
-			op->o_tmpfree( ctrls[ 0 ]->ldctl_value.bv_val, op->o_tmpmemctx );
+		for ( n = 0; ctrls[ n ] != NULL; n++ )
+			/* count 'em */ ;
+
+		if ( op->o_ctrls ) {
+			for ( i = 0; op->o_ctrls[ i ] != NULL; i++ )
+				/* count 'em */ ;
 		}
 
+		n_added = n - i;
+		lower = (LDAPControl *)&ctrls[ n ];
+		upper = &lower[ n_added ];
+
+		for ( i = 0; ctrls[ i ] != NULL; i++ ) {
+			if ( ctrls[ i ] < lower || ctrls[ i ] >= upper ) {
+				/* original; don't touch */
+				continue;
+			}
+
+			if ( !BER_BVISNULL( &ctrls[ i ]->ldctl_value ) ) {
+				op->o_tmpfree( ctrls[ i ]->ldctl_value.bv_val, op->o_tmpmemctx );
+			}
+		}
+
 		op->o_tmpfree( ctrls, op->o_tmpmemctx );
 	} 
 

Modified: openldap/trunk/servers/slapd/back-ldap/chain.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/chain.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/chain.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* chain.c - chain LDAP operations */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/chain.c,v 1.12.2.24 2007/09/14 22:00:56 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/chain.c,v 1.52.2.6 2007/09/14 21:59:28 ando Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -112,7 +112,7 @@
 static int ldap_chain_db_init_one( BackendDB *be );
 static int ldap_chain_db_open_one( BackendDB *be );
 #define	ldap_chain_db_close_one(be)	(0)
-#define	ldap_chain_db_destroy_one(be)	(lback)->bi_db_destroy( (be) )
+#define	ldap_chain_db_destroy_one(be, rs)	(lback)->bi_db_destroy( (be), (rs) )
 
 typedef struct ldap_chain_cb_t {
 	ldap_chain_status_t	lb_status;
@@ -441,7 +441,7 @@
 	
 		/* parse reference and use 
 		 * proto://[host][:port]/ only */
-		rc = ldap_url_parse_ext( ref->bv_val, &srv );
+		rc = ldap_url_parse_ext( ref->bv_val, &srv, LDAP_PVT_URL_PARSE_NONE );
 		if ( rc != LDAP_URL_SUCCESS ) {
 			/* try next */
 			rc = LDAP_OTHER;
@@ -507,7 +507,7 @@
 			if ( rc != 0 ) {
 				lip->li_uri = NULL;
 				lip->li_bvuri = NULL;
-				(void)ldap_chain_db_destroy_one( op->o_bd );
+				(void)ldap_chain_db_destroy_one( op->o_bd, NULL);
 				goto cleanup;
 			}
 
@@ -546,7 +546,7 @@
 			lip->li_uri = NULL;
 			lip->li_bvuri = NULL;
 			(void)ldap_chain_db_close_one( op->o_bd );
-			(void)ldap_chain_db_destroy_one( op->o_bd );
+			(void)ldap_chain_db_destroy_one( op->o_bd, NULL );
 		}
 
 further_cleanup:;
@@ -628,7 +628,7 @@
 
 		/* parse reference and use
 		 * proto://[host][:port]/ only */
-		rc = ldap_url_parse_ext( ref[0].bv_val, &srv );
+		rc = ldap_url_parse_ext( ref[0].bv_val, &srv, LDAP_PVT_URL_PARSE_NONE );
 		if ( rc != LDAP_URL_SUCCESS ) {
 			/* try next */
 			rs->sr_err = LDAP_OTHER;
@@ -691,7 +691,7 @@
 			if ( rc != 0 ) {
 				lip->li_uri = NULL;
 				lip->li_bvuri = NULL;
-				(void)ldap_chain_db_destroy_one( op->o_bd );
+				(void)ldap_chain_db_destroy_one( op->o_bd, NULL );
 				goto cleanup;
 			}
 
@@ -730,7 +730,7 @@
 			lip->li_uri = NULL;
 			lip->li_bvuri = NULL;
 			(void)ldap_chain_db_close_one( op->o_bd );
-			(void)ldap_chain_db_destroy_one( op->o_bd );
+			(void)ldap_chain_db_destroy_one( op->o_bd, NULL );
 		}
 		
 further_cleanup:;
@@ -838,6 +838,7 @@
 	 */
 
 	db = *op->o_bd;
+	SLAP_DBFLAGS( &db ) &= ~SLAP_DBFLAG_MONITORING;
 	op->o_bd = &db;
 
 	text = rs->sr_text;
@@ -1188,7 +1189,7 @@
 
 done:;
 	if ( rc != LDAP_SUCCESS ) {
-		(void)ldap_chain_db_destroy_one( ca->be );
+		(void)ldap_chain_db_destroy_one( ca->be, NULL );
 		ch_free( ca->be );
 		ca->be = NULL;
 	}
@@ -1213,9 +1214,9 @@
 	struct berval			bv;
 
 	/* FIXME: should not hardcode "olcDatabase" here */
-	bv.bv_len = snprintf( lca->ca->msg, sizeof( lca->ca->msg ),
+	bv.bv_len = snprintf( lca->ca->cr_msg, sizeof( lca->ca->cr_msg ),
 		"olcDatabase={%d}%s", lca->count, lback->bi_type );
-	bv.bv_val = lca->ca->msg;
+	bv.bv_val = lca->ca->cr_msg;
 
 	lca->ca->be->be_private = (void *)li;
 	config_build_entry( lca->op, lca->rs, lca->p->e_private, lca->ca,
@@ -1475,11 +1476,11 @@
 
 	case CH_MAX_DEPTH:
 		if ( c->value_int < 0 ) {
-			snprintf( c->msg, sizeof( c->msg ),
+			snprintf( c->cr_msg, sizeof( c->cr_msg ),
 				"<%s> invalid max referral depth %d",
 				c->argv[0], c->value_int );
 			Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
-				c->log, c->msg, 0 );
+				c->log, c->cr_msg, 0 );
 			rc = 1;
 			break;
 		}
@@ -1502,7 +1503,8 @@
 
 static int
 ldap_chain_db_init(
-	BackendDB *be )
+	BackendDB *be,
+	ConfigReply *cr )
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
 	ldap_chain_t	*lc = NULL;
@@ -1633,7 +1635,7 @@
 
 				db.bd_info = lback;
 				db.be_private = (void *)lc->lc_cfg_li;
-				ldap_chain_db_destroy_one( &db );
+				ldap_chain_db_destroy_one( &db, NULL );
 				lc->lc_cfg_li = NULL;
 
 			} else {
@@ -1686,7 +1688,7 @@
 
 	lca->be->be_private = (void *)li;
 
-	return lca->func( lca->be );
+	return lca->func( lca->be, NULL );
 }
 
 static int
@@ -1709,7 +1711,7 @@
 			db.bd_info = lback;
 			db.be_private = lc->lc_common_li;
 
-			rc = func( &db );
+			rc = func( &db, NULL );
 
 			if ( rc != 0 ) {
 				return rc;
@@ -1733,10 +1735,12 @@
 
 static int
 ldap_chain_db_open(
-	BackendDB	*be )
+	BackendDB	*be,
+	ConfigReply	*cr )
 {
 	slap_overinst	*on = (slap_overinst *) be->bd_info;
 	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
+	slap_mask_t	monitoring;
 	int		rc = 0;
 
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
@@ -1754,21 +1758,26 @@
 	}
 
 	/* filter out and restore monitoring */
+	monitoring = ( SLAP_DBFLAGS( be ) & SLAP_DBFLAG_MONITORING );
+	SLAP_DBFLAGS( be ) &= ~SLAP_DBFLAG_MONITORING;
 	rc = ldap_chain_db_func( be, db_open );
+	SLAP_DBFLAGS( be ) |= monitoring;
 
 	return rc;
 }
 
 static int
 ldap_chain_db_close(
-	BackendDB	*be )
+	BackendDB	*be,
+	ConfigReply	*cr )
 {
 	return ldap_chain_db_func( be, db_close );
 }
 
 static int
 ldap_chain_db_destroy(
-	BackendDB	*be )
+	BackendDB	*be,
+	ConfigReply	*cr )
 {
 	slap_overinst	*on = (slap_overinst *) be->bd_info;
 	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
@@ -1800,11 +1809,13 @@
 
 	be->bd_info = lback;
 	be->be_private = NULL;
-	rc = lback->bi_db_init( be );
+	rc = lback->bi_db_init( be, NULL );
 	if ( rc != 0 ) {
 		return rc;
 	}
 	li = (ldapinfo_t *)be->be_private;
+	li->li_urllist_f = NULL;
+	li->li_urllist_p = NULL;
 
 	be->bd_info = bi;
 
@@ -1833,11 +1844,13 @@
 
 	be->bd_info = lback;
 	be->be_private = NULL;
-	t = lback->bi_db_init( be );
+	t = lback->bi_db_init( be, NULL );
 	if ( t != 0 ) {
 		return t;
 	}
 	li = (ldapinfo_t *)be->be_private;
+	li->li_urllist_f = NULL;
+	li->li_urllist_p = NULL;
 
 	/* copy common data */
 	li->li_nretries = lc->lc_common_li->li_nretries;
@@ -1855,7 +1868,27 @@
 ldap_chain_db_open_one(
 	BackendDB	*be )
 {
-	return lback->bi_db_open( be );
+	if ( SLAP_DBMONITORING( be ) ) {
+		ldapinfo_t	*li = (ldapinfo_t *)be->be_private;
+
+		if ( li->li_uri == NULL ) {
+			ber_str2bv( "cn=Common Connections", 0, 1,
+				&li->li_monitor_info.lmi_rdn );
+
+		} else {
+			char		*ptr;
+
+			li->li_monitor_info.lmi_rdn.bv_len
+				= STRLENOF( "cn=" ) + strlen( li->li_uri );
+			ptr = li->li_monitor_info.lmi_rdn.bv_val
+				= ch_malloc( li->li_monitor_info.lmi_rdn.bv_len + 1 );
+			ptr = lutil_strcopy( ptr, "cn=" );
+			ptr = lutil_strcopy( ptr, li->li_uri );
+			ptr[ 0 ] = '\0';
+		}
+	}
+
+	return lback->bi_db_open( be, NULL );
 }
 
 typedef struct ldap_chain_conn_apply_t {
@@ -2026,10 +2059,8 @@
 }
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
-static slap_overinst ldapchain;
-
 int
-chain_init( void )
+chain_initialize( void )
 {
 	int	rc;
 

Modified: openldap/trunk/servers/slapd/back-ldap/compare.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* compare.c - ldap backend compare function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/compare.c,v 1.52.2.11 2007/01/13 11:19:06 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/compare.c,v 1.60.2.4 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -51,8 +51,7 @@
 
 retry:
 	ctrls = op->o_ctrls;
-	rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-		li->li_version, &li->li_idassert, op, rs, &ctrls );
+	rc = ldap_back_controls_add( op, rs, lc, &ctrls );
 	if ( rc != LDAP_SUCCESS ) {
 		send_ldap_result( op, rs );
 		goto cleanup;
@@ -69,13 +68,13 @@
 		retrying &= ~LDAP_BACK_RETRYING;
 		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 	
 	if ( lc != NULL ) {
 		ldap_back_release_conn( li, lc );

Modified: openldap/trunk/servers/slapd/back-ldap/config.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* config.c - ldap backend configuration file routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/config.c,v 1.73.2.24 2007/01/27 23:56:43 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/config.c,v 1.115.2.7 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -69,6 +69,7 @@
 	LDAP_BACK_CFG_CONNPOOLMAX,
 	LDAP_BACK_CFG_CANCEL,
 	LDAP_BACK_CFG_QUARANTINE,
+	LDAP_BACK_CFG_ST_REQUEST,
 	LDAP_BACK_CFG_REWRITE,
 
 	LDAP_BACK_CFG_LAST
@@ -83,7 +84,7 @@
 			"SYNTAX OMsDirectoryString "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "tls", "what", 2, 2, 0,
+	{ "tls", "what", 2, 0, 0,
 		ARG_MAGIC|LDAP_BACK_CFG_TLS,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.1 "
 			"NAME 'olcDbStartTLS' "
@@ -183,7 +184,7 @@
 			"SYNTAX OMsDirectoryString "
 			"X-ORDERED 'VALUES' )",
 		NULL, NULL },
-	{ "rebind-as-user", "NO|yes", 1, 2, 0,
+	{ "rebind-as-user", "true|FALSE", 1, 2, 0,
 		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_REBIND,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.10 "
 			"NAME 'olcDbRebindAsUser' "
@@ -191,7 +192,7 @@
 			"SYNTAX OMsBoolean "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "chase-referrals", "YES|no", 2, 2, 0,
+	{ "chase-referrals", "true|FALSE", 2, 2, 0,
 		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_CHASE,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.11 "
 			"NAME 'olcDbChaseReferrals' "
@@ -199,7 +200,7 @@
 			"SYNTAX OMsBoolean "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "t-f-support", "NO|yes|discover", 2, 2, 0,
+	{ "t-f-support", "true|FALSE|discover", 2, 2, 0,
 		ARG_MAGIC|LDAP_BACK_CFG_T_F,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.12 "
 			"NAME 'olcDbTFSupport' "
@@ -207,7 +208,7 @@
 			"SYNTAX OMsDirectoryString "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "proxy-whoami", "NO|yes", 1, 2, 0,
+	{ "proxy-whoami", "true|FALSE", 1, 2, 0,
 		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_WHOAMI,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.13 "
 			"NAME 'olcDbProxyWhoAmI' "
@@ -223,7 +224,7 @@
 			"SYNTAX OMsDirectoryString "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "idle-timeout", "timeout", 2, 0, 0,
+	{ "idle-timeout", "timeout", 2, 2, 0,
 		ARG_MAGIC|LDAP_BACK_CFG_IDLE_TIMEOUT,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.15 "
 			"NAME 'olcDbIdleTimeout' "
@@ -231,7 +232,7 @@
 			"SYNTAX OMsDirectoryString "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "conn-ttl", "ttl", 2, 0, 0,
+	{ "conn-ttl", "ttl", 2, 2, 0,
 		ARG_MAGIC|LDAP_BACK_CFG_CONN_TTL,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.16 "
 			"NAME 'olcDbConnTtl' "
@@ -239,7 +240,7 @@
 			"SYNTAX OMsDirectoryString "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "network-timeout", "timeout", 2, 0, 0,
+	{ "network-timeout", "timeout", 2, 2, 0,
 		ARG_MAGIC|LDAP_BACK_CFG_NETWORK_TIMEOUT,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.17 "
 			"NAME 'olcDbNetworkTimeout' "
@@ -247,7 +248,7 @@
 			"SYNTAX OMsDirectoryString "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "protocol-version", "version", 2, 0, 0,
+	{ "protocol-version", "version", 2, 2, 0,
 		ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_VERSION,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.18 "
 			"NAME 'olcDbProtocolVersion' "
@@ -255,7 +256,7 @@
 			"SYNTAX OMsInteger "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "single-conn", "TRUE/FALSE", 2, 0, 0,
+	{ "single-conn", "true|FALSE", 2, 2, 0,
 		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_SINGLECONN,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.19 "
 			"NAME 'olcDbSingleConn' "
@@ -263,7 +264,7 @@
 			"SYNTAX OMsBoolean "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "cancel", "ABANDON|ignore|exop", 2, 0, 0,
+	{ "cancel", "ABANDON|ignore|exop", 2, 2, 0,
 		ARG_MAGIC|LDAP_BACK_CFG_CANCEL,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.20 "
 			"NAME 'olcDbCancel' "
@@ -271,7 +272,7 @@
 			"SYNTAX OMsDirectoryString "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "quarantine", "retrylist", 2, 0, 0,
+	{ "quarantine", "retrylist", 2, 2, 0,
 		ARG_MAGIC|LDAP_BACK_CFG_QUARANTINE,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.21 "
 			"NAME 'olcDbQuarantine' "
@@ -279,7 +280,7 @@
 			"SYNTAX OMsDirectoryString "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "use-temporary-conn", "TRUE/FALSE", 2, 0, 0,
+	{ "use-temporary-conn", "true|FALSE", 2, 2, 0,
 		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_USETEMP,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.22 "
 			"NAME 'olcDbUseTemporaryConn' "
@@ -287,7 +288,7 @@
 			"SYNTAX OMsBoolean "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "conn-pool-max", "<n>", 2, 0, 0,
+	{ "conn-pool-max", "<n>", 2, 2, 0,
 		ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_CONNPOOLMAX,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.23 "
 			"NAME 'olcDbConnectionPoolMax' "
@@ -295,6 +296,16 @@
 			"SYNTAX OMsInteger "
 			"SINGLE-VALUE )",
 		NULL, NULL },
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+	{ "session-tracking-request", "true|FALSE", 2, 2, 0,
+		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_ST_REQUEST,
+		ldap_back_cf_gen, "( OLcfgDbAt:3.24 "
+			"NAME 'olcDbSessionTrackingRequest' "
+			"DESC 'Add session tracking control to proxied requests' "
+			"SYNTAX OMsBoolean "
+			"SINGLE-VALUE )",
+		NULL, NULL },
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
 	{ "suffixmassage", "[virtual]> <real", 2, 3, 0,
 		ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
 		ldap_back_cf_gen, NULL, NULL, NULL },
@@ -352,6 +363,7 @@
 	{ BER_BVC( "try-propagate" ),	LDAP_BACK_F_PROPAGATE_TLS },
 	{ BER_BVC( "start" ),		LDAP_BACK_F_TLS_USE_MASK },
 	{ BER_BVC( "try-start" ),	LDAP_BACK_F_USE_TLS },
+	{ BER_BVC( "ldaps" ),		LDAP_BACK_F_TLS_LDAPS },
 	{ BER_BVC( "none" ),		LDAP_BACK_F_NONE },
 	{ BER_BVNULL,			0 }
 };
@@ -364,9 +376,7 @@
 };
 
 static slap_verbmasks cancel_mode[] = {
-#if 0	/* needs ldap_int_discard(), 2.4 */
 	{ BER_BVC( "ignore" ),		LDAP_BACK_F_CANCEL_IGNORE },
-#endif
 	{ BER_BVC( "exop" ),		LDAP_BACK_F_CANCEL_EXOP },
 	{ BER_BVC( "exop-discover" ),	LDAP_BACK_F_CANCEL_EXOP_DISCOVER },
 	{ BER_BVC( "abandon" ),		LDAP_BACK_F_CANCEL_ABANDON },
@@ -547,17 +557,19 @@
 slap_idassert_authzfrom_parse( ConfigArgs *c, slap_idassert_t *si )
 {
 	struct berval	bv;
+	struct berval	in;
+	int		rc;
 
  	if ( strcmp( c->argv[ 1 ], "*" ) == 0
  		|| strcmp( c->argv[ 1 ], "dn:*" ) == 0
  		|| strcasecmp( c->argv[ 1 ], "dn.regex:.*" ) == 0 )
  	{
  		if ( si->si_authz != NULL ) {
- 			snprintf( c->msg, sizeof( c->msg ),
+ 			snprintf( c->cr_msg, sizeof( c->cr_msg ),
  				"\"idassert-authzFrom <authz>\": "
  				"\"%s\" conflicts with existing authz rules",
  				c->argv[ 1 ] );
- 			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+ 			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
  			return 1;
  		}
  
@@ -566,32 +578,23 @@
  		return 0;
  
  	} else if ( ( si->si_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) {
-  		snprintf( c->msg, sizeof( c->msg ),
+  		snprintf( c->cr_msg, sizeof( c->cr_msg ),
   			"\"idassert-authzFrom <authz>\": "
  			"\"<authz>\" conflicts with \"*\"" );
-  		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+  		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
   		return 1;
   	}
-
-#ifdef SLAP_AUTHZ_SYNTAX
-	{
-		struct berval	in;
-		int		rc;
-
-		ber_str2bv( c->argv[ 1 ], 0, 0, &in );
-		rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
-		if ( rc != LDAP_SUCCESS ) {
-			snprintf( c->msg, sizeof( c->msg ),
-				"\"idassert-authzFrom <authz>\": "
-				"invalid syntax" );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
-			return 1;
-		}
-	}
-#else /* !SLAP_AUTHZ_SYNTAX */
-	ber_str2bv( c->argv[ 1 ], 0, 1, &bv );
-#endif /* !SLAP_AUTHZ_SYNTAX */
-
+ 	
+ 	ber_str2bv( c->argv[ 1 ], 0, 0, &in );
+ 	rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
+ 	if ( rc != LDAP_SUCCESS ) {
+ 		snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ 			"\"idassert-authzFrom <authz>\": "
+ 			"invalid syntax" );
+ 		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
+ 		return 1;
+ 	}
+  
 	ber_bvarray_add( &si->si_authz, &bv );
 
 	return 0;
@@ -609,11 +612,11 @@
 
 			j = verb_to_mask( argvi, idassert_mode );
 			if ( BER_BVISNULL( &idassert_mode[ j ].word ) ) {
-				snprintf( c->msg, sizeof( c->msg ),
+				snprintf( c->cr_msg, sizeof( c->cr_msg ),
 					"\"idassert-bind <args>\": "
 					"unknown mode \"%s\"",
 					argvi );
-				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 				return 1;
 			}
 
@@ -624,11 +627,11 @@
 
 			if ( strcasecmp( argvi, "native" ) == 0 ) {
 				if ( si->si_bc.sb_method != LDAP_AUTH_SASL ) {
-					snprintf( c->msg, sizeof( c->msg ),
+					snprintf( c->cr_msg, sizeof( c->cr_msg ),
 						"\"idassert-bind <args>\": "
 						"authz=\"native\" incompatible "
 						"with auth method" );
-					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 					return 1;
 				}
 				si->si_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
@@ -637,11 +640,11 @@
 				si->si_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
 
 			} else {
-				snprintf( c->msg, sizeof( c->msg ),
+				snprintf( c->cr_msg, sizeof( c->cr_msg ),
 					"\"idassert-bind <args>\": "
 					"unknown authz \"%s\"",
 					argvi );
-				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 				return 1;
 			}
 
@@ -651,11 +654,11 @@
 			int	j, err = 0;
 
 			if ( flags == NULL ) {
-				snprintf( c->msg, sizeof( c->msg ),
+				snprintf( c->cr_msg, sizeof( c->cr_msg ),
 					"\"idassert-bind <args>\": "
 					"unable to parse flags \"%s\"",
 					argvi );
-				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 				return 1;
 			}
 
@@ -699,11 +702,11 @@
 					}
 
 				} else {
-					snprintf( c->msg, sizeof( c->msg ),
+					snprintf( c->cr_msg, sizeof( c->cr_msg ),
 						"\"idassert-bind <args>\": "
 						"unknown flag \"%s\"",
 						flags[ j ] );
-					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 					err = 1;
 					break;
 				}
@@ -718,6 +721,7 @@
 			return 1;
 		}
 	}
+	bindconf_tls_defaults( &si->si_bc );
 
 	return 0;
 }
@@ -782,10 +786,25 @@
 			}
 			break;
 
-		case LDAP_BACK_CFG_TLS:
+		case LDAP_BACK_CFG_TLS: {
+			struct berval bc = BER_BVNULL, bv2;
 			enum_to_verb( tls_mode, ( li->li_flags & LDAP_BACK_F_TLS_MASK ), &bv );
 			assert( !BER_BVISNULL( &bv ) );
-			value_add_one( &c->rvalue_vals, &bv );
+			bindconf_tls_unparse( &li->li_tls, &bc );
+
+			if ( !BER_BVISEMPTY( &bc )) {
+				bv2.bv_len = bv.bv_len + bc.bv_len + 1;
+				bv2.bv_val = ch_malloc( bv2.bv_len + 1 );
+				strcpy( bv2.bv_val, bv.bv_val );
+				bv2.bv_val[bv.bv_len] = ' ';
+				strcpy( &bv2.bv_val[bv.bv_len + 1], bc.bv_val );
+				ber_bvarray_add( &c->rvalue_vals, &bv2 );
+
+			} else {
+				value_add_one( &c->rvalue_vals, &bv );
+			}
+			ber_memfree( bc.bv_val );
+			}
 			break;
 
 		case LDAP_BACK_CFG_ACL_AUTHCDN:
@@ -1109,6 +1128,12 @@
 			}
 			break;
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+		case LDAP_BACK_CFG_ST_REQUEST:
+			c->value_int = LDAP_BACK_ST_REQUEST( li );
+			break;
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
 		default:
 			/* FIXME: we need to handle all... */
 			assert( 0 );
@@ -1225,6 +1250,12 @@
 			li->li_flags &= ~LDAP_BACK_F_QUARANTINE;
 			break;
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+		case LDAP_BACK_CFG_ST_REQUEST:
+			li->li_flags &= ~LDAP_BACK_F_ST_REQUEST;
+			break;
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
 		default:
 			/* FIXME: we need to handle all... */
 			assert( 0 );
@@ -1250,7 +1281,7 @@
 		}
 
 		/* PARANOID: DN and more are not required nor allowed */
-		urlrc = ldap_url_parselist_ext( &lud, c->argv[ 1 ], ", \t" );
+		urlrc = ldap_url_parselist_ext( &lud, c->argv[ 1 ], ", \t", LDAP_PVT_URL_PARSE_NONE );
 		if ( urlrc != LDAP_URL_SUCCESS ) {
 			char	*why;
 
@@ -1289,11 +1320,11 @@
 				why = "unknown reason";
 				break;
 			}
-			snprintf( c->msg, sizeof( c->msg),
+			snprintf( c->cr_msg, sizeof( c->cr_msg),
 					"unable to parse uri \"%s\" "
 					"in \"uri <uri>\" line: %s",
 					c->value_string, why );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			urlrc = 1;
 			goto done_url;
 		}
@@ -1309,13 +1340,13 @@
 					|| tmpludp->lud_filter != NULL
 					|| tmpludp->lud_exts != NULL )
 			{
-				snprintf( c->msg, sizeof( c->msg ),
+				snprintf( c->cr_msg, sizeof( c->cr_msg ),
 						"warning, only protocol, "
 						"host and port allowed "
 						"in \"uri <uri>\" statement "
 						"for uri #%d of \"%s\"",
 						i, c->argv[ 1 ] );
-				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			}
 		}
 
@@ -1344,12 +1375,12 @@
 			urllist[ i ]  = ldap_url_desc2str( &tmplud );
 
 			if ( urllist[ i ] == NULL ) {
-				snprintf( c->msg, sizeof( c->msg),
+				snprintf( c->cr_msg, sizeof( c->cr_msg),
 					"unable to rebuild uri "
 					"in \"uri <uri>\" statement "
 					"for \"%s\"",
 					c->argv[ 1 ] );
-				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 				urlrc = 1;
 				goto done_url;
 			}
@@ -1386,6 +1417,13 @@
 		}
 		li->li_flags &= ~LDAP_BACK_F_TLS_MASK;
 		li->li_flags |= tls_mode[i].mask;
+		if ( c->argc > 2 ) {
+			for ( i=2; i<c->argc; i++ ) {
+				if ( bindconf_tls_parse( c->argv[i], &li->li_tls ))
+					return 1;
+			}
+			bindconf_tls_defaults( &li->li_tls );
+		}
 		break;
 
 	case LDAP_BACK_CFG_ACL_AUTHCDN:
@@ -1398,11 +1436,11 @@
 			break;
 
 		default:
-			snprintf( c->msg, sizeof( c->msg),
+			snprintf( c->cr_msg, sizeof( c->cr_msg),
 				"\"acl-authcDN <DN>\" incompatible "
 				"with auth method %d",
 				li->li_acl_authmethod );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 		if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) {
@@ -1424,11 +1462,11 @@
 			break;
 
 		default:
-			snprintf( c->msg, sizeof( c->msg ),
+			snprintf( c->cr_msg, sizeof( c->cr_msg ),
 				"\"acl-passwd <cred>\" incompatible "
 				"with auth method %d",
 				li->li_acl_authmethod );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 		if ( !BER_BVISNULL( &li->li_acl_passwd ) ) {
@@ -1444,6 +1482,7 @@
 				return 1;
 			}
 		}
+		bindconf_tls_defaults( &li->li_acl );
 		break;
 
 	case LDAP_BACK_CFG_IDASSERT_MODE:
@@ -1542,11 +1581,11 @@
 			break;
 
 		default:
-			snprintf( c->msg, sizeof( c->msg ),
+			snprintf( c->cr_msg, sizeof( c->cr_msg ),
 				"\"idassert-authcDN <DN>\" incompatible "
 				"with auth method %d",
 				li->li_idassert_authmethod );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 		if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) {
@@ -1568,11 +1607,11 @@
 			break;
 
 		default:
-			snprintf( c->msg, sizeof( c->msg ),
+			snprintf( c->cr_msg, sizeof( c->cr_msg ),
 				"\"idassert-passwd <cred>\" incompatible "
 				"with auth method %d",
 				li->li_idassert_authmethod );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 		if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) {
@@ -1587,10 +1626,10 @@
 
 	case LDAP_BACK_CFG_IDASSERT_METHOD:
 		/* no longer supported */
-		snprintf( c->msg, sizeof( c->msg ),
+		snprintf( c->cr_msg, sizeof( c->cr_msg ),
 			"\"idassert-method <args>\": "
 			"no longer supported; use \"idassert-bind\"" );
-		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 		return 1;
 
 	case LDAP_BACK_CFG_IDASSERT_BIND:
@@ -1629,17 +1668,23 @@
 			&& mask == LDAP_BACK_F_T_F_DISCOVER
 			&& !LDAP_BACK_T_F( li ) )
 		{
+			slap_bindconf	sb = { BER_BVNULL };
 			int		rc;
 
 			if ( li->li_uri == NULL ) {
-				snprintf( c->msg, sizeof( c->msg ),
-					"need URI to discover \"cancel\" support "
-					"in \"cancel exop-discover\"" );
-				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				snprintf( c->cr_msg, sizeof( c->cr_msg ),
+					"need URI to discover absolute filters support "
+					"in \"t-f-support discover\"" );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 				return 1;
 			}
 
-			rc = slap_discover_feature( li->li_uri, li->li_version,
+			ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri );
+			sb.sb_version = li->li_version;
+			sb.sb_method = LDAP_AUTH_SIMPLE;
+			BER_BVSTR( &sb.sb_binddn, "" );
+
+			rc = slap_discover_feature( &sb,
 					slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
 					LDAP_FEATURE_ABSOLUTE_FILTERS );
 			if ( rc == LDAP_COMPARE_TRUE ) {
@@ -1669,10 +1714,10 @@
 				unsigned	u;
 
 				if ( lutil_atoux( &u, c->argv[ i ], 0 ) != 0 ) {
-					snprintf( c->msg, sizeof( c->msg),
+					snprintf( c->cr_msg, sizeof( c->cr_msg),
 						"unable to parse timeout \"%s\"",
 						c->argv[ i ] );
-					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 					return 1;
 				}
 
@@ -1684,10 +1729,10 @@
 			}
 
 			if ( slap_cf_aux_table_parse( c->argv[ i ], li->li_timeout, timeout_table, "slapd-ldap timeout" ) ) {
-				snprintf( c->msg, sizeof( c->msg),
+				snprintf( c->cr_msg, sizeof( c->cr_msg),
 					"unable to parse timeout \"%s\"",
 					c->argv[ i ] );
-				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 				return 1;
 			}
 		}
@@ -1697,10 +1742,10 @@
 		unsigned long	t;
 
 		if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
-			snprintf( c->msg, sizeof( c->msg),
+			snprintf( c->cr_msg, sizeof( c->cr_msg),
 				"unable to parse idle timeout \"%s\"",
 				c->argv[ 1 ] );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 		li->li_idle_timeout = (time_t)t;
@@ -1710,10 +1755,10 @@
 		unsigned long	t;
 
 		if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
-			snprintf( c->msg, sizeof( c->msg),
+			snprintf( c->cr_msg, sizeof( c->cr_msg),
 				"unable to parse conn ttl\"%s\"",
 				c->argv[ 1 ] );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 		li->li_conn_ttl = (time_t)t;
@@ -1723,10 +1768,10 @@
 		unsigned long	t;
 
 		if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
-			snprintf( c->msg, sizeof( c->msg),
+			snprintf( c->cr_msg, sizeof( c->cr_msg),
 				"unable to parse network timeout \"%s\"",
 				c->argv[ 1 ] );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 		li->li_network_timeout = (time_t)t;
@@ -1734,11 +1779,11 @@
 
 	case LDAP_BACK_CFG_VERSION:
 		if ( c->value_int != 0 && ( c->value_int < LDAP_VERSION_MIN || c->value_int > LDAP_VERSION_MAX ) ) {
-			snprintf( c->msg, sizeof( c->msg ),
+			snprintf( c->cr_msg, sizeof( c->cr_msg ),
 				"unsupported version \"%s\" "
 				"in \"protocol-version <version>\"",
 				c->argv[ 1 ] );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 
@@ -1767,7 +1812,7 @@
 		if ( c->value_int < LDAP_BACK_CONN_PRIV_MIN
 			|| c->value_int > LDAP_BACK_CONN_PRIV_MAX )
 		{
-			snprintf( c->msg, sizeof( c->msg ),
+			snprintf( c->cr_msg, sizeof( c->cr_msg ),
 				"invalid max size " "of privileged "
 				"connections pool \"%s\" "
 				"in \"conn-pool-max <n> "
@@ -1775,7 +1820,7 @@
 				c->argv[ 1 ],
 				LDAP_BACK_CONN_PRIV_MIN,
 				LDAP_BACK_CONN_PRIV_MAX );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 		li->li_conn_priv_max = c->value_int;
@@ -1795,17 +1840,23 @@
 			&& mask == LDAP_BACK_F_CANCEL_EXOP_DISCOVER
 			&& !LDAP_BACK_CANCEL( li ) )
 		{
+			slap_bindconf	sb = { BER_BVNULL };
 			int		rc;
 
 			if ( li->li_uri == NULL ) {
-				snprintf( c->msg, sizeof( c->msg ),
+				snprintf( c->cr_msg, sizeof( c->cr_msg ),
 					"need URI to discover \"cancel\" support "
 					"in \"cancel exop-discover\"" );
-				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 				return 1;
 			}
 
-			rc = slap_discover_feature( li->li_uri, li->li_version,
+			ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri );
+			sb.sb_version = li->li_version;
+			sb.sb_method = LDAP_AUTH_SIMPLE;
+			BER_BVSTR( &sb.sb_binddn, "" );
+
+			rc = slap_discover_feature( &sb,
 					slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
 					LDAP_EXOP_CANCEL );
 			if ( rc == LDAP_COMPARE_TRUE ) {
@@ -1819,15 +1870,15 @@
 
 	case LDAP_BACK_CFG_QUARANTINE:
 		if ( LDAP_BACK_QUARANTINE( li ) ) {
-			snprintf( c->msg, sizeof( c->msg ),
+			snprintf( c->cr_msg, sizeof( c->cr_msg ),
 				"quarantine already defined" );
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 			return 1;
 		}
 		rc = slap_retry_info_parse( c->argv[1], &li->li_quarantine,
-			c->msg, sizeof( c->msg ) );
+			c->cr_msg, sizeof( c->cr_msg ) );
 		if ( rc ) {
-			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 
 		} else {
 			ldap_pvt_thread_mutex_init( &li->li_quarantine_mutex );
@@ -1838,13 +1889,24 @@
 		}
 		break;
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+	case LDAP_BACK_CFG_ST_REQUEST:
+		if ( c->value_int ) {
+			li->li_flags |= LDAP_BACK_F_ST_REQUEST;
+
+		} else {
+			li->li_flags &= ~LDAP_BACK_F_ST_REQUEST;
+		}
+		break;
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
 	case LDAP_BACK_CFG_REWRITE:
-		snprintf( c->msg, sizeof( c->msg ),
+		snprintf( c->cr_msg, sizeof( c->cr_msg ),
 			"rewrite/remap capabilities have been moved "
 			"to the \"rwm\" overlay; see slapo-rwm(5) "
 			"for details (hint: add \"overlay rwm\" "
 			"and prefix all directives with \"rwm-\")" );
-		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
 		return 1;
 		
 	default:

Modified: openldap/trunk/servers/slapd/back-ldap/delete.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/delete.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/delete.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* delete.c - ldap backend delete function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/delete.c,v 1.37.2.13 2007/01/17 20:57:10 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/delete.c,v 1.46.2.4 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -50,8 +50,7 @@
 
 retry:
 	ctrls = op->o_ctrls;
-	rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-		li->li_version, &li->li_idassert, op, rs, &ctrls );
+	rc = ldap_back_controls_add( op, rs, lc, &ctrls );
 	if ( rc != LDAP_SUCCESS ) {
 		send_ldap_result( op, rs );
 		rc = rs->sr_err;
@@ -67,13 +66,13 @@
 		retrying &= ~LDAP_BACK_RETRYING;
 		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	if ( lc != NULL ) {
 		ldap_back_release_conn( li, lc );

Copied: openldap/trunk/servers/slapd/back-ldap/distproc.c (from rev 891, openldap/vendor/openldap-2.4.7/servers/slapd/back-ldap/distproc.c)
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/distproc.c	                        (rev 0)
+++ openldap/trunk/servers/slapd/back-ldap/distproc.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,1017 @@
+/* distproc.c - implement distributed procedures */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/distproc.c,v 1.3.2.5 2007/08/31 23:14:02 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2005-2007 The OpenLDAP Foundation.
+ * Portions Copyright 2003 Howard Chu.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Pierangelo Masarati for inclusion
+ * in OpenLDAP Software.
+ * Based on back-ldap and slapo-chain, developed by Howard Chu
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+
+#ifdef SLAP_DISTPROC
+
+#include "back-ldap.h"
+
+#include "config.h"
+
+/*
+ * From <draft-sermersheim-ldap-distproc>
+ *
+
+      ContinuationReference ::= SET {
+         referralURI      [0] SET SIZE (1..MAX) OF URI,
+         localReference   [2] LDAPDN,
+         referenceType    [3] ReferenceType,
+         remainingName    [4] RelativeLDAPDN OPTIONAL,
+         searchScope      [5] SearchScope OPTIONAL,
+         searchedSubtrees [6] SearchedSubtrees OPTIONAL,
+         failedName       [7] LDAPDN OPTIONAL,
+         ...  }
+
+      ReferenceType ::= ENUMERATED {
+         superior               (0),
+         subordinate            (1),
+         cross                  (2),
+         nonSpecificSubordinate (3),
+         supplier               (4),
+         master                 (5),
+         immediateSuperior      (6),
+         self                   (7),
+         ...  }
+
+      SearchScope ::= ENUMERATED {
+         baseObject         (0),
+         singleLevel        (1),
+         wholeSubtree       (2),
+         subordinateSubtree (3),
+         ...  }
+
+   SearchedSubtrees ::= SET OF RelativeLDAPDN
+
+   LDAPDN, RelativeLDAPDN, and LDAPString, are defined in [RFC2251].
+
+ */
+
+typedef enum ReferenceType_t {
+	LDAP_DP_RT_UNKNOWN			= -1,
+	LDAP_DP_RT_SUPERIOR			= 0,
+	LDAP_DP_RT_SUBORDINATE			= 1,
+	LDAP_DP_RT_CROSS			= 2,
+	LDAP_DP_RT_NONSPECIFICSUBORDINATE	= 3,
+	LDAP_DP_RT_SUPPLIER			= 4,
+	LDAP_DP_RT_MASTER			= 5,
+	LDAP_DP_RT_IMMEDIATESUPERIOR		= 6,
+	LDAP_DP_RT_SELF				= 7,
+	LDAP_DP_RT_LAST
+} ReferenceType_t;
+
+typedef enum SearchScope_t {
+	LDAP_DP_SS_UNKNOWN			= -1,
+	LDAP_DP_SS_BASEOBJECT			= 0,
+	LDAP_DP_SS_SINGLELEVEL			= 1,
+	LDAP_DP_SS_WHOLESUBTREE			= 2,
+	LDAP_DP_SS_SUBORDINATESUBTREE		= 3,
+	LDAP_DP_SS_LAST
+} SearchScope_t;
+
+typedef struct ContinuationReference_t {
+	BerVarray		cr_referralURI;
+	/* ?			[1] ? */
+	struct berval		cr_localReference;
+	ReferenceType_t		cr_referenceType;
+	struct berval		cr_remainingName;
+	SearchScope_t		cr_searchScope;
+	BerVarray		cr_searchedSubtrees;
+	struct berval		cr_failedName;
+} ContinuationReference_t;
+#define	CR_INIT		{ NULL, BER_BVNULL, LDAP_DP_RT_UNKNOWN, BER_BVNULL, LDAP_DP_SS_UNKNOWN, NULL, BER_BVNULL }
+
+static struct berval	bv2rt[] = {
+	BER_BVC( "superior" ),
+	BER_BVC( "subordinate" ),
+	BER_BVC( "cross" ),
+	BER_BVC( "nonSpecificSubordinate" ),
+	BER_BVC( "supplier" ),
+	BER_BVC( "master" ),
+	BER_BVC( "immediateSuperior" ),
+	BER_BVC( "self" ),
+	BER_BVNULL
+};
+
+static struct berval	bv2ss[] = {
+	BER_BVC( "baseObject" ),
+	BER_BVC( "singleLevel" ),
+	BER_BVC( "wholeSubtree" ),
+	BER_BVC( "subordinateSubtree" ),
+	BER_BVNULL
+};
+
+static struct berval *
+ldap_distproc_rt2bv( ReferenceType_t rt )
+{
+	return &bv2rt[ rt ];
+}
+
+static const char *
+ldap_distproc_rt2str( ReferenceType_t rt )
+{
+	return bv2rt[ rt ].bv_val;
+}
+
+static ReferenceType_t
+ldap_distproc_bv2rt( struct berval *bv )
+{
+	ReferenceType_t		rt;
+
+	for ( rt = 0; !BER_BVISNULL( &bv2rt[ rt ] ); rt++ ) {
+		if ( ber_bvstrcasecmp( bv, &bv2rt[ rt ] ) == 0 ) {
+			return rt;
+		}
+	}
+
+	return LDAP_DP_RT_UNKNOWN;
+}
+
+static ReferenceType_t
+ldap_distproc_str2rt( const char *s )
+{
+	struct berval	bv;
+
+	ber_str2bv( s, 0, 0, &bv );
+	return ldap_distproc_bv2rt( &bv );
+}
+
+static struct berval *
+ldap_distproc_ss2bv( SearchScope_t ss )
+{
+	return &bv2ss[ ss ];
+}
+
+static const char *
+ldap_distproc_ss2str( SearchScope_t ss )
+{
+	return bv2ss[ ss ].bv_val;
+}
+
+static SearchScope_t
+ldap_distproc_bv2ss( struct berval *bv )
+{
+	ReferenceType_t		ss;
+
+	for ( ss = 0; !BER_BVISNULL( &bv2ss[ ss ] ); ss++ ) {
+		if ( ber_bvstrcasecmp( bv, &bv2ss[ ss ] ) == 0 ) {
+			return ss;
+		}
+	}
+
+	return LDAP_DP_SS_UNKNOWN;
+}
+
+static SearchScope_t
+ldap_distproc_str2ss( const char *s )
+{
+	struct berval	bv;
+
+	ber_str2bv( s, 0, 0, &bv );
+	return ldap_distproc_bv2ss( &bv );
+}
+
+/*
+ * NOTE: this overlay assumes that the chainingBehavior control
+ * is registered by the chain overlay; it may move here some time.
+ * This overlay provides support for that control as well.
+ */
+
+
+static int		sc_returnContRef;
+#define o_returnContRef			o_ctrlflag[sc_returnContRef]
+#define get_returnContRef(op)		((op)->o_returnContRef & SLAP_CONTROL_MASK)
+
+static struct berval	slap_EXOP_CHAINEDREQUEST = BER_BVC( LDAP_EXOP_X_CHAINEDREQUEST );
+static struct berval	slap_FEATURE_CANCHAINOPS = BER_BVC( LDAP_FEATURE_X_CANCHAINOPS );
+
+static BackendInfo	*lback;
+
+typedef struct ldap_distproc_t {
+	/* "common" configuration info (anything occurring before an "uri") */
+	ldapinfo_t		*lc_common_li;
+
+	/* current configuration info */
+	ldapinfo_t		*lc_cfg_li;
+
+	/* tree of configured[/generated?] "uri" info */
+	ldap_avl_info_t		lc_lai;
+
+	unsigned		lc_flags;
+#define LDAP_DISTPROC_F_NONE		(0x00U)
+#define	LDAP_DISTPROC_F_CHAINING	(0x01U)
+#define	LDAP_DISTPROC_F_CACHE_URI	(0x10U)
+
+#define	LDAP_DISTPROC_CHAINING( lc )	( ( (lc)->lc_flags & LDAP_DISTPROC_F_CHAINING ) == LDAP_DISTPROC_F_CHAINING )
+#define	LDAP_DISTPROC_CACHE_URI( lc )	( ( (lc)->lc_flags & LDAP_DISTPROC_F_CACHE_URI ) == LDAP_DISTPROC_F_CACHE_URI )
+
+} ldap_distproc_t;
+
+static int ldap_distproc_db_init_common( BackendDB	*be );
+static int ldap_distproc_db_init_one( BackendDB *be );
+#define	ldap_distproc_db_open_one(be)		(lback)->bi_db_open( (be) )
+#define	ldap_distproc_db_close_one(be)		(0)
+#define	ldap_distproc_db_destroy_one(be, ca)	(lback)->bi_db_destroy( (be), (ca) )
+
+static int
+ldap_distproc_parse_ctrl(
+	Operation	*op,
+	SlapReply	*rs,
+	LDAPControl	*ctrl );
+
+static int
+ldap_distproc_uri_cmp( const void *c1, const void *c2 )
+{
+	const ldapinfo_t	*li1 = (const ldapinfo_t *)c1;
+	const ldapinfo_t	*li2 = (const ldapinfo_t *)c2;
+
+	assert( li1->li_bvuri != NULL );
+	assert( !BER_BVISNULL( &li1->li_bvuri[ 0 ] ) );
+	assert( BER_BVISNULL( &li1->li_bvuri[ 1 ] ) );
+
+	assert( li2->li_bvuri != NULL );
+	assert( !BER_BVISNULL( &li2->li_bvuri[ 0 ] ) );
+	assert( BER_BVISNULL( &li2->li_bvuri[ 1 ] ) );
+
+	/* If local DNs don't match, it is definitely not a match */
+	return ber_bvcmp( &li1->li_bvuri[ 0 ], &li2->li_bvuri[ 0 ] );
+}
+
+static int
+ldap_distproc_uri_dup( void *c1, void *c2 )
+{
+	ldapinfo_t	*li1 = (ldapinfo_t *)c1;
+	ldapinfo_t	*li2 = (ldapinfo_t *)c2;
+
+	assert( li1->li_bvuri != NULL );
+	assert( !BER_BVISNULL( &li1->li_bvuri[ 0 ] ) );
+	assert( BER_BVISNULL( &li1->li_bvuri[ 1 ] ) );
+
+	assert( li2->li_bvuri != NULL );
+	assert( !BER_BVISNULL( &li2->li_bvuri[ 0 ] ) );
+	assert( BER_BVISNULL( &li2->li_bvuri[ 1 ] ) );
+
+	/* Cannot have more than one shared session with same DN */
+	if ( ber_bvcmp( &li1->li_bvuri[ 0 ], &li2->li_bvuri[ 0 ] ) == 0 ) {
+		return -1;
+	}
+		
+	return 0;
+}
+
+static int
+ldap_distproc_operational( Operation *op, SlapReply *rs )
+{
+	/* Trap entries generated by back-ldap.
+	 * 
+	 * FIXME: we need a better way to recognize them; a cleaner
+	 * solution would be to be able to intercept the response
+	 * of be_operational(), so that we can divert only those
+	 * calls that fail because operational attributes were
+	 * requested for entries that do not belong to the underlying
+	 * database.  This fix is likely to intercept also entries
+	 * generated by back-perl and so. */
+	if ( rs->sr_entry->e_private == NULL ) {
+		return 0;
+	}
+
+	return SLAP_CB_CONTINUE;
+}
+
+static int
+ldap_distproc_response( Operation *op, SlapReply *rs )
+{
+	return SLAP_CB_CONTINUE;
+}
+
+/*
+ * configuration...
+ */
+
+enum {
+	/* NOTE: the chaining behavior control is registered
+	 * by the chain overlay; it may move here some time */
+	DP_CHAINING = 1,
+	DP_CACHE_URI,
+
+	DP_LAST
+};
+
+static ConfigDriver distproc_cfgen;
+static ConfigCfAdd distproc_cfadd;
+static ConfigLDAPadd distproc_ldadd;
+
+static ConfigTable distproc_cfg[] = {
+	{ "distproc-chaining", "args",
+		2, 4, 0, ARG_MAGIC|ARG_BERVAL|DP_CHAINING, distproc_cfgen,
+		/* NOTE: using the same attributeTypes defined
+		 * for the "chain" overlay */
+		"( OLcfgOvAt:3.1 NAME 'olcChainingBehavior' "
+			"DESC 'Chaining behavior control parameters (draft-sermersheim-ldap-chaining)' "
+			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+	{ "distproc-cache-uri", "TRUE/FALSE",
+		2, 2, 0, ARG_MAGIC|ARG_ON_OFF|DP_CACHE_URI, distproc_cfgen,
+		"( OLcfgOvAt:3.2 NAME 'olcChainCacheURI' "
+			"DESC 'Enables caching of URIs not present in configuration' "
+			"SYNTAX OMsBoolean "
+			"SINGLE-VALUE )", NULL, NULL },
+	{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
+};
+
+static ConfigOCs distproc_ocs[] = {
+	{ "( OLcfgOvOc:7.1 "
+		"NAME 'olcDistProcConfig' "
+		"DESC 'Distributed procedures <draft-sermersheim-ldap-distproc> configuration' "
+		"SUP olcOverlayConfig "
+		"MAY ( "
+			"olcChainingBehavior $ "
+			"olcChainCacheURI "
+			") )",
+		Cft_Overlay, distproc_cfg, NULL, distproc_cfadd },
+	{ "( OLcfgOvOc:7.2 "
+		"NAME 'olcDistProcDatabase' "
+		"DESC 'Distributed procedure remote server configuration' "
+		"AUXILIARY )",
+		Cft_Misc, distproc_cfg, distproc_ldadd },
+	{ NULL, 0, NULL }
+};
+
+static int
+distproc_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
+{
+	slap_overinst		*on;
+	ldap_distproc_t		*lc;
+
+	ldapinfo_t		*li;
+
+	AttributeDescription	*ad = NULL;
+	Attribute		*at;
+	const char		*text;
+
+	int			rc;
+
+	if ( p->ce_type != Cft_Overlay
+		|| !p->ce_bi
+		|| p->ce_bi->bi_cf_ocs != distproc_ocs )
+	{
+		return LDAP_CONSTRAINT_VIOLATION;
+	}
+
+	on = (slap_overinst *)p->ce_bi;
+	lc = (ldap_distproc_t *)on->on_bi.bi_private;
+
+	assert( ca->be == NULL );
+	ca->be = (BackendDB *)ch_calloc( 1, sizeof( BackendDB ) );
+
+	ca->be->bd_info = (BackendInfo *)on;
+
+	rc = slap_str2ad( "olcDbURI", &ad, &text );
+	assert( rc == LDAP_SUCCESS );
+
+	at = attr_find( e->e_attrs, ad );
+	if ( lc->lc_common_li == NULL && at != NULL ) {
+		/* FIXME: we should generate an empty default entry
+		 * if none is supplied */
+		Debug( LDAP_DEBUG_ANY, "slapd-distproc: "
+			"first underlying database \"%s\" "
+			"cannot contain attribute \"%s\".\n",
+			e->e_name.bv_val, ad->ad_cname.bv_val, 0 );
+		rc = LDAP_CONSTRAINT_VIOLATION;
+		goto done;
+
+	} else if ( lc->lc_common_li != NULL && at == NULL ) {
+		/* FIXME: we should generate an empty default entry
+		 * if none is supplied */
+		Debug( LDAP_DEBUG_ANY, "slapd-distproc: "
+			"subsequent underlying database \"%s\" "
+			"must contain attribute \"%s\".\n",
+			e->e_name.bv_val, ad->ad_cname.bv_val, 0 );
+		rc = LDAP_CONSTRAINT_VIOLATION;
+		goto done;
+	}
+
+	if ( lc->lc_common_li == NULL ) {
+		rc = ldap_distproc_db_init_common( ca->be );
+
+	} else {
+		rc = ldap_distproc_db_init_one( ca->be );
+	}
+
+	if ( rc != 0 ) {
+		Debug( LDAP_DEBUG_ANY, "slapd-distproc: "
+			"unable to init %sunderlying database \"%s\".\n",
+			lc->lc_common_li == NULL ? "common " : "", e->e_name.bv_val, 0 );
+		return LDAP_CONSTRAINT_VIOLATION;
+	}
+
+	li = ca->be->be_private;
+
+	if ( lc->lc_common_li == NULL ) {
+		lc->lc_common_li = li;
+
+	} else if ( avl_insert( &lc->lc_lai.lai_tree, (caddr_t)li,
+		ldap_distproc_uri_cmp, ldap_distproc_uri_dup ) )
+	{
+		Debug( LDAP_DEBUG_ANY, "slapd-distproc: "
+			"database \"%s\" insert failed.\n",
+			e->e_name.bv_val, 0, 0 );
+		rc = LDAP_CONSTRAINT_VIOLATION;
+		goto done;
+	}
+
+done:;
+	if ( rc != LDAP_SUCCESS ) {
+		(void)ldap_distproc_db_destroy_one( ca->be, NULL );
+		ch_free( ca->be );
+		ca->be = NULL;
+	}
+
+	return rc;
+}
+
+typedef struct ldap_distproc_cfadd_apply_t {
+	Operation	*op;
+	SlapReply	*rs;
+	Entry		*p;
+	ConfigArgs	*ca;
+	int		count;
+} ldap_distproc_cfadd_apply_t;
+
+static int
+ldap_distproc_cfadd_apply( void *datum, void *arg )
+{
+	ldapinfo_t			*li = (ldapinfo_t *)datum;
+	ldap_distproc_cfadd_apply_t	*lca = (ldap_distproc_cfadd_apply_t *)arg;
+
+	struct berval			bv;
+
+	/* FIXME: should not hardcode "olcDatabase" here */
+	bv.bv_len = snprintf( lca->ca->cr_msg, sizeof( lca->ca->cr_msg ),
+		"olcDatabase={%d}%s", lca->count, lback->bi_type );
+	bv.bv_val = lca->ca->cr_msg;
+
+	lca->ca->be->be_private = (void *)li;
+	config_build_entry( lca->op, lca->rs, lca->p->e_private, lca->ca,
+		&bv, lback->bi_cf_ocs, &distproc_ocs[ 1 ] );
+
+	lca->count++;
+
+	return 0;
+}
+
+static int
+distproc_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca )
+{
+	CfEntryInfo	*pe = p->e_private;
+	slap_overinst	*on = (slap_overinst *)pe->ce_bi;
+	ldap_distproc_t	*lc = (ldap_distproc_t *)on->on_bi.bi_private;
+	void		*priv = (void *)ca->be->be_private;
+
+	if ( lback->bi_cf_ocs ) {
+		ldap_distproc_cfadd_apply_t	lca = { 0 };
+
+		lca.op = op;
+		lca.rs = rs;
+		lca.p = p;
+		lca.ca = ca;
+		lca.count = 0;
+
+		(void)ldap_distproc_cfadd_apply( (void *)lc->lc_common_li, (void *)&lca );
+
+		(void)avl_apply( lc->lc_lai.lai_tree, ldap_distproc_cfadd_apply,
+			&lca, 1, AVL_INORDER );
+
+		ca->be->be_private = priv;
+	}
+
+	return 0;
+}
+
+static int
+distproc_cfgen( ConfigArgs *c )
+{
+	slap_overinst	*on = (slap_overinst *)c->bi;
+	ldap_distproc_t	*lc = (ldap_distproc_t *)on->on_bi.bi_private;
+
+	int		rc = 0;
+
+	if ( c->op == SLAP_CONFIG_EMIT ) {
+		switch( c->type ) {
+		case DP_CACHE_URI:
+			c->value_int = LDAP_DISTPROC_CACHE_URI( lc );
+			break;
+
+		default:
+			assert( 0 );
+			rc = 1;
+		}
+		return rc;
+
+	} else if ( c->op == LDAP_MOD_DELETE ) {
+		switch( c->type ) {
+		case DP_CHAINING:
+			return 1;
+
+		case DP_CACHE_URI:
+			lc->lc_flags &= ~LDAP_DISTPROC_F_CACHE_URI;
+			break;
+
+		default:
+			return 1;
+		}
+		return rc;
+	}
+
+	switch( c->type ) {
+	case DP_CACHE_URI:
+		if ( c->value_int ) {
+			lc->lc_flags |= LDAP_DISTPROC_F_CACHE_URI;
+		} else {
+			lc->lc_flags &= ~LDAP_DISTPROC_F_CACHE_URI;
+		}
+		break;
+
+	default:
+		assert( 0 );
+		return 1;
+	}
+
+	return rc;
+}
+
+static int
+ldap_distproc_db_init(
+	BackendDB *be,
+	ConfigReply *cr )
+{
+	slap_overinst	*on = (slap_overinst *)be->bd_info;
+	ldap_distproc_t	*lc = NULL;
+
+	if ( lback == NULL ) {
+		lback = backend_info( "ldap" );
+
+		if ( lback == NULL ) {
+			return 1;
+		}
+	}
+
+	lc = ch_malloc( sizeof( ldap_distproc_t ) );
+	if ( lc == NULL ) {
+		return 1;
+	}
+	memset( lc, 0, sizeof( ldap_distproc_t ) );
+	ldap_pvt_thread_mutex_init( &lc->lc_lai.lai_mutex );
+
+	on->on_bi.bi_private = (void *)lc;
+
+	return 0;
+}
+
+static int
+ldap_distproc_db_config(
+	BackendDB	*be,
+	const char	*fname,
+	int		lineno,
+	int		argc,
+	char		**argv )
+{
+	slap_overinst	*on = (slap_overinst *)be->bd_info;
+	ldap_distproc_t	*lc = (ldap_distproc_t *)on->on_bi.bi_private;
+
+	int		rc = SLAP_CONF_UNKNOWN;
+		
+	if ( lc->lc_common_li == NULL ) {
+		void	*be_private = be->be_private;
+		ldap_distproc_db_init_common( be );
+		lc->lc_common_li = lc->lc_cfg_li = (ldapinfo_t *)be->be_private;
+		be->be_private = be_private;
+	}
+
+	/* Something for the distproc database? */
+	if ( strncasecmp( argv[ 0 ], "distproc-", STRLENOF( "distproc-" ) ) == 0 ) {
+		char		*save_argv0 = argv[ 0 ];
+		BackendInfo	*bd_info = be->bd_info;
+		void		*be_private = be->be_private;
+		ConfigOCs	*be_cf_ocs = be->be_cf_ocs;
+		int		is_uri = 0;
+
+		argv[ 0 ] += STRLENOF( "distproc-" );
+
+		if ( strcasecmp( argv[ 0 ], "uri" ) == 0 ) {
+			rc = ldap_distproc_db_init_one( be );
+			if ( rc != 0 ) {
+				Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+					"underlying slapd-ldap initialization failed.\n.",
+					fname, lineno, 0 );
+				return 1;
+			}
+			lc->lc_cfg_li = be->be_private;
+			is_uri = 1;
+		}
+
+		/* TODO: add checks on what other slapd-ldap(5) args
+		 * should be put in the template; this is not quite
+		 * harmful, because attributes that shouldn't don't
+		 * get actually used, but the user should at least
+		 * be warned.
+		 */
+
+		be->bd_info = lback;
+		be->be_private = (void *)lc->lc_cfg_li;
+		be->be_cf_ocs = lback->bi_cf_ocs;
+
+		rc = config_generic_wrapper( be, fname, lineno, argc, argv );
+
+		argv[ 0 ] = save_argv0;
+		be->be_cf_ocs = be_cf_ocs;
+		be->be_private = be_private;
+		be->bd_info = bd_info;
+
+		if ( is_uri ) {
+private_destroy:;
+			if ( rc != 0 ) {
+				BackendDB		db = *be;
+
+				db.bd_info = lback;
+				db.be_private = (void *)lc->lc_cfg_li;
+				ldap_distproc_db_destroy_one( &db, NULL );
+				lc->lc_cfg_li = NULL;
+
+			} else {
+				if ( lc->lc_cfg_li->li_bvuri == NULL
+					|| BER_BVISNULL( &lc->lc_cfg_li->li_bvuri[ 0 ] )
+					|| !BER_BVISNULL( &lc->lc_cfg_li->li_bvuri[ 1 ] ) )
+				{
+					Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+						"no URI list allowed in slapo-distproc.\n",
+						fname, lineno, 0 );
+					rc = 1;
+					goto private_destroy;
+				}
+
+				if ( avl_insert( &lc->lc_lai.lai_tree,
+					(caddr_t)lc->lc_cfg_li,
+					ldap_distproc_uri_cmp, ldap_distproc_uri_dup ) )
+				{
+					Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+						"duplicate URI in slapo-distproc.\n",
+						fname, lineno, 0 );
+					rc = 1;
+					goto private_destroy;
+				}
+			}
+		}
+	}
+	
+	return rc;
+}
+
+enum db_which {
+	db_open = 0,
+	db_close,
+	db_destroy,
+
+	db_last
+};
+
+typedef struct ldap_distproc_db_apply_t {
+	BackendDB	*be;
+	BI_db_func	*func;
+} ldap_distproc_db_apply_t;
+
+static int
+ldap_distproc_db_apply( void *datum, void *arg )
+{
+	ldapinfo_t		*li = (ldapinfo_t *)datum;
+	ldap_distproc_db_apply_t	*lca = (ldap_distproc_db_apply_t *)arg;
+
+	lca->be->be_private = (void *)li;
+
+	return lca->func( lca->be, NULL );
+}
+
+static int
+ldap_distproc_db_func(
+	BackendDB *be,
+	enum db_which which
+)
+{
+	slap_overinst	*on = (slap_overinst *)be->bd_info;
+	ldap_distproc_t	*lc = (ldap_distproc_t *)on->on_bi.bi_private;
+
+	int		rc = 0;
+
+	if ( lc ) {
+		BI_db_func	*func = (&lback->bi_db_open)[ which ];
+
+		if ( func != NULL && lc->lc_common_li != NULL ) {
+			BackendDB		db = *be;
+
+			db.bd_info = lback;
+			db.be_private = lc->lc_common_li;
+
+			rc = func( &db, NULL );
+
+			if ( rc != 0 ) {
+				return rc;
+			}
+
+			if ( lc->lc_lai.lai_tree != NULL ) {
+				ldap_distproc_db_apply_t	lca;
+
+				lca.be = &db;
+				lca.func = func;
+
+				rc = avl_apply( lc->lc_lai.lai_tree,
+					ldap_distproc_db_apply, (void *)&lca,
+					1, AVL_INORDER ) != AVL_NOMORE;
+			}
+		}
+	}
+
+	return rc;
+}
+
+static int
+ldap_distproc_db_open(
+	BackendDB	*be,
+	ConfigReply	*cr )
+{
+	return ldap_distproc_db_func( be, db_open );
+}
+
+static int
+ldap_distproc_db_close(
+	BackendDB	*be,
+	ConfigReply	*cr )
+{
+	return ldap_distproc_db_func( be, db_close );
+}
+
+static int
+ldap_distproc_db_destroy(
+	BackendDB	*be,
+	ConfigReply	*cr )
+{
+	slap_overinst	*on = (slap_overinst *) be->bd_info;
+	ldap_distproc_t	*lc = (ldap_distproc_t *)on->on_bi.bi_private;
+
+	int		rc;
+
+	rc = ldap_distproc_db_func( be, db_destroy );
+
+	if ( lc ) {
+		avl_free( lc->lc_lai.lai_tree, NULL );
+		ldap_pvt_thread_mutex_destroy( &lc->lc_lai.lai_mutex );
+		ch_free( lc );
+	}
+
+	return rc;
+}
+
+/*
+ * inits one instance of the slapd-ldap backend, and stores
+ * the private info in be_private of the arg
+ */
+static int
+ldap_distproc_db_init_common(
+	BackendDB	*be )
+{
+	BackendInfo	*bi = be->bd_info;
+	int		t;
+
+	be->bd_info = lback;
+	be->be_private = NULL;
+	t = lback->bi_db_init( be, NULL );
+	if ( t != 0 ) {
+		return t;
+	}
+	be->bd_info = bi;
+
+	return 0;
+}
+
+/*
+ * inits one instance of the slapd-ldap backend, stores
+ * the private info in be_private of the arg and fills
+ * selected fields with data from the template.
+ *
+ * NOTE: add checks about the other fields of the template,
+ * which are ignored and SHOULD NOT be configured by the user.
+ */
+static int
+ldap_distproc_db_init_one(
+	BackendDB	*be )
+{
+	slap_overinst	*on = (slap_overinst *)be->bd_info;
+	ldap_distproc_t	*lc = (ldap_distproc_t *)on->on_bi.bi_private;
+
+	BackendInfo	*bi = be->bd_info;
+	ldapinfo_t	*li;
+
+	slap_op_t	t;
+
+	be->bd_info = lback;
+	be->be_private = NULL;
+	t = lback->bi_db_init( be, NULL );
+	if ( t != 0 ) {
+		return t;
+	}
+	li = (ldapinfo_t *)be->be_private;
+
+	/* copy common data */
+	li->li_nretries = lc->lc_common_li->li_nretries;
+	li->li_flags = lc->lc_common_li->li_flags;
+	li->li_version = lc->lc_common_li->li_version;
+	for ( t = 0; t < SLAP_OP_LAST; t++ ) {
+		li->li_timeout[ t ] = lc->lc_common_li->li_timeout[ t ];
+	}
+	be->bd_info = bi;
+
+	return 0;
+}
+
+typedef struct ldap_distproc_conn_apply_t {
+	BackendDB	*be;
+	Connection	*conn;
+} ldap_distproc_conn_apply_t;
+
+static int
+ldap_distproc_conn_apply( void *datum, void *arg )
+{
+	ldapinfo_t		*li = (ldapinfo_t *)datum;
+	ldap_distproc_conn_apply_t	*lca = (ldap_distproc_conn_apply_t *)arg;
+
+	lca->be->be_private = (void *)li;
+
+	return lback->bi_connection_destroy( lca->be, lca->conn );
+}
+
+static int
+ldap_distproc_connection_destroy(
+	BackendDB *be,
+	Connection *conn
+)
+{
+	slap_overinst		*on = (slap_overinst *) be->bd_info;
+	ldap_distproc_t		*lc = (ldap_distproc_t *)on->on_bi.bi_private;
+	void			*private = be->be_private;
+	ldap_distproc_conn_apply_t	lca;
+	int			rc;
+
+	be->be_private = NULL;
+	lca.be = be;
+	lca.conn = conn;
+	ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
+	rc = avl_apply( lc->lc_lai.lai_tree, ldap_distproc_conn_apply,
+		(void *)&lca, 1, AVL_INORDER ) != AVL_NOMORE;
+	ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex );
+	be->be_private = private;
+
+	return rc;
+}
+
+static int
+ldap_distproc_parse_returnContRef_ctrl(
+	Operation	*op,
+	SlapReply	*rs,
+	LDAPControl	*ctrl )
+{
+	if ( get_returnContRef( op ) != SLAP_CONTROL_NONE ) {
+		rs->sr_text = "returnContinuationReference control specified multiple times";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	if ( op->o_pagedresults != SLAP_CONTROL_NONE ) {
+		rs->sr_text = "returnContinuationReference control specified with pagedResults control";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	if ( !BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
+		rs->sr_text = "returnContinuationReference control: value must be NULL";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	op->o_returnContRef = ctrl->ldctl_iscritical ? SLAP_CONTROL_CRITICAL : SLAP_CONTROL_NONCRITICAL;
+
+	return LDAP_SUCCESS;
+}
+
+static int
+ldap_exop_chained_request(
+		Operation	*op,
+		SlapReply	*rs )
+{
+	Statslog( LDAP_DEBUG_STATS, "%s CHAINED REQUEST\n",
+	    op->o_log_prefix, 0, 0, 0, 0 );
+
+	rs->sr_err = backend_check_restrictions( op, rs, 
+			(struct berval *)&slap_EXOP_CHAINEDREQUEST );
+	if ( rs->sr_err != LDAP_SUCCESS ) {
+		return rs->sr_err;
+	}
+
+	/* by now, just reject requests */
+	rs->sr_text = "under development";
+	return LDAP_UNWILLING_TO_PERFORM;
+}
+
+
+static slap_overinst distproc;
+
+int
+distproc_initialize( void )
+{
+	int	rc;
+
+	/* Make sure we don't exceed the bits reserved for userland */
+	config_check_userland( DP_LAST );
+
+	rc = load_extop( (struct berval *)&slap_EXOP_CHAINEDREQUEST,
+		SLAP_EXOP_HIDE, ldap_exop_chained_request );
+	if ( rc != LDAP_SUCCESS ) {
+		Debug( LDAP_DEBUG_ANY, "slapd-distproc: "
+			"unable to register chainedRequest exop: %d.\n",
+			rc, 0, 0 );
+		return rc;
+	}
+
+#ifdef LDAP_DEVEL
+	rc = supported_feature_load( &slap_FEATURE_CANCHAINOPS );
+	if ( rc != LDAP_SUCCESS ) {
+		Debug( LDAP_DEBUG_ANY, "slapd-distproc: "
+			"unable to register canChainOperations supported feature: %d.\n",
+			rc, 0, 0 );
+		return rc;
+	}
+#endif
+
+	rc = register_supported_control( LDAP_CONTROL_X_RETURNCONTREF,
+			SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE, NULL,
+			ldap_distproc_parse_returnContRef_ctrl, &sc_returnContRef );
+	if ( rc != LDAP_SUCCESS ) {
+		Debug( LDAP_DEBUG_ANY, "slapd-distproc: "
+			"unable to register returnContinuationReference control: %d.\n",
+			rc, 0, 0 );
+		return rc;
+	}
+
+	distproc.on_bi.bi_type = "distproc";
+	distproc.on_bi.bi_db_init = ldap_distproc_db_init;
+	distproc.on_bi.bi_db_config = ldap_distproc_db_config;
+	distproc.on_bi.bi_db_open = ldap_distproc_db_open;
+	distproc.on_bi.bi_db_close = ldap_distproc_db_close;
+	distproc.on_bi.bi_db_destroy = ldap_distproc_db_destroy;
+
+	/* ... otherwise the underlying backend's function would be called,
+	 * likely passing an invalid entry; on the contrary, the requested
+	 * operational attributes should have been returned while chasing
+	 * the referrals.  This all in all is a bit messy, because part
+	 * of the operational attributes are generated by the backend;
+	 * part by the frontend; back-ldap should receive all the available
+	 * ones from the remote server, but then, on its own, it strips those
+	 * it assumes will be (re)generated by the frontend (e.g.
+	 * subschemaSubentry, entryDN, ...) */
+	distproc.on_bi.bi_operational = ldap_distproc_operational;
+	
+	distproc.on_bi.bi_connection_destroy = ldap_distproc_connection_destroy;
+
+	distproc.on_response = ldap_distproc_response;
+
+	distproc.on_bi.bi_cf_ocs = distproc_ocs;
+
+	rc = config_register_schema( distproc_cfg, distproc_ocs );
+	if ( rc ) {
+		return rc;
+	}
+
+	return overlay_register( &distproc );
+}
+
+#endif /* SLAP_DISTPROC */

Modified: openldap/trunk/servers/slapd/back-ldap/extended.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/extended.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/extended.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* extended.c - ldap backend extended routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/extended.c,v 1.22.2.18 2007/05/19 12:27:53 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/extended.c,v 1.36.2.7 2007/09/29 08:30:58 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -47,7 +47,7 @@
 	ldapinfo_t	*li = (ldapinfo_t *) op->o_bd->be_private;
 
 	ldapconn_t	*lc = NULL;
-	LDAPControl	**oldctrls = NULL;
+	LDAPControl	**ctrls = NULL, **oldctrls = NULL;
 	int		rc;
 
 	/* FIXME: this needs to be called here, so it is
@@ -58,9 +58,8 @@
 		return -1;
 	}
 
-	oldctrls = op->o_ctrls;
-	if ( ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-		li->li_version, &li->li_idassert, op, rs, &op->o_ctrls ) )
+	ctrls = op->o_ctrls;
+	if ( ldap_back_controls_add( op, rs, lc, &ctrls ) )
 	{
 		op->o_ctrls = oldctrls;
 		send_ldap_extended( op, rs );
@@ -70,13 +69,11 @@
 		goto done;
 	}
 
+	op->o_ctrls = ctrls;
 	rc = exop( op, rs, &lc );
 
-	if ( op->o_ctrls && op->o_ctrls != oldctrls ) {
-		free( op->o_ctrls[ 0 ] );
-		free( op->o_ctrls );
-	}
 	op->o_ctrls = oldctrls;
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 done:;
 	if ( lc != NULL ) {
@@ -125,13 +122,12 @@
 			ndn = op->o_req_ndn;
 
 	assert( lc != NULL );
+	assert( rs->sr_ctrls == NULL );
 
 	if ( BER_BVISNULL( &ndn ) && op->ore_reqdata != NULL ) {
-		/* NOTE: most of this code is mutuated
-		 * from slap_passwd_parse(); we can't call
-		 * that function since now the request data
-		 * has been destroyed by NULL-terminating
-		 * the bervals.  Luckily enough, we only need
+		/* NOTE: most of this code is mutated
+		 * from slap_passwd_parse();
+		 * But here we only need
 		 * the first berval... */
 
 		ber_tag_t tag;
@@ -156,7 +152,7 @@
 
 		tag = ber_peek_tag( ber, &len );
 		if ( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_ID ) {
-			tag = ber_scanf( ber, "m", &tmpid );
+			tag = ber_get_stringbv( ber, &tmpid, LBER_BV_NOTERM );
 
 			if ( tag == LBER_ERROR ) {
 				return LDAP_PROTOCOL_ERROR;
@@ -164,8 +160,11 @@
 		}
 
 		if ( !BER_BVISEMPTY( &tmpid ) ) {
+			char idNull = tmpid.bv_val[tmpid.bv_len];
+			tmpid.bv_val[tmpid.bv_len] = '\0';
 			rs->sr_err = dnPrettyNormal( NULL, &tmpid, &dn,
 				&ndn, op->o_tmpmemctx );
+			tmpid.bv_val[tmpid.bv_len] = idNull;
 			if ( rs->sr_err != LDAP_SUCCESS ) {
 				/* should have been successfully parsed earlier! */
 				return rs->sr_err;
@@ -190,6 +189,7 @@
 		op->o_ctrls, NULL, &msgid );
 
 	if ( rc == LDAP_SUCCESS ) {
+		/* TODO: set timeout? */
 		if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, NULL, &res ) == -1 ) {
 			ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
 			rs->sr_err = rc;
@@ -206,17 +206,7 @@
 			rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
 					(char **)&rs->sr_matched,
 					&text,
-					NULL, NULL, 0 );
-#ifndef LDAP_NULL_IS_NULL
-			if ( rs->sr_matched && rs->sr_matched[ 0 ] == '\0' ) {
-				free( (char *)rs->sr_matched );
-				rs->sr_matched = NULL;
-			}
-			if ( rs->sr_text && rs->sr_text[ 0 ] == '\0' ) {
-				free( (char *)rs->sr_text );
-				rs->sr_text = NULL;
-			}
-#endif /* LDAP_NULL_IS_NULL */
+					NULL, &rs->sr_ctrls, 0 );
 
 			if ( rc == LDAP_SUCCESS ) {
 				if ( rs->sr_err == LDAP_SUCCESS ) {
@@ -280,6 +270,11 @@
 		rs->sr_matched = NULL;
 	}
 
+	if ( rs->sr_ctrls ) {
+		ldap_controls_free( rs->sr_ctrls );
+		rs->sr_ctrls = NULL;
+	}
+
 	if ( text ) {
 		free( text );
 		rs->sr_text = NULL;
@@ -309,6 +304,7 @@
 	char		*text = NULL;
 
 	assert( lc != NULL );
+	assert( rs->sr_ctrls == NULL );
 
 	Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_generic(%s, \"%s\")\n",
 		op->ore_reqoid.bv_val, op->o_req_dn.bv_val, 0 );
@@ -319,6 +315,7 @@
 		op->o_ctrls, NULL, &msgid );
 
 	if ( rc == LDAP_SUCCESS ) {
+		/* TODO: set timeout? */
 		if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, NULL, &res ) == -1 ) {
 			ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
 			rs->sr_err = rc;
@@ -335,17 +332,7 @@
 			rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
 					(char **)&rs->sr_matched,
 					&text,
-					NULL, NULL, 0 );
-#ifndef LDAP_NULL_IS_NULL
-			if ( rs->sr_matched && rs->sr_matched[ 0 ] == '\0' ) {
-				free( (char *)rs->sr_matched );
-				rs->sr_matched = NULL;
-			}
-			if ( rs->sr_text && rs->sr_text[ 0 ] == '\0' ) {
-				free( (char *)rs->sr_text );
-				rs->sr_text = NULL;
-			}
-#endif /* LDAP_NULL_IS_NULL */
+					NULL, &rs->sr_ctrls, 0 );
 			if ( rc == LDAP_SUCCESS ) {
 				if ( rs->sr_err == LDAP_SUCCESS ) {
 					rc = ldap_parse_extended_result( lc->lc_ld, res,
@@ -390,6 +377,11 @@
 		rs->sr_matched = NULL;
 	}
 
+	if ( rs->sr_ctrls ) {
+		ldap_controls_free( rs->sr_ctrls );
+		rs->sr_ctrls = NULL;
+	}
+
 	if ( text ) {
 		free( text );
 		rs->sr_text = NULL;

Modified: openldap/trunk/servers/slapd/back-ldap/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* init.c - initialize ldap backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/init.c,v 1.79.2.13 2007/01/05 09:47:10 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/init.c,v 1.99.2.5 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -29,6 +29,7 @@
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "config.h"
 #include "back-ldap.h"
 
 int
@@ -41,6 +42,18 @@
 int
 ldap_back_initialize( BackendInfo *bi )
 {
+	int		rc;
+
+	bi->bi_flags =
+#ifdef LDAP_DYNAMIC_OBJECTS
+		/* this is set because all the support a proxy has to provide
+		 * is the capability to forward the refresh exop, and to
+		 * pass thru entries that contain the dynamicObject class
+		 * and the entryTtl attribute */
+		SLAP_BFLAG_DYNAMIC |
+#endif /* LDAP_DYNAMIC_OBJECTS */
+		0;
+
 	bi->bi_open = ldap_back_open;
 	bi->bi_config = 0;
 	bi->bi_close = 0;
@@ -49,7 +62,7 @@
 	bi->bi_db_init = ldap_back_db_init;
 	bi->bi_db_config = config_generic_wrapper;
 	bi->bi_db_open = ldap_back_db_open;
-	bi->bi_db_close = 0;
+	bi->bi_db_close = ldap_back_db_close;
 	bi->bi_db_destroy = ldap_back_db_destroy;
 
 	bi->bi_op_bind = ldap_back_bind;
@@ -70,17 +83,26 @@
 	bi->bi_connection_init = 0;
 	bi->bi_connection_destroy = ldap_back_conn_destroy;
 
-	if ( chain_init() ) {
-		return -1;
+	rc = chain_initialize();
+	if ( rc ) {
+		return rc;
 	}
 
+#ifdef SLAP_DISTPROC
+	rc = distproc_initialize();
+	if ( rc ) {
+		return rc;
+	}
+#endif
+
 	return ldap_back_init_cf( bi );
 }
 
 int
-ldap_back_db_init( Backend *be )
+ldap_back_db_init( Backend *be, ConfigReply *cr )
 {
 	ldapinfo_t	*li;
+	int		rc;
 	unsigned	i;
 
 	li = (ldapinfo_t *)ch_calloc( 1, sizeof( ldapinfo_t ) );
@@ -89,6 +111,8 @@
  	}
 
 	li->li_rebind_f = ldap_back_default_rebind;
+	li->li_urllist_f = ldap_back_default_urllist;
+	li->li_urllist_p = li;
 	ldap_pvt_thread_mutex_init( &li->li_uri_mutex );
 
 	BER_BVZERO( &li->li_acl_authcID );
@@ -135,14 +159,23 @@
 
 	be->be_cf_ocs = be->bd_info->bi_cf_ocs;
 
-	return 0;
+	rc = ldap_back_monitor_db_init( be );
+	if ( rc != 0 ) {
+		/* ignore, by now */
+		rc = 0;
+	}
+
+	return rc;
 }
 
 int
-ldap_back_db_open( BackendDB *be )
+ldap_back_db_open( BackendDB *be, ConfigReply *cr )
 {
 	ldapinfo_t	*li = (ldapinfo_t *)be->be_private;
 
+	slap_bindconf	sb = { BER_BVNULL };
+	int		rc = 0;
+
 	Debug( LDAP_DEBUG_TRACE,
 		"ldap_back_db_open: URI=%s\n",
 		li->li_uri != NULL ? li->li_uri : "", 0, 0 );
@@ -160,10 +193,13 @@
 		break;
 	}
 
+	ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri );
+	sb.sb_version = li->li_version;
+	sb.sb_method = LDAP_AUTH_SIMPLE;
+	BER_BVSTR( &sb.sb_binddn, "" );
+
 	if ( LDAP_BACK_T_F_DISCOVER( li ) && !LDAP_BACK_T_F( li ) ) {
-		int		rc;
-
-		rc = slap_discover_feature( li->li_uri, li->li_version,
+		rc = slap_discover_feature( &sb,
 				slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
 				LDAP_FEATURE_ABSOLUTE_FILTERS );
 		if ( rc == LDAP_COMPARE_TRUE ) {
@@ -172,9 +208,7 @@
 	}
 
 	if ( LDAP_BACK_CANCEL_DISCOVER( li ) && !LDAP_BACK_CANCEL( li ) ) {
-		int		rc;
-
-		rc = slap_discover_feature( li->li_uri, li->li_version,
+		rc = slap_discover_feature( &sb,
 				slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
 				LDAP_EXOP_CANCEL );
 		if ( rc == LDAP_COMPARE_TRUE ) {
@@ -182,9 +216,20 @@
 		}
 	}
 
+	/* monitor setup */
+	rc = ldap_back_monitor_db_open( be );
+	if ( rc != 0 ) {
+		/* ignore by now */
+		rc = 0;
+#if 0
+		goto fail;
+#endif
+	}
+
 	li->li_flags |= LDAP_BACK_F_ISOPEN;
 
-	return 0;
+fail:;
+	return rc;
 }
 
 void
@@ -211,12 +256,26 @@
 }
 
 int
-ldap_back_db_destroy( Backend *be )
+ldap_back_db_close( Backend *be, ConfigReply *cr )
 {
+	int		rc = 0;
+
 	if ( be->be_private ) {
+		rc = ldap_back_monitor_db_close( be );
+	}
+
+	return rc;
+}
+
+int
+ldap_back_db_destroy( Backend *be, ConfigReply *cr )
+{
+	if ( be->be_private ) {
 		ldapinfo_t	*li = ( ldapinfo_t * )be->be_private;
 		unsigned	i;
 
+		(void)ldap_back_monitor_db_destroy( be );
+
 		ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
 
 		if ( li->li_uri != NULL ) {

Modified: openldap/trunk/servers/slapd/back-ldap/modify.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/modify.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/modify.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* modify.c - ldap backend modify function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/modify.c,v 1.58.2.14 2007/01/13 11:19:07 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/modify.c,v 1.69.2.4 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -52,7 +52,7 @@
 		return rs->sr_err;
 	}
 
-	for ( i = 0, ml = op->oq_modify.rs_modlist; ml; i++, ml = ml->sml_next )
+	for ( i = 0, ml = op->orm_modlist; ml; i++, ml = ml->sml_next )
 		/* just count mods */ ;
 
 	modv = (LDAPMod **)ch_malloc( ( i + 1 )*sizeof( LDAPMod * )
@@ -64,8 +64,8 @@
 	mods = (LDAPMod *)&modv[ i + 1 ];
 
 	isupdate = be_shadow_update( op );
-	for ( i = 0, ml = op->oq_modify.rs_modlist; ml; ml = ml->sml_next ) {
-		if ( !isupdate && !get_manageDIT( op ) && ml->sml_desc->ad_type->sat_no_user_mod  )
+	for ( i = 0, ml = op->orm_modlist; ml; ml = ml->sml_next ) {
+		if ( !isupdate && !get_relax( op ) && ml->sml_desc->ad_type->sat_no_user_mod  )
 		{
 			continue;
 		}
@@ -99,8 +99,7 @@
 
 retry:;
 	ctrls = op->o_ctrls;
-	rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-		li->li_version, &li->li_idassert, op, rs, &ctrls );
+	rc = ldap_back_controls_add( op, rs, lc, &ctrls );
 	if ( rc != LDAP_SUCCESS ) {
 		send_ldap_result( op, rs );
 		rc = -1;
@@ -116,13 +115,13 @@
 		retrying &= ~LDAP_BACK_RETRYING;
 		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:;
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	for ( i = 0; modv[ i ]; i++ ) {
 		ch_free( modv[ i ]->mod_bvalues );

Modified: openldap/trunk/servers/slapd/back-ldap/modrdn.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/modrdn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/modrdn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* modrdn.c - ldap backend modrdn function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/modrdn.c,v 1.38.2.14 2007/01/17 20:57:10 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/modrdn.c,v 1.47.2.5 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -74,8 +74,7 @@
 
 retry:
 	ctrls = op->o_ctrls;
-	rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-		li->li_version, &li->li_idassert, op, rs, &ctrls );
+	rc = ldap_back_controls_add( op, rs, lc, &ctrls );
 	if ( rc != LDAP_SUCCESS ) {
 		send_ldap_result( op, rs );
 		rc = -1;
@@ -92,13 +91,13 @@
 		retrying &= ~LDAP_BACK_RETRYING;
 		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	if ( lc != NULL ) {
 		ldap_back_release_conn( li, lc );

Copied: openldap/trunk/servers/slapd/back-ldap/monitor.c (from rev 891, openldap/vendor/openldap-2.4.7/servers/slapd/back-ldap/monitor.c)
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/monitor.c	                        (rev 0)
+++ openldap/trunk/servers/slapd/back-ldap/monitor.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -0,0 +1,638 @@
+/* monitor.c - monitor ldap backend */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/monitor.c,v 1.2.2.3 2007/08/31 23:14:02 quanah Exp $ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2003-2007 The OpenLDAP Foundation.
+ * Portions Copyright 1999-2003 Howard Chu.
+ * Portions Copyright 2000-2003 Pierangelo Masarati.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by the Howard Chu for inclusion
+ * in OpenLDAP Software and subsequently enhanced by Pierangelo
+ * Masarati.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+#include <ac/stdlib.h>
+#include <ac/errno.h>
+#include <sys/stat.h>
+#include "lutil.h"
+#include "back-ldap.h"
+
+#include "config.h"
+
+static ObjectClass		*oc_olmLDAPDatabase;
+
+static AttributeDescription	*ad_olmDbURIList;
+
+/*
+ * NOTE: there's some confusion in monitor OID arc;
+ * by now, let's consider:
+ * 
+ * Subsystems monitor attributes	1.3.6.1.4.1.4203.666.1.55.0
+ * Databases monitor attributes		1.3.6.1.4.1.4203.666.1.55.0.1
+ * LDAP database monitor attributes	1.3.6.1.4.1.4203.666.1.55.0.1.2
+ *
+ * Subsystems monitor objectclasses	1.3.6.1.4.1.4203.666.3.16.0
+ * Databases monitor objectclasses	1.3.6.1.4.1.4203.666.3.16.0.1
+ * LDAP database monitor objectclasses	1.3.6.1.4.1.4203.666.3.16.0.1.2
+ */
+
+static struct {
+	char			*name;
+	char			*oid;
+}		s_oid[] = {
+	{ "olmLDAPAttributes",			"olmDatabaseAttributes:2" },
+	{ "olmLDAPObjectClasses",		"olmDatabaseObjectClasses:2" },
+
+	{ NULL }
+};
+
+static struct {
+	char			*desc;
+	AttributeDescription	**ad;
+}		s_at[] = {
+	{ "( olmLDAPAttributes:1 "
+		"NAME ( 'olmDbURIList' ) "
+		"DESC 'List of URIs a proxy is serving; can be modified run-time' "
+		"SUP managedInfo )",
+		&ad_olmDbURIList },
+
+	{ NULL }
+};
+
+static struct {
+	char		*desc;
+	ObjectClass	**oc;
+}		s_oc[] = {
+	/* augments an existing object, so it must be AUXILIARY
+	 * FIXME: derive from some ABSTRACT "monitoredEntity"? */
+	{ "( olmLDAPObjectClasses:1 "
+		"NAME ( 'olmLDAPDatabase' ) "
+		"SUP top AUXILIARY "
+		"MAY ( "
+			"olmDbURIList "
+			") )",
+		&oc_olmLDAPDatabase },
+
+	{ NULL }
+};
+
+static int
+ldap_back_monitor_info_destroy( ldapinfo_t * li )
+{
+	if ( !BER_BVISNULL( &li->li_monitor_info.lmi_rdn ) )
+		ch_free( li->li_monitor_info.lmi_rdn.bv_val );
+	if ( !BER_BVISNULL( &li->li_monitor_info.lmi_nrdn ) )
+		ch_free( li->li_monitor_info.lmi_nrdn.bv_val );
+	if ( !BER_BVISNULL( &li->li_monitor_info.lmi_filter ) )
+		ch_free( li->li_monitor_info.lmi_filter.bv_val );
+	if ( !BER_BVISNULL( &li->li_monitor_info.lmi_more_filter ) )
+		ch_free( li->li_monitor_info.lmi_more_filter.bv_val );
+
+	memset( &li->li_monitor_info, 0, sizeof( li->li_monitor_info ) );
+
+	return 0;
+}
+
+static int
+ldap_back_monitor_update(
+	Operation	*op,
+	SlapReply	*rs,
+	Entry		*e,
+	void		*priv )
+{
+	ldapinfo_t		*li = (ldapinfo_t *)priv;
+
+	Attribute		*a;
+
+	/* update olmDbURIList */
+	a = attr_find( e->e_attrs, ad_olmDbURIList );
+	if ( a != NULL ) {
+		struct berval	bv;
+
+		assert( a->a_vals != NULL );
+		assert( !BER_BVISNULL( &a->a_vals[ 0 ] ) );
+		assert( BER_BVISNULL( &a->a_vals[ 1 ] ) );
+
+		ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
+		if ( li->li_uri ) {
+			ber_str2bv( li->li_uri, 0, 0, &bv );
+			if ( !bvmatch( &a->a_vals[ 0 ], &bv ) ) {
+				ber_bvreplace( &a->a_vals[ 0 ], &bv );
+			}
+		}
+		ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
+	}
+
+	return SLAP_CB_CONTINUE;
+}
+
+static int
+ldap_back_monitor_modify(
+	Operation	*op,
+	SlapReply	*rs,
+	Entry		*e,
+	void		*priv )
+{
+	ldapinfo_t		*li = (ldapinfo_t *) priv;
+	
+	Attribute		*save_attrs = NULL;
+	Modifications		*ml,
+				*ml_olmDbURIList = NULL;
+	struct berval		ul = BER_BVNULL;
+	int			got = 0;
+
+	for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
+		if ( ml->sml_desc == ad_olmDbURIList ) {
+			if ( ml_olmDbURIList != NULL ) {
+				rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
+				rs->sr_text = "conflicting modifications";
+				goto done;
+			}
+
+			if ( ml->sml_op != LDAP_MOD_REPLACE ) {
+				rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
+				rs->sr_text = "modification not allowed";
+				goto done;
+			}
+
+			ml_olmDbURIList = ml;
+			got++;
+			continue;
+		}
+	}
+
+	if ( got == 0 ) {
+		return SLAP_CB_CONTINUE;
+	}
+
+	save_attrs = attrs_dup( e->e_attrs );
+
+	if ( ml_olmDbURIList != NULL ) {
+		Attribute	*a = NULL;
+		LDAPURLDesc	*ludlist = NULL;
+		int		rc;
+
+		ml = ml_olmDbURIList;
+		assert( ml->sml_nvalues != NULL );
+
+		if ( BER_BVISNULL( &ml->sml_nvalues[ 0 ] ) ) {
+			rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
+			rs->sr_text = "no value provided";
+			goto done;
+		}
+
+		if ( !BER_BVISNULL( &ml->sml_nvalues[ 1 ] ) ) {
+			rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
+			rs->sr_text = "multiple values provided";
+			goto done;
+		}
+
+		rc = ldap_url_parselist_ext( &ludlist,
+			ml->sml_nvalues[ 0 ].bv_val, NULL,
+			LDAP_PVT_URL_PARSE_NOEMPTY_HOST
+				| LDAP_PVT_URL_PARSE_DEF_PORT );
+		if ( rc != LDAP_URL_SUCCESS ) {
+			rs->sr_err = LDAP_INVALID_SYNTAX;
+			rs->sr_text = "unable to parse URI list";
+			goto done;
+		}
+
+		ul.bv_val = ldap_url_list2urls( ludlist );
+		ldap_free_urllist( ludlist );
+		if ( ul.bv_val == NULL ) {
+			rs->sr_err = LDAP_OTHER;
+			goto done;
+		}
+		ul.bv_len = strlen( ul.bv_val );
+		
+		a = attr_find( e->e_attrs, ad_olmDbURIList );
+		if ( a != NULL ) {
+			if ( a->a_nvals == a->a_vals ) {
+				a->a_nvals = ch_calloc( sizeof( struct berval ), 2 );
+			}
+
+			ber_bvreplace( &a->a_vals[ 0 ], &ul );
+			ber_bvreplace( &a->a_nvals[ 0 ], &ul );
+
+		} else {
+			attr_merge_normalize_one( e, ad_olmDbURIList, &ul, NULL );
+		}
+	}
+
+	/* apply changes */
+	if ( !BER_BVISNULL( &ul ) ) {
+		ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
+		if ( li->li_uri ) {
+			ch_free( li->li_uri );
+		}
+		li->li_uri = ul.bv_val;
+		ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
+
+		BER_BVZERO( &ul );
+	}
+
+done:;
+	if ( !BER_BVISNULL( &ul ) ) {
+		ldap_memfree( ul.bv_val );
+	}
+
+	if ( rs->sr_err == LDAP_SUCCESS ) {
+		attrs_free( save_attrs );
+		return SLAP_CB_CONTINUE;
+	}
+
+	attrs_free( e->e_attrs );
+	e->e_attrs = save_attrs;
+
+	return rs->sr_err;
+}
+
+static int
+ldap_back_monitor_free(
+	Entry		*e,
+	void		**priv )
+{
+	ldapinfo_t		*li = (ldapinfo_t *)(*priv);
+
+	*priv = NULL;
+
+	if ( !slapd_shutdown && !BER_BVISNULL( &li->li_monitor_info.lmi_rdn ) ) {
+		ldap_back_monitor_info_destroy( li );
+	}
+
+	return SLAP_CB_CONTINUE;
+}
+
+static int
+ldap_back_monitor_conn_create(
+	Operation	*op,
+	SlapReply	*rs,
+	struct berval	*ndn,
+	Entry 		*e_parent,
+	Entry		**ep )
+{
+	monitor_entry_t		*mp_parent;
+	ldap_monitor_info_t	*lmi;
+	ldapinfo_t		*li;
+
+	assert( e_parent->e_private != NULL );
+
+	mp_parent = e_parent->e_private;
+	lmi = (ldap_monitor_info_t *)mp_parent->mp_info;
+	li = lmi->lmi_li;
+
+	/* do the hard work! */
+
+	return 1;
+}
+
+/*
+ * call from within ldap_back_initialize()
+ */
+static int
+ldap_back_monitor_initialize( void )
+{
+	int		i, code;
+	ConfigArgs c;
+	char	*argv[ 3 ];
+
+	static int	ldap_back_monitor_initialized = 0;
+
+	/* register schema here; if compiled as dynamic object,
+	 * must be loaded __after__ back_monitor.la */
+
+	if ( ldap_back_monitor_initialized++ ) {
+		return 0;
+	}
+
+	if ( backend_info( "monitor" ) == NULL ) {
+		return -1;
+	}
+
+	argv[ 0 ] = "back-ldap monitor";
+	c.argv = argv;
+	c.argc = 3;
+	c.fname = argv[0];
+	for ( i = 0; s_oid[ i ].name; i++ ) {
+	
+		argv[ 1 ] = s_oid[ i ].name;
+		argv[ 2 ] = s_oid[ i ].oid;
+
+		if ( parse_oidm( &c, 0, NULL ) != 0 ) {
+			Debug( LDAP_DEBUG_ANY,
+				"ldap_back_monitor_initialize: unable to add "
+				"objectIdentifier \"%s=%s\"\n",
+				s_oid[ i ].name, s_oid[ i ].oid, 0 );
+			return 1;
+		}
+	}
+
+	for ( i = 0; s_at[ i ].desc != NULL; i++ ) {
+		code = register_at( s_at[ i ].desc, s_at[ i ].ad, 1 );
+		if ( code != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_ANY,
+				"ldap_back_monitor_initialize: register_at failed\n",
+				0, 0, 0 );
+		}
+	}
+
+	for ( i = 0; s_oc[ i ].desc != NULL; i++ ) {
+		code = register_oc( s_oc[ i ].desc, s_oc[ i ].oc, 1 );
+		if ( code != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_ANY,
+				"ldap_back_monitor_initialize: register_oc failed\n",
+				0, 0, 0 );
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * call from within ldap_back_db_init()
+ */
+int
+ldap_back_monitor_db_init( BackendDB *be )
+{
+	int	rc;
+
+	rc = ldap_back_monitor_initialize();
+	if ( rc != LDAP_SUCCESS ) {
+		return rc;
+	}
+
+#if 0	/* uncomment to turn monitoring on by default */
+	SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_MONITORING;
+#endif
+
+	return 0;
+}
+
+/*
+ * call from within ldap_back_db_open()
+ */
+int
+ldap_back_monitor_db_open( BackendDB *be )
+{
+	ldapinfo_t		*li = (ldapinfo_t *) be->be_private;
+	char			buf[ BACKMONITOR_BUFSIZE ];
+	Entry			*e = NULL;
+	monitor_callback_t	*cb = NULL;
+	struct berval		suffix, *filter, *base;
+	char			*ptr;
+	time_t			now;
+	char			timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
+	struct berval 		timestamp;
+	int			rc = 0;
+	BackendInfo		*mi;
+	monitor_extra_t		*mbe;
+
+	if ( !SLAP_DBMONITORING( be ) ) {
+		return 0;
+	}
+
+	/* check if monitor is configured and usable */
+	mi = backend_info( "monitor" );
+	if ( !mi || !mi->bi_extra ) {
+		SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING;
+		return 0;
+ 	}
+ 	mbe = mi->bi_extra;
+
+	/* don't bother if monitor is not configured */
+	if ( !mbe->is_configured() ) {
+		static int warning = 0;
+
+		if ( warning++ == 0 ) {
+			Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: "
+				"monitoring disabled; "
+				"configure monitor database to enable\n",
+				0, 0, 0 );
+		}
+
+		return 0;
+	}
+
+	/* set up the fake subsystem that is used to create
+	 * the volatile connection entries */
+	li->li_monitor_info.lmi_mss.mss_name = "back-ldap";
+	li->li_monitor_info.lmi_mss.mss_flags = MONITOR_F_VOLATILE_CH;
+	li->li_monitor_info.lmi_mss.mss_create = ldap_back_monitor_conn_create;
+
+	li->li_monitor_info.lmi_li = li;
+	li->li_monitor_info.lmi_scope = LDAP_SCOPE_SUBORDINATE;
+	base = &li->li_monitor_info.lmi_base;
+	BER_BVSTR( base, "cn=databases,cn=monitor" );
+	filter = &li->li_monitor_info.lmi_filter;
+	BER_BVZERO( filter );
+
+	suffix.bv_len = ldap_bv2escaped_filter_value_len( &be->be_nsuffix[ 0 ] );
+	if ( suffix.bv_len == be->be_nsuffix[ 0 ].bv_len ) {
+		suffix = be->be_nsuffix[ 0 ];
+
+	} else {
+		ldap_bv2escaped_filter_value( &be->be_nsuffix[ 0 ], &suffix );
+	}
+	
+	filter->bv_len = STRLENOF( "(&" )
+		+ li->li_monitor_info.lmi_more_filter.bv_len
+		+ STRLENOF( "(monitoredInfo=" )
+		+ strlen( be->bd_info->bi_type )
+		+ STRLENOF( ")(!(monitorOverlay=" )
+		+ strlen( be->bd_info->bi_type )
+		+ STRLENOF( "))(namingContexts:distinguishedNameMatch:=" )
+		+ suffix.bv_len + STRLENOF( "))" );
+	ptr = filter->bv_val = ch_malloc( filter->bv_len + 1 );
+	ptr = lutil_strcopy( ptr, "(&" );
+	ptr = lutil_strncopy( ptr, li->li_monitor_info.lmi_more_filter.bv_val,
+		li->li_monitor_info.lmi_more_filter.bv_len );
+	ptr = lutil_strcopy( ptr, "(monitoredInfo=" );
+	ptr = lutil_strcopy( ptr, be->bd_info->bi_type );
+	ptr = lutil_strcopy( ptr, ")(!(monitorOverlay=" );
+	ptr = lutil_strcopy( ptr, be->bd_info->bi_type );
+	ptr = lutil_strcopy( ptr, "))(namingContexts:distinguishedNameMatch:=" );
+	ptr = lutil_strncopy( ptr, suffix.bv_val, suffix.bv_len );
+	ptr = lutil_strcopy( ptr, "))" );
+	ptr[ 0 ] = '\0';
+	assert( filter->bv_len == ptr - filter->bv_val );
+
+	if ( suffix.bv_val != be->be_nsuffix[ 0 ].bv_val ) {
+		ch_free( suffix.bv_val );
+	}
+
+	now = slap_get_time();
+	timestamp.bv_val = timebuf;
+	timestamp.bv_len = sizeof( timebuf );
+	slap_timestamp( &now, &timestamp );
+
+	/* caller (e.g. an overlay based on back-ldap) may want to use
+	 * a different RDN... */
+	if ( BER_BVISNULL( &li->li_monitor_info.lmi_rdn ) ) {
+		ber_str2bv( "cn=Connections", 0, 1, &li->li_monitor_info.lmi_rdn );
+	}
+
+	ptr = ber_bvchr( &li->li_monitor_info.lmi_rdn, '=' );
+	assert( ptr != NULL );
+	ptr[ 0 ] = '\0';
+	ptr++;
+
+	snprintf( buf, sizeof( buf ),
+		"dn: %s=%s\n"
+		"objectClass: monitorContainer\n"
+		"%s: %s\n"
+		"creatorsName: %s\n"
+		"createTimestamp: %s\n"
+		"modifiersName: %s\n"
+		"modifyTimestamp: %s\n",
+		li->li_monitor_info.lmi_rdn.bv_val,
+			ptr,
+		li->li_monitor_info.lmi_rdn.bv_val,
+			ptr,
+		BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val,
+		timestamp.bv_val,
+		BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val,
+		timestamp.bv_val );
+	e = str2entry( buf );
+	if ( e == NULL ) {
+		rc = -1;
+		goto cleanup;
+	}
+
+	ptr[ -1 ] = '=';
+
+	/* add labeledURI and special, modifiable URI value */
+	if ( li->li_uri != NULL ) {
+		struct berval	bv;
+		LDAPURLDesc	*ludlist = NULL;
+		int		rc;
+
+		rc = ldap_url_parselist_ext( &ludlist,
+			li->li_uri, NULL,
+			LDAP_PVT_URL_PARSE_NOEMPTY_HOST
+				| LDAP_PVT_URL_PARSE_DEF_PORT );
+		if ( rc != LDAP_URL_SUCCESS ) {
+			Debug( LDAP_DEBUG_ANY,
+				"ldap_back_monitor_db_open: "
+				"unable to parse URI list (ignored)\n",
+				0, 0, 0 );
+		} else {
+			for ( ; ludlist != NULL; ) {
+				LDAPURLDesc	*next = ludlist->lud_next;
+
+				bv.bv_val = ldap_url_desc2str( ludlist );
+				assert( bv.bv_val != NULL );
+				ldap_free_urldesc( ludlist );
+				bv.bv_len = strlen( bv.bv_val );
+				attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI,
+					&bv, NULL );
+				ch_free( bv.bv_val );
+
+				ludlist = next;
+			}
+		}
+		
+		ber_str2bv( li->li_uri, 0, 0, &bv );
+		attr_merge_normalize_one( e, ad_olmDbURIList,
+			&bv, NULL );
+	}
+
+	ber_dupbv( &li->li_monitor_info.lmi_nrdn, &e->e_nname );
+
+	cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
+	cb->mc_update = ldap_back_monitor_update;
+	cb->mc_modify = ldap_back_monitor_modify;
+	cb->mc_free = ldap_back_monitor_free;
+	cb->mc_private = (void *)li;
+
+	rc = mbe->register_entry_parent( e, cb,
+		(monitor_subsys_t *)&li->li_monitor_info,
+		MONITOR_F_VOLATILE_CH,
+		base, LDAP_SCOPE_SUBORDINATE, filter );
+
+cleanup:;
+	if ( rc != 0 ) {
+		if ( cb != NULL ) {
+			ch_free( cb );
+			cb = NULL;
+		}
+
+		if ( e != NULL ) {
+			entry_free( e );
+			e = NULL;
+		}
+
+		if ( !BER_BVISNULL( filter ) ) {
+			ch_free( filter->bv_val );
+			BER_BVZERO( filter );
+		}
+	}
+
+	/* store for cleanup */
+	li->li_monitor_info.lmi_cb = (void *)cb;
+
+	if ( e != NULL ) {
+		entry_free( e );
+	}
+
+	return rc;
+}
+
+/*
+ * call from within ldap_back_db_close()
+ */
+int
+ldap_back_monitor_db_close( BackendDB *be )
+{
+	ldapinfo_t		*li = (ldapinfo_t *) be->be_private;
+
+	if ( li && !BER_BVISNULL( &li->li_monitor_info.lmi_filter ) ) {
+		BackendInfo		*mi;
+		monitor_extra_t		*mbe;
+
+		/* check if monitor is configured and usable */
+		mi = backend_info( "monitor" );
+		if ( mi && mi->bi_extra ) {
+ 			mbe = mi->bi_extra;
+
+			mbe->unregister_entry_parent(
+				&li->li_monitor_info.lmi_nrdn,
+				(monitor_callback_t *)li->li_monitor_info.lmi_cb,
+				&li->li_monitor_info.lmi_base,
+				li->li_monitor_info.lmi_scope,
+				&li->li_monitor_info.lmi_filter );
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * call from within ldap_back_db_destroy()
+ */
+int
+ldap_back_monitor_db_destroy( BackendDB *be )
+{
+	ldapinfo_t		*li = (ldapinfo_t *) be->be_private;
+
+	if ( li ) {
+		(void)ldap_back_monitor_info_destroy( li );
+	}
+
+	return 0;
+}
+

Modified: openldap/trunk/servers/slapd/back-ldap/proto-ldap.h
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/proto-ldap.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/proto-ldap.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/proto-ldap.h,v 1.3.2.13 2007/01/13 11:19:07 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/proto-ldap.h,v 1.15.2.5 2007/08/31 23:14:02 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -24,13 +24,11 @@
 LDAP_BEGIN_DECL
 
 extern BI_init			ldap_back_initialize;
-
 extern BI_open			ldap_back_open;
-extern BI_close			ldap_back_close;
-extern BI_destroy		ldap_back_destroy;
 
 extern BI_db_init		ldap_back_db_init;
 extern BI_db_open		ldap_back_db_open;
+extern BI_db_close		ldap_back_db_close;
 extern BI_db_destroy		ldap_back_db_destroy;
 
 extern BI_op_bind		ldap_back_bind;
@@ -65,6 +63,7 @@
 
 extern ldapconn_t * ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc );
 
+#if 0
 extern int
 ldap_back_proxy_authz_ctrl(
 		struct berval	*bound_ndn,
@@ -78,7 +77,27 @@
 ldap_back_proxy_authz_ctrl_free(
 		Operation	*op,
 		LDAPControl	***pctrls );
+#endif
 
+extern int
+ldap_back_proxy_authz_ctrl(
+		Operation	*op,
+		SlapReply	*rs,
+		struct berval	*bound_ndn,
+		int		version,
+		slap_idassert_t	*si,
+		LDAPControl	*ctrl );
+
+extern int
+ldap_back_controls_add(
+		Operation	*op,
+		SlapReply	*rs,
+		ldapconn_t	*lc,
+		LDAPControl	***pctrls );
+
+extern int
+ldap_back_controls_free( Operation *op, SlapReply *rs, LDAPControl ***pctrls );
+
 extern void
 ldap_back_quarantine(
 	Operation	*op,
@@ -97,9 +116,18 @@
 extern int slap_idassert_authzfrom_parse_cf( const char *fname, int lineno, const char *arg, slap_idassert_t *si );
 extern int slap_idassert_parse_cf( const char *fname, int lineno, int argc, char *argv[], slap_idassert_t *si );
 
-extern int chain_init( void );
+extern int chain_initialize( void );
+#ifdef SLAP_DISTPROC
+extern int distproc_initialize( void );
+#endif
 
+extern int ldap_back_monitor_db_init( BackendDB *be );
+extern int ldap_back_monitor_db_open( BackendDB *be );
+extern int ldap_back_monitor_db_close( BackendDB *be );
+extern int ldap_back_monitor_db_destroy( BackendDB *be );
+
 extern LDAP_REBIND_PROC		ldap_back_default_rebind;
+extern LDAP_URLLIST_PROC	ldap_back_default_urllist;
 
 LDAP_END_DECL
 

Modified: openldap/trunk/servers/slapd/back-ldap/search.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* search.c - ldap backend search function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/search.c,v 1.148.2.40 2007/09/29 09:06:51 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/search.c,v 1.201.2.8 2007/09/29 09:55:22 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -205,8 +205,7 @@
 	}
 
 	ctrls = op->o_ctrls;
-	rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-		li->li_version, &li->li_idassert, op, rs, &ctrls );
+	rc = ldap_back_controls_add( op, rs, lc, &ctrls );
 	if ( rc != LDAP_SUCCESS ) {
 		goto finish;
 	}
@@ -469,22 +468,8 @@
 			}
 
 			if ( match.bv_val != NULL ) {
-#ifndef LDAP_NULL_IS_NULL
-				if ( match.bv_val[ 0 ] == '\0' ) {
-					LDAP_FREE( match.bv_val );
-					BER_BVZERO( &match );
-				} else
-#endif /* LDAP_NULL_IS_NULL */
-				{
-					match.bv_len = strlen( match.bv_val );
-				}
+				match.bv_len = strlen( match.bv_val );
 			}
-#ifndef LDAP_NULL_IS_NULL
-			if ( rs->sr_text != NULL && rs->sr_text[ 0 ] == '\0' ) {
-				LDAP_FREE( (char *)rs->sr_text );
-				rs->sr_text = NULL;
-			}
-#endif /* LDAP_NULL_IS_NULL */
 
 			rc = 0;
 			break;
@@ -543,7 +528,7 @@
 		send_ldap_result( op, rs );
 	}
 
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	if ( rs->sr_ctrls ) {
 		ldap_controls_free( rs->sr_ctrls );
@@ -642,13 +627,10 @@
 		slap_syntax_validate_func	*validate;
 		slap_syntax_transform_func	*pretty;
 
-		attr = (Attribute *)ch_malloc( sizeof( Attribute ) );
+		attr = attr_alloc( NULL );
 		if ( attr == NULL ) {
 			continue;
 		}
-		attr->a_flags = 0;
-		attr->a_next = 0;
-		attr->a_desc = NULL;
 		if ( slap_bv2ad( &a, &attr->a_desc, &text ) 
 				!= LDAP_SUCCESS )
 		{
@@ -659,7 +641,7 @@
 					"%s ldap_build_entry: "
 					"slap_bv2undef_ad(%s): %s\n",
 					op->o_log_prefix, a.bv_val, text );
-				ch_free( attr );
+				attr_free( attr );
 				continue;
 			}
 		}
@@ -682,7 +664,7 @@
 			 */
 			( void )ber_scanf( &ber, "x" /* [W] */ );
 
-			ch_free( attr );
+			attr_free( attr );
 			continue;
 		}
 		
@@ -694,11 +676,6 @@
 			 * values result filter
 			 */
 			attr->a_vals = (struct berval *)&slap_dummy_bv;
-			last = 0;
-
-		} else {
-			for ( last = 0; !BER_BVISNULL( &attr->a_vals[ last ] ); last++ )
-				/* just count vals */ ;
 		}
 
 		validate = attr->a_desc->ad_type->sat_syntax->ssyn_validate;
@@ -710,7 +687,7 @@
 			goto next_attr;
 		}
 
-		for ( i = 0; i < last; i++ ) {
+		for ( i = 0; !BER_BVISNULL( &attr->a_vals[i] ); i++ ) {
 			struct berval	pval;
 			int		rc;
 
@@ -742,6 +719,7 @@
 				attr->a_vals[i] = pval;
 			}
 		}
+		attr->a_numvals = last = i;
 
 		if ( last && attr->a_desc->ad_type->sat_equality &&
 				attr->a_desc->ad_type->sat_equality->smr_normalize )
@@ -763,7 +741,7 @@
 
 				if ( rc != LDAP_SUCCESS ) {
 					BER_BVZERO( &attr->a_nvals[i] );
-					ch_free( attr );
+					attr_free( attr );
 					goto next_attr;
 				}
 			}
@@ -843,8 +821,7 @@
 
 retry:
 	ctrls = op->o_ctrls;
-	rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-		li->li_version, &li->li_idassert, op, &rs, &ctrls );
+	rc = ldap_back_controls_add( op, &rs, lc, &ctrls );
 	if ( rc != LDAP_SUCCESS ) {
 		goto cleanup;
 	}
@@ -858,7 +835,7 @@
 			do_retry = 0;
 			if ( ldap_back_retry( &lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
 				/* if the identity changed, there might be need to re-authz */
-				(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+				(void)ldap_back_controls_free( op, &rs, &ctrls );
 				goto retry;
 			}
 		}
@@ -871,7 +848,7 @@
 		goto cleanup;
 	}
 
-	*ent = ch_calloc( 1, sizeof( Entry ) );
+	*ent = entry_alloc();
 	if ( *ent == NULL ) {
 		rc = LDAP_NO_MEMORY;
 		goto cleanup;
@@ -885,7 +862,7 @@
 	}
 
 cleanup:
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, &rs, &ctrls );
 
 	if ( result ) {
 		ldap_msgfree( result );

Modified: openldap/trunk/servers/slapd/back-ldap/unbind.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldap/unbind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldap/unbind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* unbind.c - ldap backend unbind function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/unbind.c,v 1.24.2.10 2007/01/17 23:03:20 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/unbind.c,v 1.33.2.3 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-ldif/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-ldif/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldif/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-ldif
-# $OpenLDAP: pkg/ldap/servers/slapd/back-ldif/Makefile.in,v 1.1.2.4 2007/01/02 21:44:03 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-ldif/Makefile.in,v 1.2.2.2 2007/08/31 23:14:03 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 2005-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-ldif/ldif.c
===================================================================
--- openldap/trunk/servers/slapd/back-ldif/ldif.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-ldif/ldif.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ldif.c - the ldif backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldif/ldif.c,v 1.1.2.23 2007/10/10 16:57:13 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldif/ldif.c,v 1.48.2.9 2007/11/27 20:27:31 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2005-2007 The OpenLDAP Foundation.
@@ -97,7 +97,9 @@
 
 	dn = *orig_dn;
 
-	for ( ptr = dn.bv_val, end = &dn.bv_val[dn.bv_len]; ptr < end; ptr++) {
+	/* escape dirsep's
+	 * use "\" + hexpair, so the escaped DN remains formally valid */
+	for ( ptr = dn.bv_val, end = &dn.bv_val[dn.bv_len]; ptr < end; ptr++ ) {
 		if ( ptr[0] == LDAP_DIRSEP[0] ) {
 			nsep++;
 		}
@@ -114,7 +116,7 @@
 		{
 			static const char hex[] = "0123456789ABCDEF";
 			if ( ptr[0] == LDAP_DIRSEP[0] ) {
-				*p++ = '\\';	/* FIXME: fs-escape */
+				*p++ = '\\';
 				*p++ = hex[(LDAP_DIRSEP[0] & 0xF0U) >> 4];
 				*p = hex[LDAP_DIRSEP[0] & 0x0FU];
 			} else {
@@ -138,14 +140,22 @@
 	}
 	strcpy(ptr, LDIF);
 #if IX_FSL != IX_DNL
-	ptr = res->bv_val;
-	while( ptr=strchr(ptr, IX_DNL) ) {
-		*ptr++ = IX_FSL;
-		ptr = strchr(ptr, IX_DNR);
-		if ( ptr )
+	{
+		struct berval bv;
+		bv = *res;
+		while ( ptr = ber_bvchr( &bv, IX_DNL ) ) {
+			*ptr++ = IX_FSL;
+			assert( ( ptr - bv.bv_val ) <= bv.bv_len );
+			bv.bv_len -= ( ptr - bv.bv_val );
+			bv.bv_val = ptr;
+			ptr = ber_bvchr( &bv, IX_DNR );
+			if ( !ptr )
+				break;
 			*ptr++ = IX_FSR;
-		else
-			break;
+			assert( ( ptr - bv.bv_val ) <= bv.bv_len );
+			bv.bv_len -= ( ptr - bv.bv_val );
+			bv.bv_val = ptr;
+		}
 	}
 #endif
 	if ( dn.bv_val != orig_dn->bv_val ) {
@@ -184,14 +194,16 @@
 	return entry;
 }
 
+/*
+ * return number of bytes written, or -1 in case of error
+ * do not return numbers less than -1
+ */
 static int spew_file(int fd, char * spew, int len) {
 	int writeres = 0;
 	
 	while(len > 0) {
 		writeres = write(fd, spew, len);
 		if(writeres == -1) {
-			Debug( LDAP_DEBUG_ANY, "could not spew write: %s\n",
-				STRERROR( errno ), 0, 0 );
 			return -1;
 		}
 		else {
@@ -202,23 +214,28 @@
 	return writeres;
 }
 
-static int spew_entry(Entry * e, struct berval * path) {
-	int rs;
+static int
+spew_entry( Entry * e, struct berval * path, int dolock, int *save_errnop )
+{
+	int rs, save_errno = 0;
 	int openres;
-	int spew_res;
+	int res, spew_res;
 	int entry_length;
 	char * entry_as_string;
+	char *tmpfname = NULL;
 
-	openres = open(path->bv_val, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR);
-	if(openres == -1) {
-		if(errno == ENOENT)
-			rs = LDAP_NO_SUCH_OBJECT;
-		else
-			rs = LDAP_UNWILLING_TO_PERFORM;
-		Debug( LDAP_DEBUG_ANY, "could not open \"%s\": %s\n",
-			path->bv_val, STRERROR( errno ), 0 );
-	}
-	else {
+	tmpfname = ch_malloc( path->bv_len + STRLENOF( "XXXXXX" ) + 1 );
+	AC_MEMCPY( tmpfname, path->bv_val, path->bv_len );
+	AC_MEMCPY( &tmpfname[ path->bv_len ], "XXXXXX", STRLENOF( "XXXXXX" ) + 1 );
+
+	openres = mkstemp( tmpfname );
+	if ( openres == -1 ) {
+		save_errno = errno;
+		rs = LDAP_UNWILLING_TO_PERFORM;
+		Debug( LDAP_DEBUG_ANY, "could not create tmpfile \"%s\": %s\n",
+			tmpfname, STRERROR( save_errno ), 0 );
+
+	} else {
 		struct berval rdn;
 		int tmp;
 
@@ -231,27 +248,71 @@
 			rdn.bv_len = tmp;
 		}
 
+		spew_res = -2;
+		if ( dolock ) {
+			ldap_pvt_thread_mutex_lock(&entry2str_mutex);
+		}
+
 		entry_as_string = entry2str(e, &entry_length);
+		if ( entry_as_string != NULL ) {
+			spew_res = spew_file( openres,
+				entry_as_string, entry_length );
+			if ( spew_res == -1 ) {
+				save_errno = errno;
+			}
+		}
 
+		if ( dolock ) {
+			ldap_pvt_thread_mutex_unlock(&entry2str_mutex);
+		}
+
 		/* Restore full DN */
 		if ( rdn.bv_len != e->e_name.bv_len ) {
 			e->e_name.bv_val[e->e_name.bv_len] = ',';
 			e->e_name.bv_len = rdn.bv_len;
 		}
 
-		if(entry_as_string == NULL) {
-			rs = LDAP_UNWILLING_TO_PERFORM;
-			close(openres);
+		res = close( openres );
+		rs = LDAP_UNWILLING_TO_PERFORM;
+
+		if ( spew_res > -2 ) {
+			if ( res == -1 || spew_res == -1 ) {
+				if ( save_errno == 0 ) {
+					save_errno = errno;
+				}
+				Debug( LDAP_DEBUG_ANY, "write error to tmpfile \"%s\": %s\n",
+					tmpfname, STRERROR( save_errno ), 0 );
+
+			} else {
+				res = rename( tmpfname, path->bv_val );
+				if ( res == 0 ) {
+					rs = LDAP_SUCCESS;
+
+				} else {
+					save_errno = errno;
+					switch ( save_errno ) {
+					case ENOENT:
+						rs = LDAP_NO_SUCH_OBJECT;
+						break;
+
+					default:
+						break;
+					}
+				}
+			}
 		}
-		else {
-			spew_res = spew_file(openres, entry_as_string, entry_length);
-			close(openres);
-			if(spew_res == -1)
-				rs = LDAP_UNWILLING_TO_PERFORM;
-			else
-				rs = LDAP_SUCCESS;
+
+		if ( rs != LDAP_SUCCESS ) {
+			unlink( tmpfname );
 		}
 	}
+
+	ch_free( tmpfname );
+
+	if ( rs != LDAP_SUCCESS && save_errnop != NULL ) {
+		*save_errnop = save_errno;
+	}
+
 	return rs;
 }
 
@@ -327,7 +388,7 @@
 	struct bvlist *next;
 	struct berval bv;
 	struct berval num;
-	unsigned int inum;
+	int inum;
 	int off;
 } bvlist;
 
@@ -340,7 +401,7 @@
 
 	fd = open( path->bv_val, O_RDONLY );
 	if ( fd < 0 ) {
-		Debug( LDAP_DEBUG_ANY,
+		Debug( LDAP_DEBUG_TRACE,
 			"=> ldif_enum_tree: failed to open %s: %s\n",
 			path->bv_val, STRERROR(errno), 0 );
 		return LDAP_NO_SUCH_OBJECT;
@@ -446,11 +507,13 @@
 			bvl = ch_malloc( sizeof(bvlist) );
 			ber_dupbv( &bvl->bv, &fname );
 			BER_BVZERO( &bvl->num );
-			itmp.bv_val = strchr( bvl->bv.bv_val, IX_FSL );
+			itmp.bv_val = ber_bvchr( &bvl->bv, IX_FSL );
 			if ( itmp.bv_val ) {
 				char *ptr;
 				itmp.bv_val++;
-				ptr = strchr( itmp.bv_val, IX_FSR );
+				itmp.bv_len = bvl->bv.bv_len
+					- ( itmp.bv_val - bvl->bv.bv_val );
+				ptr = ber_bvchr( &itmp, IX_FSR );
 				if ( ptr ) {
 					itmp.bv_len = ptr - itmp.bv_val;
 					ber_dupbv( &bvl->num, &itmp );
@@ -507,14 +570,14 @@
 	enumCookie *ck
 )
 {
-	struct ldif_info *ni = (struct ldif_info *) ck->op->o_bd->be_private;
+	struct ldif_info *li = (struct ldif_info *) ck->op->o_bd->be_private;
 	struct berval path;
 	struct berval pdn, pndn;
 	int rc;
 
 	dnParent( &ck->op->o_req_dn, &pdn );
 	dnParent( &ck->op->o_req_ndn, &pndn );
-	dn2path( &ck->op->o_req_ndn, &ck->op->o_bd->be_nsuffix[0], &ni->li_base_path, &path);
+	dn2path( &ck->op->o_req_ndn, &ck->op->o_bd->be_nsuffix[0], &li->li_base_path, &path);
 	rc = r_enum_tree(ck, &path, &pdn, &pndn);
 	ch_free( path.bv_val );
 	return rc;
@@ -608,7 +671,7 @@
 			entry->e_ocflags = 0;
 		}
 		/* check that the entry still obeys the schema */
-		rc = entry_schema_check( op, entry, NULL, 0,
+		rc = entry_schema_check( op, entry, NULL, 0, 0,
 			  &rs->sr_text, textbuf, sizeof( textbuf ) );
 	}
 
@@ -618,7 +681,7 @@
 int
 ldif_back_referrals( Operation *op, SlapReply *rs )
 {
-	struct ldif_info	*ni = NULL;
+	struct ldif_info	*li = NULL;
 	Entry			*entry;
 	int			rc = LDAP_SUCCESS;
 
@@ -634,9 +697,9 @@
 		return rc;
 	}
 
-	ni = (struct ldif_info *)op->o_bd->be_private;
-	ldap_pvt_thread_rdwr_rlock( &ni->li_rdwr );
-	entry = (Entry *)get_entry( op, &ni->li_base_path );
+	li = (struct ldif_info *)op->o_bd->be_private;
+	ldap_pvt_thread_rdwr_rlock( &li->li_rdwr );
+	entry = get_entry( op, &li->li_base_path );
 
 	/* no object is found for them */
 	if ( entry == NULL ) {
@@ -655,10 +718,10 @@
 			op->o_req_dn = pndn;
 			op->o_req_ndn = pndn;
 
-			entry = (Entry *)get_entry( op, &ni->li_base_path );
+			entry = get_entry( op, &li->li_base_path );
 		}
 
-		ldap_pvt_thread_rdwr_runlock( &ni->li_rdwr );
+		ldap_pvt_thread_rdwr_runlock( &li->li_rdwr );
 
 		op->o_req_dn = odn;
 		op->o_req_ndn = ondn;
@@ -667,8 +730,8 @@
 		rs->sr_matched = NULL;
 		if ( entry != NULL ) {
 			Debug( LDAP_DEBUG_TRACE,
-				"ldif_back_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
-				(long) op->o_tag, op->o_req_dn.bv_val, entry->e_name.bv_val );
+				"ldif_back_referrals: tag=%lu target=\"%s\" matched=\"%s\"\n",
+				(unsigned long) op->o_tag, op->o_req_dn.bv_val, entry->e_name.bv_val );
 
 			if ( is_entry_referral( entry ) ) {
 				rc = LDAP_OTHER;
@@ -708,7 +771,7 @@
 		return rc;
 	}
 
-	ldap_pvt_thread_rdwr_runlock( &ni->li_rdwr );
+	ldap_pvt_thread_rdwr_runlock( &li->li_rdwr );
 
 	if ( is_entry_referral( entry ) ) {
 		/* entry is a referral */
@@ -717,8 +780,8 @@
 			refs, &entry->e_name, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
 
 		Debug( LDAP_DEBUG_TRACE,
-			"ldif_back_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
-			(long) op->o_tag, op->o_req_dn.bv_val, entry->e_name.bv_val );
+			"ldif_back_referrals: tag=%lu target=\"%s\" matched=\"%s\"\n",
+			(unsigned long) op->o_tag, op->o_req_dn.bv_val, entry->e_name.bv_val );
 
 		rs->sr_matched = entry->e_name.bv_val;
 		if ( rs->sr_ref != NULL ) {
@@ -744,23 +807,29 @@
 static int
 ldif_back_bind( Operation *op, SlapReply *rs )
 {
-	struct ldif_info *ni = NULL;
+	struct ldif_info *li = NULL;
 	Attribute * a = NULL;
 	AttributeDescription *password = slap_schema.si_ad_userPassword;
 	int return_val = 0;
 	Entry * entry = NULL;
 
-	ni = (struct ldif_info *) op->o_bd->be_private;
-	ldap_pvt_thread_rdwr_rlock(&ni->li_rdwr);
-	entry = (Entry *) get_entry(op, &ni->li_base_path);
+	switch ( be_rootdn_bind( op, rs ) ) {
+	case SLAP_CB_CONTINUE:
+		break;
 
+	default:
+		/* in case of success, front end will send result;
+		 * otherwise, be_rootdn_bind() did */
+		return rs->sr_err;
+	}
+
+	li = (struct ldif_info *) op->o_bd->be_private;
+	ldap_pvt_thread_rdwr_rlock(&li->li_rdwr);
+	entry = get_entry(op, &li->li_base_path);
+
 	/* no object is found for them */
 	if(entry == NULL) {
-		if(be_isroot_pw(op)) {
-			rs->sr_err = return_val = LDAP_SUCCESS;
-		} else {
-			rs->sr_err = return_val = LDAP_INVALID_CREDENTIALS;
-		}
+		rs->sr_err = return_val = LDAP_INVALID_CREDENTIALS;
 		goto return_result;
 	}
 
@@ -784,7 +853,7 @@
 	goto return_result;
 
  return_result:
-	ldap_pvt_thread_rdwr_runlock(&ni->li_rdwr);
+	ldap_pvt_thread_rdwr_runlock(&li->li_rdwr);
 	if(return_val != 0)
 		send_ldap_result( op, rs );
 	if(entry != NULL)
@@ -794,21 +863,21 @@
 
 static int ldif_back_search(Operation *op, SlapReply *rs)
 {
-	struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
+	struct ldif_info *li = (struct ldif_info *) op->o_bd->be_private;
 	enumCookie ck = { NULL, NULL, NULL, 0, 0 };
 
 	ck.op = op;
 	ck.rs = rs;
-	ldap_pvt_thread_rdwr_rlock(&ni->li_rdwr);
+	ldap_pvt_thread_rdwr_rlock(&li->li_rdwr);
 	rs->sr_err = enum_tree( &ck );
-	ldap_pvt_thread_rdwr_runlock(&ni->li_rdwr);
+	ldap_pvt_thread_rdwr_runlock(&li->li_rdwr);
 	send_ldap_result(op, rs);
 
 	return rs->sr_err;
 }
 
 static int ldif_back_add(Operation *op, SlapReply *rs) {
-	struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
+	struct ldif_info *li = (struct ldif_info *) op->o_bd->be_private;
 	Entry * e = op->ora_e;
 	struct berval dn = e->e_nname;
 	struct berval leaf_path = BER_BVNULL;
@@ -817,16 +886,19 @@
 	char textbuf[SLAP_TEXT_BUFLEN];
 
 	Debug( LDAP_DEBUG_TRACE, "ldif_back_add: \"%s\"\n", dn.bv_val, 0, 0);
-	slap_add_opattrs( op, &rs->sr_text, textbuf, sizeof( textbuf ), 1 );
 
-	rs->sr_err = entry_schema_check(op, e, NULL, 0,
+	rs->sr_err = entry_schema_check(op, e, NULL, 0, 1,
 		&rs->sr_text, textbuf, sizeof( textbuf ) );
 	if ( rs->sr_err != LDAP_SUCCESS ) goto send_res;
-				
-	ldap_pvt_thread_rdwr_wlock(&ni->li_rdwr);
 
-	dn2path(&dn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &leaf_path);
+	rs->sr_err = slap_add_opattrs( op,
+		&rs->sr_text, textbuf, sizeof( textbuf ), 1 );
+	if ( rs->sr_err != LDAP_SUCCESS ) goto send_res;
 
+	ldap_pvt_thread_rdwr_wlock(&li->li_rdwr);
+
+	dn2path(&dn, &op->o_bd->be_nsuffix[0], &li->li_base_path, &leaf_path);
+
 	if(leaf_path.bv_val != NULL) {
 		struct berval base = BER_BVNULL;
 		/* build path to container and ldif of container */
@@ -856,9 +928,7 @@
 		if(rs->sr_err == LDAP_SUCCESS) {
 			statres = stat(leaf_path.bv_val, &stats);
 			if(statres == -1 && errno == ENOENT) {
-				ldap_pvt_thread_mutex_lock(&entry2str_mutex);
-				rs->sr_err = (int) spew_entry(e, &leaf_path);
-				ldap_pvt_thread_mutex_unlock(&entry2str_mutex);
+				rs->sr_err = spew_entry(e, &leaf_path, 1, NULL);
 			}
 			else if ( statres == -1 ) {
 				rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
@@ -872,7 +942,7 @@
 		SLAP_FREE(leaf_path.bv_val);
 	}
 
-	ldap_pvt_thread_rdwr_wunlock(&ni->li_rdwr);
+	ldap_pvt_thread_rdwr_wunlock(&li->li_rdwr);
 
 send_res:
 	Debug( LDAP_DEBUG_TRACE, 
@@ -880,11 +950,11 @@
 				rs->sr_text : "", 0);
 	send_ldap_result(op, rs);
 	slap_graduate_commit_csn( op );
-	return 0;
+	return rs->sr_err;
 }
 
 static int ldif_back_modify(Operation *op, SlapReply *rs) {
-	struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
+	struct ldif_info *li = (struct ldif_info *) op->o_bd->be_private;
 	Modifications * modlst = op->orm_modlist;
 	struct berval path = BER_BVNULL;
 	Entry * entry = NULL;
@@ -892,19 +962,16 @@
 
 	slap_mods_opattrs( op, &op->orm_modlist, 1 );
 
-	ldap_pvt_thread_rdwr_wlock(&ni->li_rdwr);
-	dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path,
+	ldap_pvt_thread_rdwr_wlock(&li->li_rdwr);
+	dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &li->li_base_path,
 		&path);
-	entry = (Entry *) get_entry(op, &ni->li_base_path);
+	entry = get_entry(op, &li->li_base_path);
 
 	if(entry != NULL) {
 		rs->sr_err = apply_modify_to_entry(entry, modlst, op, rs);
 		if(rs->sr_err == LDAP_SUCCESS) {
 			int save_errno;
-			ldap_pvt_thread_mutex_lock(&entry2str_mutex);
-			spew_res = spew_entry(entry, &path);
-			save_errno = errno;
-			ldap_pvt_thread_mutex_unlock(&entry2str_mutex);
+			spew_res = spew_entry(entry, &path, 1, &save_errno);
 			if(spew_res == -1) {
 				Debug( LDAP_DEBUG_ANY,
 					"%s ldif_back_modify: could not output entry \"%s\": %s\n",
@@ -922,14 +989,14 @@
 	if(path.bv_val != NULL)
 		SLAP_FREE(path.bv_val);
 	rs->sr_text = NULL;
-	ldap_pvt_thread_rdwr_wunlock(&ni->li_rdwr);
+	ldap_pvt_thread_rdwr_wunlock(&li->li_rdwr);
 	send_ldap_result(op, rs);
 	slap_graduate_commit_csn( op );
-	return 0;
+	return rs->sr_err;
 }
 
 static int ldif_back_delete(Operation *op, SlapReply *rs) {
-	struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
+	struct ldif_info *li = (struct ldif_info *) op->o_bd->be_private;
 	struct berval path = BER_BVNULL;
 	int res = 0;
 
@@ -942,32 +1009,48 @@
 		slap_get_csn( op, &csn, 1 );
 	}
 
-	ldap_pvt_thread_rdwr_wlock(&ni->li_rdwr);
-	dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &path);
+	ldap_pvt_thread_rdwr_wlock(&li->li_rdwr);
+	dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &li->li_base_path, &path);
 
 	path.bv_val[path.bv_len - STRLENOF(LDIF)] = '\0';
 	res = rmdir(path.bv_val);
 	path.bv_val[path.bv_len - STRLENOF(LDIF)] = '.';
-	if ( res && errno != ENOENT ) {
-		rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
+	rs->sr_err = LDAP_SUCCESS;
+	if ( res ) {
+		switch ( errno ) {
+		case ENOTEMPTY:
+			rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
+			break;
+
+		case ENOENT:
+			rs->sr_err = LDAP_NO_SUCH_OBJECT;
+			break;
+
+		default:
+			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+			break;
+		}
+
 	} else {
 		res = unlink(path.bv_val);
-	}
+		if ( res == -1 ) {
+			switch ( errno ) {
+			case ENOENT:
+				rs->sr_err = LDAP_NO_SUCH_OBJECT;
+				break;
 
-	if(res == -1) {
-		if(errno == ENOENT)
-			rs->sr_err = LDAP_NO_SUCH_OBJECT;
-		else
-			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+			default:
+				rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+				break;
+			}
+		}
 	}
-	else
-		rs->sr_err = LDAP_SUCCESS;
 
 	SLAP_FREE(path.bv_val);
-	ldap_pvt_thread_rdwr_wunlock(&ni->li_rdwr);
+	ldap_pvt_thread_rdwr_wunlock(&li->li_rdwr);
 	send_ldap_result(op, rs);
 	slap_graduate_commit_csn( op );
-	return 0;
+	return rs->sr_err;
 }
 
 
@@ -990,10 +1073,13 @@
 		exists_res = open(newpath.bv_val, O_RDONLY);
 		if(exists_res == -1 && errno == ENOENT) {
 			ldap_pvt_thread_mutex_lock( &entry2str_mutex );
-			res = spew_entry(entry, &newpath);
+			res = spew_entry(entry, &newpath, 0, NULL);
 			if(res != -1) {
 				/* if this fails we should log something bad */
 				res = unlink(path.bv_val);
+				path.bv_val[path.bv_len - STRLENOF(".ldif")] = '\0';
+				newpath.bv_val[newpath.bv_len - STRLENOF(".ldif")] = '\0';
+				res = rename(path.bv_val, newpath.bv_val);
 				res = LDAP_SUCCESS;
 			}
 			else {
@@ -1024,89 +1110,73 @@
 	return res;
 }
 
-static int ldif_back_modrdn(Operation *op, SlapReply *rs) {
-	struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
+static int
+ldif_back_modrdn(Operation *op, SlapReply *rs)
+{
+	struct ldif_info *li = (struct ldif_info *) op->o_bd->be_private;
 	struct berval new_dn = BER_BVNULL, new_ndn = BER_BVNULL;
-	struct berval p_dn, bv = BER_BVNULL;
+	struct berval p_dn;
 	Entry * entry = NULL;
-	LDAPRDN new_rdn = NULL;
-	LDAPRDN old_rdn = NULL;
-	Modifications * mods = NULL;
 	int res;
 
-	ldap_pvt_thread_rdwr_wlock( &ni->li_rdwr );
-	entry = (Entry *) get_entry(op, &ni->li_base_path);
+	slap_mods_opattrs( op, &op->orr_modlist, 1 );
 
+	ldap_pvt_thread_rdwr_wlock( &li->li_rdwr );
+	entry = get_entry( op, &li->li_base_path );
+
 	/* build the mods to the entry */
-	if(entry != NULL) {
-		if(ldap_bv2rdn(&op->oq_modrdn.rs_newrdn, &new_rdn,
-			(char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP)) {
-			rs->sr_err = LDAP_INVALID_DN_SYNTAX;
-		}
-		else if(op->oq_modrdn.rs_deleteoldrdn &&
-			ldap_bv2rdn(&op->o_req_dn, &old_rdn, (char **)&rs->sr_text,
-			LDAP_DN_FORMAT_LDAP)) {
-			rs->sr_err = LDAP_OTHER;
-		}
-		else { /* got both rdns successfully, ready to build mods */
-			if(slap_modrdn2mods(op, rs, entry, old_rdn, new_rdn, &mods)
-				!= LDAP_SUCCESS) {
-				rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-			}
-			else { /* built mods successfully */
+	if ( entry != NULL ) {
+		/* build new dn, and new ndn for the entry */
+		if ( op->oq_modrdn.rs_newSup != NULL ) {
+			struct berval	op_dn = op->o_req_dn,
+					op_ndn = op->o_req_ndn;
+			Entry		*np;
 
-				/* build new dn, and new ndn for the entry */
-				if(op->oq_modrdn.rs_newSup != NULL) {
-					struct berval	op_dn = op->o_req_dn,
-							op_ndn = op->o_req_ndn;
-					Entry		*np;
-
-					/* new superior */
-					p_dn = *op->oq_modrdn.rs_newSup;
-					op->o_req_dn = *op->oq_modrdn.rs_newSup;
-					op->o_req_ndn = *op->oq_modrdn.rs_nnewSup;
-					np = (Entry *)get_entry( op, &ni->li_base_path );
-					op->o_req_dn = op_dn;
-					op->o_req_ndn = op_ndn;
-					if ( np == NULL ) {
-						goto no_such_object;
-					}
-					entry_free( np );
-				} else {
-					dnParent(&entry->e_name, &p_dn);
-				}
-				build_new_dn(&new_dn, &p_dn, &op->oq_modrdn.rs_newrdn, NULL); 
-				dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx );
-				ber_dupbv( &new_ndn, &bv );
-				entry->e_name = new_dn;
-				entry->e_nname = new_ndn;
-
-				/* perform the modifications */
-				res = apply_modify_to_entry(entry, mods, op, rs);
-				if(res == LDAP_SUCCESS) {
-					rs->sr_err = move_entry(entry, &op->o_req_ndn,
-								&new_ndn,
-								&op->o_bd->be_nsuffix[0],
-								&ni->li_base_path);
-				} else {
-					rs->sr_err = res;
-				}
+			/* new superior */
+			p_dn = *op->oq_modrdn.rs_newSup;
+			op->o_req_dn = *op->oq_modrdn.rs_newSup;
+			op->o_req_ndn = *op->oq_modrdn.rs_nnewSup;
+			np = get_entry( op, &li->li_base_path );
+			op->o_req_dn = op_dn;
+			op->o_req_ndn = op_ndn;
+			if ( np == NULL ) {
+				goto no_such_object;
 			}
+			entry_free( np );
+		} else {
+			dnParent( &entry->e_name, &p_dn );
 		}
+		build_new_dn( &new_dn, &p_dn, &op->oq_modrdn.rs_newrdn, NULL ); 
+		dnNormalize( 0, NULL, NULL, &new_dn, &new_ndn, NULL );
+		ber_memfree_x( entry->e_name.bv_val, NULL );
+		ber_memfree_x( entry->e_nname.bv_val, NULL );
+		entry->e_name = new_dn;
+		entry->e_nname = new_ndn;
+
+		/* perform the modifications */
+		res = apply_modify_to_entry( entry, op->orr_modlist, op, rs );
+		if ( res == LDAP_SUCCESS ) {
+			rs->sr_err = move_entry( entry, &op->o_req_ndn,
+						&new_ndn,
+						&op->o_bd->be_nsuffix[0],
+						&li->li_base_path );
+		} else {
+			rs->sr_err = res;
+		}
 	} else {
 no_such_object:;
-	/* entry was null */
+		/* entry was null */
 		rs->sr_err = LDAP_NO_SUCH_OBJECT;
 	}
 
 	if ( entry != NULL ) {
-		entry_free(entry);
+		entry_free( entry );
 	}
 	rs->sr_text = "";
-	ldap_pvt_thread_rdwr_wunlock( &ni->li_rdwr );
-	send_ldap_result(op, rs);
+	ldap_pvt_thread_rdwr_wunlock( &li->li_rdwr );
+	send_ldap_result( op, rs );
 	slap_graduate_commit_csn( op );
-	return 0;
+	return rs->sr_err;
 }
 
 /* return LDAP_SUCCESS IFF we can retrieve the specified entry.
@@ -1119,19 +1189,19 @@
 	int rw,
 	Entry **ent )
 {
-	struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
+	struct ldif_info *li = (struct ldif_info *) op->o_bd->be_private;
 	struct berval op_dn = op->o_req_dn, op_ndn = op->o_req_ndn;
 
 	assert( ndn != NULL );
 	assert( !BER_BVISNULL( ndn ) );
 
-	ldap_pvt_thread_rdwr_rlock( &ni->li_rdwr );
+	ldap_pvt_thread_rdwr_rlock( &li->li_rdwr );
 	op->o_req_dn = *ndn;
 	op->o_req_ndn = *ndn;
-	*ent = (Entry *) get_entry( op, &ni->li_base_path );
+	*ent = get_entry( op, &li->li_base_path );
 	op->o_req_dn = op_dn;
 	op->o_req_ndn = op_ndn;
-	ldap_pvt_thread_rdwr_runlock( &ni->li_rdwr );
+	ldap_pvt_thread_rdwr_runlock( &li->li_rdwr );
 
 	if ( *ent && oc && !is_entry_objectclass_or_sub( *ent, oc ) ) {
 		entry_free( *ent );
@@ -1141,72 +1211,69 @@
 	return ( *ent == NULL ? 1 : 0 );
 }
 
-static int ldif_tool_entry_open(BackendDB * be, int mode) {
-	struct ldif_info *ni = (struct ldif_info *) be->be_private;
-	ni->li_tool_current = 0;
+static int ldif_tool_entry_open(BackendDB *be, int mode) {
+	struct ldif_info *li = (struct ldif_info *) be->be_private;
+	li->li_tool_current = 0;
 	return 0;
 }					
 
 static int ldif_tool_entry_close(BackendDB * be) {
-	struct ldif_info *ni = (struct ldif_info *) be->be_private;
+	struct ldif_info *li = (struct ldif_info *) be->be_private;
 
-	SLAP_FREE(ni->li_tool_cookie.entries);
+	SLAP_FREE(li->li_tool_cookie.entries);
 	return 0;
 }
 
+static ID ldif_tool_entry_next(BackendDB *be)
+{
+	struct ldif_info *li = (struct ldif_info *) be->be_private;
+	if(li->li_tool_current >= li->li_tool_cookie.eind)
+		return NOID;
+	else
+		return ++li->li_tool_current;
+}
+
 static ID
 ldif_tool_entry_first(BackendDB *be)
 {
-	struct ldif_info *ni = (struct ldif_info *) be->be_private;
-	ID id = 1; /* first entry in the array of entries shifted by one */
+	struct ldif_info *li = (struct ldif_info *) be->be_private;
 
-	ni->li_tool_current = 1;
-	if(ni->li_tool_cookie.entries == NULL) {
+	if(li->li_tool_cookie.entries == NULL) {
 		Operation op = {0};
 
 		op.o_bd = be;
 		op.o_req_dn = *be->be_suffix;
 		op.o_req_ndn = *be->be_nsuffix;
 		op.ors_scope = LDAP_SCOPE_SUBTREE;
-		ni->li_tool_cookie.op = &op;
-		(void)enum_tree( &ni->li_tool_cookie );
-		ni->li_tool_cookie.op = NULL;
+		li->li_tool_cookie.op = &op;
+		(void)enum_tree( &li->li_tool_cookie );
+		li->li_tool_cookie.op = NULL;
 	}
-	return id;
+	return ldif_tool_entry_next( be );
 }
 
-static ID ldif_tool_entry_next(BackendDB *be)
-{
-	struct ldif_info *ni = (struct ldif_info *) be->be_private;
-	ni->li_tool_current += 1;
-	if(ni->li_tool_current > ni->li_tool_cookie.eind)
-		return NOID;
-	else
-		return ni->li_tool_current;
-}
-
 static Entry * ldif_tool_entry_get(BackendDB * be, ID id) {
-	struct ldif_info *ni = (struct ldif_info *) be->be_private;
+	struct ldif_info *li = (struct ldif_info *) be->be_private;
 	Entry * e;
 
-	if(id > ni->li_tool_cookie.eind || id < 1)
+	if(id > li->li_tool_cookie.eind || id < 1)
 		return NULL;
 	else {
-		e = ni->li_tool_cookie.entries[id - 1];
-		ni->li_tool_cookie.entries[id - 1] = NULL;
+		e = li->li_tool_cookie.entries[id - 1];
+		li->li_tool_cookie.entries[id - 1] = NULL;
 		return e;
 	}
 }
 
 static ID ldif_tool_entry_put(BackendDB * be, Entry * e, struct berval *text) {
-	struct ldif_info *ni = (struct ldif_info *) be->be_private;
+	struct ldif_info *li = (struct ldif_info *) be->be_private;
 	struct berval dn = e->e_nname;
 	struct berval leaf_path = BER_BVNULL;
 	struct stat stats;
 	int statres;
 	int res = LDAP_SUCCESS;
 
-	dn2path(&dn, &be->be_nsuffix[0], &ni->li_base_path, &leaf_path);
+	dn2path(&dn, &be->be_nsuffix[0], &li->li_base_path, &leaf_path);
 
 	if(leaf_path.bv_val != NULL) {
 		struct berval base = BER_BVNULL;
@@ -1233,7 +1300,7 @@
 		if(res == LDAP_SUCCESS) {
 			statres = stat(leaf_path.bv_val, &stats);
 			if(statres == -1 && errno == ENOENT) {
-				res = (int) spew_entry(e, &leaf_path);
+				res = spew_entry(e, &leaf_path, 0, NULL);
 			}
 			else /* it already exists */
 				res = LDAP_ALREADY_EXISTS;
@@ -1250,37 +1317,33 @@
 }
 
 static int
-ldif_back_db_init( BackendDB *be )
+ldif_back_db_init( BackendDB *be, ConfigReply *cr )
 {
-	struct ldif_info *ni;
+	struct ldif_info *li;
 
-	ni = ch_calloc( 1, sizeof(struct ldif_info) );
-	be->be_private = ni;
+	li = ch_calloc( 1, sizeof(struct ldif_info) );
+	be->be_private = li;
 	be->be_cf_ocs = ldifocs;
-	ldap_pvt_thread_rdwr_init(&ni->li_rdwr);
+	ldap_pvt_thread_rdwr_init(&li->li_rdwr);
 	return 0;
 }
 
 static int
-ldif_back_db_destroy(
-			   Backend	*be
-			   )
+ldif_back_db_destroy( Backend *be, ConfigReply *cr )
 {
-	struct ldif_info *ni = be->be_private;
+	struct ldif_info *li = be->be_private;
 
-	ch_free(ni->li_base_path.bv_val);
-	ldap_pvt_thread_rdwr_destroy(&ni->li_rdwr);
+	ch_free(li->li_base_path.bv_val);
+	ldap_pvt_thread_rdwr_destroy(&li->li_rdwr);
 	free( be->be_private );
 	return 0;
 }
 
 static int
-ldif_back_db_open(
-			Backend	*be
-			)
+ldif_back_db_open( Backend *be, ConfigReply *cr)
 {
-	struct ldif_info *ni = (struct ldif_info *) be->be_private;
-	if( BER_BVISEMPTY(&ni->li_base_path)) {/* missing base path */
+	struct ldif_info *li = (struct ldif_info *) be->be_private;
+	if( BER_BVISEMPTY(&li->li_base_path)) {/* missing base path */
 		Debug( LDAP_DEBUG_ANY, "missing base path for back-ldif\n", 0, 0, 0);
 		return 1;
 	}
@@ -1335,9 +1398,7 @@
 	bi->bi_entry_get_rw = ldif_back_entry_get;
 
 #if 0	/* NOTE: uncomment to completely disable access control */
-#ifdef SLAP_OVERLAY_ACCESS
 	bi->bi_access_allowed = slap_access_always_allowed;
-#endif /* SLAP_OVERLAY_ACCESS */
 #endif
 
 	bi->bi_tool_entry_open = ldif_tool_entry_open;
@@ -1350,7 +1411,6 @@
 	bi->bi_tool_sync = 0;
 	
 	bi->bi_tool_dn2id_get = 0;
-	bi->bi_tool_id2entry_get = 0;
 	bi->bi_tool_entry_modify = 0;
 
 	bi->bi_cf_ocs = ldifocs;

Modified: openldap/trunk/servers/slapd/back-meta/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-meta/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-meta
-# $OpenLDAP: pkg/ldap/servers/slapd/back-meta/Makefile.in,v 1.12.2.7 2007/01/02 21:44:03 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-meta/Makefile.in,v 1.16.2.2 2007/08/31 23:14:03 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-meta/add.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/add.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/add.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/add.c,v 1.27.2.17 2007/01/13 11:19:07 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/add.c,v 1.51.2.5 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -86,7 +86,7 @@
 	for ( i = 0, a = op->ora_e->e_attrs; a; a = a->a_next ) {
 		int			j, is_oc = 0;
 
-		if ( !isupdate && !get_manageDIT( op ) && a->a_desc->ad_type->sat_no_user_mod  )
+		if ( !isupdate && !get_relax( op ) && a->a_desc->ad_type->sat_no_user_mod  )
 		{
 			continue;
 		}
@@ -169,8 +169,7 @@
 
 retry:;
 	ctrls = op->o_ctrls;
-	if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-		mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
+	if ( meta_back_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS )
 	{
 		send_ldap_result( op, rs );
 		goto cleanup;
@@ -184,13 +183,13 @@
 		do_retry = 0;
 		if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:;
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	for ( --i; i >= 0; --i ) {
 		free( attrs[ i ]->mod_bvalues );

Modified: openldap/trunk/servers/slapd/back-meta/back-meta.h
===================================================================
--- openldap/trunk/servers/slapd/back-meta/back-meta.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/back-meta.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/back-meta.h,v 1.23.2.22 2007/01/27 23:56:43 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/back-meta.h,v 1.64.2.7 2007/10/17 00:49:53 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -31,6 +31,7 @@
 
 /* String rewrite library */
 #include "rewrite.h"
+
 LDAP_BEGIN_DECL
 
 /*
@@ -40,9 +41,6 @@
 #define META_BACK_PRINT_CONNTREE 0
 #endif /* !META_BACK_PRINT_CONNTREE */
 
-struct slap_conn;
-struct slap_op;
-
 /* from back-ldap.h before rwm removal */
 struct ldapmap {
 	int drop_missing;
@@ -223,7 +221,7 @@
 } metasingleconn_t;
 
 typedef struct metaconn_t {
-	struct slap_conn	*mc_conn;
+	Connection		*mc_conn;
 #define	lc_conn			mc_conn
 	unsigned		mc_refcnt;
 
@@ -261,6 +259,7 @@
 	/* TODO: we might want to enable different strategies
 	 * for different targets */
 	LDAP_REBIND_PROC	*mt_rebind_f;
+	LDAP_URLLIST_PROC	*mt_urllist_f;
 	void			*mt_urllist_p;
 
 	BerVarray		mt_subtree_exclude;
@@ -311,6 +310,11 @@
 #define	META_BACK_TGT_CANCEL_DISCOVER(mt)	META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK2, LDAP_BACK_F_CANCEL_EXOP_DISCOVER )
 #define	META_BACK_TGT_QUARANTINE(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_QUARANTINE )
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+#define	META_BACK_TGT_ST_REQUEST(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_ST_REQUEST )
+#define	META_BACK_TGT_ST_RESPONSE(mt)		META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_ST_RESPONSE )
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
 	int			mt_version;
 	time_t			mt_network_timeout;
 	struct timeval		mt_bind_timeout;
@@ -347,6 +351,7 @@
 	metacandidates_t	*mi_candidates;
 
 	LDAP_REBIND_PROC	*mi_rebind_f;
+	LDAP_URLLIST_PROC	*mi_urllist_f;
 
 	metadncache_t		mi_cache;
 	
@@ -500,6 +505,14 @@
 	ldap_back_send_t	sendok );
 
 extern int
+meta_back_controls_add(
+	Operation	*op,
+	SlapReply	*rs,
+	metaconn_t	*mc,
+	int		candidate,
+	LDAPControl	***pctrls );
+
+extern int
 back_meta_LTX_init_module(
 	int			argc,
 	char			*argv[] );
@@ -579,6 +592,7 @@
 meta_dncache_free( void *entry );
 
 extern LDAP_REBIND_PROC		meta_back_default_rebind;
+extern LDAP_URLLIST_PROC	meta_back_default_urllist;
 
 LDAP_END_DECL
 

Modified: openldap/trunk/servers/slapd/back-meta/bind.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/bind.c,v 1.40.2.32 2007/09/26 19:04:22 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/bind.c,v 1.95.2.12 2007/10/18 00:20:07 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -64,7 +64,7 @@
 			gotit = 0,
 			isroot = 0;
 
-	SlapReply	*candidates = meta_back_candidates_get( op );
+	SlapReply	*candidates;
 
 	rs->sr_err = LDAP_SUCCESS;
 
@@ -72,24 +72,22 @@
 		op->o_log_prefix, op->o_req_dn.bv_val, 0 );
 
 	/* the test on the bind method should be superfluous */
-	if ( op->orb_method == LDAP_AUTH_SIMPLE
-		&& be_isroot_dn( op->o_bd, &op->o_req_ndn ) )
-	{
-		if ( !be_isroot_pw( op ) ) {
-			rs->sr_err = LDAP_INVALID_CREDENTIALS;
-			rs->sr_text = NULL;
-			send_ldap_result( op, rs );
-			return rs->sr_err;
-		}
-
+	switch ( be_rootdn_bind( op, rs ) ) {
+	case LDAP_SUCCESS:
 		if ( META_BACK_DEFER_ROOTDN_BIND( mi ) ) {
-			rs->sr_err = LDAP_SUCCESS;
-			rs->sr_text = NULL;
 			/* frontend will return success */
 			return rs->sr_err;
 		}
 
 		isroot = 1;
+		/* fallthru */
+
+	case SLAP_CB_CONTINUE:
+		break;
+
+	default:
+		/* be_rootdn_bind() sent result */
+		return rs->sr_err;
 	}
 
 	/* we need meta_back_getconn() not send result even on error,
@@ -97,7 +95,7 @@
 	 * invalidCredentials */
 	mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_BIND_DONTSEND );
 	if ( !mc ) {
-		if ( StatslogTest( LDAP_DEBUG_ANY ) ) {
+		if ( LogTest( LDAP_DEBUG_ANY ) ) {
 			char	buf[ SLAP_TEXT_BUFLEN ];
 
 			snprintf( buf, sizeof( buf ),
@@ -124,6 +122,8 @@
 		return rs->sr_err;
 	}
 
+	candidates = meta_back_candidates_get( op );
+
 	/*
 	 * Each target is scanned ...
 	 */
@@ -189,9 +189,6 @@
 
 		if ( lerr != LDAP_SUCCESS ) {
 			rc = rs->sr_err = lerr;
-			/* Mark the meta_conn struct as tainted so
-			 * it'll be freed by meta_conn_back_destroy below */
-			LDAP_BACK_CONN_TAINTED_SET( mc );
 
 			/* FIXME: in some cases (e.g. unavailable)
 			 * do not assume it's not candidate; rather
@@ -206,34 +203,24 @@
 	if ( rc == LDAP_SUCCESS ) {
 		if ( isroot ) {
 			mc->mc_authz_target = META_BOUND_ALL;
-			ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ) );
 		}
 
 		if ( !LDAP_BACK_PCONN_ISPRIV( mc )
 			&& !dn_match( &op->o_req_ndn, &mc->mc_local_ndn ) )
 		{
-			metaconn_t	*tmpmc;
 			int		lerr;
 
 			/* wait for all other ops to release the connection */
-retry_lock:;
 			ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
-			if ( mc->mc_refcnt > 1 ) {
-				ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
-				ldap_pvt_thread_yield();
-				goto retry_lock;
-			}
-
 			assert( mc->mc_refcnt == 1 );
 #if META_BACK_PRINT_CONNTREE > 0
 			meta_back_print_conntree( mi, ">>> meta_back_bind" );
 #endif /* META_BACK_PRINT_CONNTREE */
-			tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
-				meta_back_conndn_cmp );
-			assert( tmpmc == mc );
 
 			/* delete all cached connections with the current connection */
 			if ( LDAP_BACK_SINGLECONN( mi ) ) {
+				metaconn_t	*tmpmc;
+
 				while ( ( tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc, meta_back_conn_cmp ) ) != NULL )
 				{
 					Debug( LDAP_DEBUG_TRACE,
@@ -256,23 +243,22 @@
 			}
 
 			ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn );
-			if ( isroot ) {
-				LDAP_BACK_CONN_ISPRIV_SET( mc );
-				LDAP_BACK_PCONN_SET( mc, op );
-			}
 			lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
 				meta_back_conndn_cmp, meta_back_conndn_dup );
 #if META_BACK_PRINT_CONNTREE > 0
 			meta_back_print_conntree( mi, "<<< meta_back_bind" );
 #endif /* META_BACK_PRINT_CONNTREE */
+			if ( lerr == 0 ) {
+				if ( isroot ) {
+					LDAP_BACK_CONN_ISPRIV_SET( mc );
+					LDAP_BACK_PCONN_SET( mc, op );
+				}
+				LDAP_BACK_CONN_CACHED_SET( mc );
+
+			} else {
+				LDAP_BACK_CONN_CACHED_CLEAR( mc );
+			}
 			ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
-			if ( lerr == -1 ) {
-				/* we can do this because mc_refcnt == 1 */
-				assert( mc->mc_refcnt == 1 );
-				mc->mc_refcnt = 0;
-				meta_back_conn_free( mc );
-				mc = NULL;
-			}
 		}
 	}
 
@@ -330,6 +316,9 @@
 		">>> %s meta_back_bind_op_result[%d]\n",
 		op->o_log_prefix, candidate, 0 );
 
+	/* make sure this is clean */
+	assert( rs->sr_ctrls == NULL );
+
 	if ( rs->sr_err == LDAP_SUCCESS ) {
 		time_t		stoptime = (time_t)(-1),
 				timeout;
@@ -407,7 +396,7 @@
 			break;
 
 		case -1:
-			ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE,
+			ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER,
 				&rs->sr_err );
 
 			snprintf( buf, sizeof( buf ),
@@ -461,6 +450,9 @@
 	metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
 	int			msgid;
 	dncookie		dc;
+	struct berval		save_o_dn;
+	int			save_o_do_not_cache;
+	LDAPControl		**ctrls = NULL;
 	
 	if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
 		ch_free( msc->msc_bound_ndn.bv_val );
@@ -488,14 +480,37 @@
 		return rs->sr_err;
 	}
 
+	/* don't add proxyAuthz; set the bindDN */
+	save_o_dn = op->o_dn;
+	save_o_do_not_cache = op->o_do_not_cache;
+	op->o_do_not_cache = 1;
+	op->o_dn = op->o_req_dn;
+
+	ctrls = op->o_ctrls;
+	rs->sr_err = meta_back_controls_add( op, rs, mc, candidate, &ctrls );
+	op->o_dn = save_o_dn;
+	op->o_do_not_cache = save_o_do_not_cache;
+	if ( rs->sr_err != LDAP_SUCCESS ) {
+		goto return_results;
+	}
+
 	/* FIXME: this fixes the bind problem right now; we need
 	 * to use the asynchronous version to get the "matched"
 	 * and more in case of failure ... */
 	/* FIXME: should we check if at least some of the op->o_ctrls
 	 * can/should be passed? */
-	rs->sr_err = ldap_sasl_bind( msc->msc_ld, mdn.bv_val,
+	for (;;) {
+		rs->sr_err = ldap_sasl_bind( msc->msc_ld, mdn.bv_val,
 			LDAP_SASL_SIMPLE, &op->orb_cred,
-			op->o_ctrls, NULL, &msgid );
+			ctrls, NULL, &msgid );
+		if ( rs->sr_err != LDAP_X_CONNECTING ) {
+			break;
+		}
+		ldap_pvt_thread_yield();
+	}
+
+	ldap_back_controls_free( op, rs, &ctrls );
+
 	meta_back_bind_op_result( op, rs, mc, candidate, msgid, LDAP_BACK_DONTSEND );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		goto return_results;
@@ -583,9 +598,16 @@
 
 		/* FIXME: should we check if at least some of the op->o_ctrls
 		 * can/should be passed? */
-		rs->sr_err = ldap_sasl_bind( msc->msc_ld,
-			"", LDAP_SASL_SIMPLE, &cred,
-			NULL, NULL, &msgid );
+		for (;;) {
+			rs->sr_err = ldap_sasl_bind( msc->msc_ld,
+				"", LDAP_SASL_SIMPLE, &cred,
+				NULL, NULL, &msgid );
+			if ( rs->sr_err != LDAP_X_CONNECTING ) {
+				break;
+			}
+			ldap_pvt_thread_yield();
+		}
+
 		rs->sr_err = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok );
 	}
 
@@ -627,7 +649,7 @@
 				i,
 				isroot = 0;
 
-	SlapReply		*candidates = meta_back_candidates_get( op );
+	SlapReply		*candidates;
 
 	if ( be_isroot( op ) ) {
 		isroot = 1;
@@ -647,6 +669,8 @@
 		goto done;
 	}
 
+	candidates = meta_back_candidates_get( op );
+
 	for ( i = 0; i < mi->mi_ntargets; i++ ) {
 		metatarget_t		*mt = mi->mi_targets[ i ];
 		metasingleconn_t	*msc = &mc->mc_conns[ i ];
@@ -809,6 +833,43 @@
 			NULL, NULL, NULL );
 }
 
+/*
+ * meta_back_default_urllist
+ *
+ * This is a callback used for mucking with the urllist
+ */
+int 
+meta_back_default_urllist(
+	LDAP		*ld,
+	LDAPURLDesc	**urllist,
+	LDAPURLDesc	**url,
+	void		*params )
+{
+	metatarget_t	*mt = (metatarget_t *)params;
+	LDAPURLDesc	**urltail;
+
+	if ( urllist == url ) {
+		return LDAP_SUCCESS;
+	}
+
+	for ( urltail = &(*url)->lud_next; *urltail; urltail = &(*urltail)->lud_next )
+		/* count */ ;
+
+	*urltail = *urllist;
+	*urllist = *url;
+	*url = NULL;
+
+	ldap_pvt_thread_mutex_lock( &mt->mt_uri_mutex );
+	if ( mt->mt_uri ) {
+		ch_free( mt->mt_uri );
+	}
+
+	ldap_get_option( ld, LDAP_OPT_URI, (void *)&mt->mt_uri );
+	ldap_pvt_thread_mutex_unlock( &mt->mt_uri_mutex );
+
+	return LDAP_SUCCESS;
+}
+
 int
 meta_back_cancel(
 	metaconn_t		*mc,
@@ -832,6 +893,9 @@
 	if ( META_BACK_TGT_ABANDON( mt ) ) {
 		rc = ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL );
 
+	} else if ( META_BACK_TGT_IGNORE( mt ) ) {
+		rc = ldap_pvt_discard( msc->msc_ld, msgid );
+
 	} else if ( META_BACK_TGT_CANCEL( mt ) ) {
 		rc = ldap_cancel_s( msc->msc_ld, msgid, NULL, NULL );
 
@@ -1046,7 +1110,7 @@
 
 			rs->sr_err = LDAP_SUCCESS;
 
-			ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER, &rs->sr_err );
+			ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE, &rs->sr_err );
 			if ( rs->sr_err != LDAP_SUCCESS ) {
 				/*
 				 * better check the type of error. In some cases
@@ -1055,7 +1119,7 @@
 				 * positive result ...
 				 */
 				ldap_get_option( msc->msc_ld,
-						LDAP_OPT_ERROR_STRING, &xtext );
+						LDAP_OPT_DIAGNOSTIC_MESSAGE, &xtext );
 				if ( xtext != NULL && xtext [ 0 ] == '\0' ) {
 					ldap_memfree( xtext );
 					xtext = NULL;
@@ -1070,7 +1134,7 @@
 
 				rs->sr_err = slap_map_api2result( rs );
 	
-				if ( StatslogTest( LDAP_DEBUG_ANY ) ) {
+				if ( LogTest( LDAP_DEBUG_ANY ) ) {
 					char	buf[ SLAP_TEXT_BUFLEN ];
 
 					snprintf( buf, sizeof( buf ),
@@ -1371,6 +1435,14 @@
 				mt->mt_idassert_authcID.bv_val,
 				mt->mt_idassert_passwd.bv_val,
 				authzID.bv_val );
+		if ( defaults == NULL ) {
+			rs->sr_err = LDAP_OTHER;
+			LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
+			if ( sendok & LDAP_BACK_SENDERR ) {
+				send_ldap_result( op, rs );
+			}
+			goto done;
+		}
 
 		rs->sr_err = ldap_sasl_interactive_bind_s( msc->msc_ld, binddn->bv_val,
 				mt->mt_idassert_sasl_mech.bv_val, NULL, NULL,
@@ -1439,9 +1511,15 @@
 		switch ( method ) {
 		case LDAP_AUTH_NONE:
 		case LDAP_AUTH_SIMPLE:
-			rs->sr_err = ldap_sasl_bind( msc->msc_ld,
+			for (;;) {
+				rs->sr_err = ldap_sasl_bind( msc->msc_ld,
 					binddn.bv_val, LDAP_SASL_SIMPLE,
 					&cred, NULL, NULL, &msgid );
+				if ( rs->sr_err != LDAP_X_CONNECTING ) {
+					break;
+				}
+				ldap_pvt_thread_yield();
+			}
 			rc = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok );
 			if ( rc == LDAP_SUCCESS ) {
 				/* set rebind stuff in case of successful proxyAuthz bind,
@@ -1469,3 +1547,140 @@
 
 	return LDAP_BACK_CONN_ISBOUND( msc );
 }
+
+/*
+ * Add controls;
+ *
+ * if any needs to be added, it is prepended to existing ones,
+ * in a newly allocated array.  The companion function
+ * ldap_back_controls_free() must be used to restore the original
+ * status of op->o_ctrls.
+ */
+int
+meta_back_controls_add(
+		Operation	*op,
+		SlapReply	*rs,
+		metaconn_t	*mc,
+		int		candidate,
+		LDAPControl	***pctrls )
+{
+	metainfo_t		*mi = (metainfo_t *)op->o_bd->be_private;
+	metatarget_t		*mt = mi->mi_targets[ candidate ];
+	metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
+
+	LDAPControl		**ctrls = NULL;
+	/* set to the maximum number of controls this backend can add */
+	LDAPControl		c[ 2 ] = { 0 };
+	int			n = 0, i, j1 = 0, j2 = 0;
+
+	*pctrls = NULL;
+
+	rs->sr_err = LDAP_SUCCESS;
+
+	/* don't add controls if protocol is not LDAPv3 */
+	switch ( mt->mt_version ) {
+	case LDAP_VERSION3:
+		break;
+
+	case 0:
+		if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
+			break;
+		}
+		/* fall thru */
+
+	default:
+		goto done;
+	}
+
+	/* put controls that go __before__ existing ones here */
+
+	/* proxyAuthz for identity assertion */
+	switch ( ldap_back_proxy_authz_ctrl( op, rs, &msc->msc_bound_ndn,
+		mt->mt_version, &mt->mt_idassert, &c[ j1 ] ) )
+	{
+	case SLAP_CB_CONTINUE:
+		break;
+
+	case LDAP_SUCCESS:
+		j1++;
+		break;
+
+	default:
+		goto done;
+	}
+
+	/* put controls that go __after__ existing ones here */
+
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+	/* session tracking */
+	if ( META_BACK_TGT_ST_REQUEST( mt ) ) {
+		switch ( slap_ctrl_session_tracking_request_add( op, rs, &c[ j1 + j2 ] ) ) {
+		case SLAP_CB_CONTINUE:
+			break;
+
+		case LDAP_SUCCESS:
+			j2++;
+			break;
+
+		default:
+			goto done;
+		}
+	}
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
+	if ( rs->sr_err == SLAP_CB_CONTINUE ) {
+		rs->sr_err = LDAP_SUCCESS;
+	}
+
+	/* if nothing to do, just bail out */
+	if ( j1 == 0 && j2 == 0 ) {
+		goto done;
+	}
+
+	assert( j1 + j1 <= sizeof( c )/sizeof(LDAPControl) );
+
+	if ( op->o_ctrls ) {
+		for ( n = 0; op->o_ctrls[ n ]; n++ )
+			/* just count ctrls */ ;
+	}
+
+	ctrls = op->o_tmpalloc( (n + j1 + j2 + 1) * sizeof( LDAPControl * ) + ( j1 + j2 ) * sizeof( LDAPControl ),
+			op->o_tmpmemctx );
+	if ( j1 ) {
+		ctrls[ 0 ] = (LDAPControl *)&ctrls[ n + j1 + j2 + 1 ];
+		*ctrls[ 0 ] = c[ 0 ];
+		for ( i = 1; i < j1; i++ ) {
+			ctrls[ i ] = &ctrls[ 0 ][ i ];
+			*ctrls[ i ] = c[ i ];
+		}
+	}
+
+	i = 0;
+	if ( op->o_ctrls ) {
+		for ( i = 0; op->o_ctrls[ i ]; i++ ) {
+			ctrls[ i + j1 ] = op->o_ctrls[ i ];
+		}
+	}
+
+	n += j1;
+	if ( j2 ) {
+		ctrls[ n ] = (LDAPControl *)&ctrls[ n + j2 + 1 ] + j1;
+		*ctrls[ n ] = c[ j1 ];
+		for ( i = 1; i < j2; i++ ) {
+			ctrls[ n + i ] = &ctrls[ n ][ i ];
+			*ctrls[ n + i ] = c[ i ];
+		}
+	}
+
+	ctrls[ n + j2 ] = NULL;
+
+done:;
+	if ( ctrls == NULL ) {
+		ctrls = op->o_ctrls;
+	}
+
+	*pctrls = ctrls;
+	
+	return rs->sr_err;
+}
+

Modified: openldap/trunk/servers/slapd/back-meta/candidates.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/candidates.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/candidates.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/candidates.c,v 1.12.2.15 2007/01/05 09:47:10 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/candidates.c,v 1.28.2.4 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-meta/compare.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/compare.c,v 1.30.2.16 2007/01/13 11:19:07 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/compare.c,v 1.50.2.5 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -113,8 +113,7 @@
 
 retry:;
 	ctrls = op->o_ctrls;
-	rc = ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-		mt->mt_version, &mt->mt_idassert, op, rs, &ctrls );
+	rc = meta_back_controls_add( op, rs, mc, candidate, &ctrls );
 	if ( rc != LDAP_SUCCESS ) {
 		send_ldap_result( op, rs );
 		goto cleanup;
@@ -130,13 +129,13 @@
 		do_retry = 0;
 		if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:;
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	if ( mdn.bv_val != op->o_req_dn.bv_val ) {
 		free( mdn.bv_val );

Modified: openldap/trunk/servers/slapd/back-meta/config.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/config.c,v 1.35.2.26 2007/09/13 19:33:55 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/config.c,v 1.74.2.8 2007/11/27 19:49:13 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -158,6 +158,8 @@
 		mt = mi->mi_targets[ i ];
 
 		mt->mt_rebind_f = mi->mi_rebind_f;
+		mt->mt_urllist_f = mi->mi_urllist_f;
+		mt->mt_urllist_p = mt;
 
 		mt->mt_nretries = mi->mi_nretries;
 		mt->mt_quarantine = mi->mi_quarantine;
@@ -198,7 +200,8 @@
 			/*
 			 * uri MUST be legal!
 			 */
-			if ( ldap_url_parselist_ext( &ludp, uris[ c ], "\t" ) != LDAP_SUCCESS
+			if ( ldap_url_parselist_ext( &ludp, uris[ c ], "\t",
+					LDAP_PVT_URL_PARSE_NONE ) != LDAP_SUCCESS
 				|| ludp->lud_next != NULL )
 			{
 				Debug( LDAP_DEBUG_ANY,
@@ -926,10 +929,8 @@
 		if ( strcasecmp( argv[ 1 ], "abandon" ) == 0 ) {
 			flag = LDAP_BACK_F_CANCEL_ABANDON;
 
-#if 0	/* needs ldap_int_discard(), 2.4 */
 		} else if ( strcasecmp( argv[ 1 ], "ignore" ) == 0 ) {
 			flag = LDAP_BACK_F_CANCEL_IGNORE;
-#endif
 
 		} else if ( strcasecmp( argv[ 1 ], "exop" ) == 0 ) {
 			flag = LDAP_BACK_F_CANCEL_EXOP;
@@ -1244,6 +1245,38 @@
 		} else {
 			mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags |= LDAP_BACK_F_QUARANTINE;
 		}
+
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+	/* session tracking request */
+	} else if ( strcasecmp( argv[ 0 ], "session-tracking-request" ) == 0 ) {
+		unsigned	*flagsp = mi->mi_ntargets ?
+				&mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags
+				: &mi->mi_flags;
+
+		if ( argc != 2 ) {
+			Debug( LDAP_DEBUG_ANY,
+	"%s: line %d: \"session-tracking-request {TRUE|false}\" needs 1 argument.\n",
+				fname, lineno, 0 );
+			return( 1 );
+		}
+
+		/* this is the default; we add it because the default might change... */
+		switch ( check_true_false( argv[ 1 ] ) ) {
+		case 1:
+			*flagsp |= LDAP_BACK_F_ST_REQUEST;
+			break;
+
+		case 0:
+			*flagsp &= ~LDAP_BACK_F_ST_REQUEST;
+			break;
+
+		default:
+			Debug( LDAP_DEBUG_ANY,
+		"%s: line %d: \"session-tracking-request {TRUE|false}\": unknown argument \"%s\".\n",
+				fname, lineno, argv[ 1 ] );
+			return( 1 );
+		}
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
 	
 	/* dn massaging */
 	} else if ( strcasecmp( argv[ 0 ], "suffixmassage" ) == 0 ) {
@@ -1292,7 +1325,7 @@
 
 		if ( BER_BVISNULL( &be->be_nsuffix[ c ] ) ) {
 			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
-	"%s: line %d: <suffix> \"%s\" must be within the database naming context, in "
+	"<suffix> \"%s\" must be within the database naming context, in "
 	"\"suffixMassage <suffix> <massaged suffix>\"\n",
 				fname, lineno, pvnc.bv_val );
 			free( pvnc.bv_val );
@@ -1310,7 +1343,7 @@
 			return 1;
 		}
 	
-		tmp_bd = select_backend( &nrnc, 0, 0 );
+		tmp_bd = select_backend( &nrnc, 0 );
 		if ( tmp_bd != NULL && tmp_bd->be_private == be->be_private ) {
 			Debug( LDAP_DEBUG_ANY, 
 	"%s: line %d: warning: <massaged suffix> \"%s\" resolves to this database, in "

Modified: openldap/trunk/servers/slapd/back-meta/conn.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/conn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/conn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/conn.c,v 1.31.2.29 2007/10/13 08:26:04 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/conn.c,v 1.86.2.12 2007/11/27 19:49:13 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -285,7 +285,7 @@
 				dont_retry = ( ri->ri_num[ ri->ri_idx ] == SLAP_RETRYNUM_TAIL
 					|| slap_get_time() < ri->ri_last + ri->ri_interval[ ri->ri_idx ] );
 				if ( !dont_retry ) {
-					if ( StatslogTest( LDAP_DEBUG_ANY ) ) {
+					if ( LogTest( LDAP_DEBUG_ANY ) ) {
 						char	buf[ SLAP_TEXT_BUFLEN ];
 
 						snprintf( buf, sizeof( buf ),
@@ -400,6 +400,7 @@
 		version = LDAP_VERSION3;
 	}
 	ldap_set_option( msc->msc_ld, LDAP_OPT_PROTOCOL_VERSION, &version );
+	ldap_set_urllist_proc( msc->msc_ld, mt->mt_urllist_f, mt->mt_urllist_p );
 
 	/* automatically chase referrals ("chase-referrals [{yes|no}]" statement) */
 	ldap_set_option( msc->msc_ld, LDAP_OPT_REFERRALS,
@@ -669,7 +670,7 @@
 
 	assert( mc->mc_refcnt > 0 );
 	if ( mc->mc_refcnt == 1 ) {
-		if ( StatslogTest( LDAP_DEBUG_ANY ) ) {
+		if ( LogTest( LDAP_DEBUG_ANY ) ) {
 			char	buf[ SLAP_TEXT_BUFLEN ];
 
 			/* this lock is required; however,
@@ -848,7 +849,6 @@
 		rs->sr_text = "No suitable candidate target found";
 
 	} else if ( candidate == META_TARGET_MULTIPLE ) {
-		Filter		f = { 0 };
 		Operation	op2 = *op;
 		SlapReply	rs2 = { 0 };
 		slap_callback	cb2 = { 0 };
@@ -867,10 +867,8 @@
 		op2.ors_slimit = 1;
 		op2.ors_tlimit = SLAP_NO_LIMIT;
 
-		f.f_choice = LDAP_FILTER_PRESENT;
-		f.f_desc = slap_schema.si_ad_objectClass;
-		op2.ors_filter = &f;
-		BER_BVSTR( &op2.ors_filterstr, "(objectClass=*)" );
+		op2.ors_filter = (Filter *)slap_filter_objectClass_pres;
+		op2.ors_filterstr = *slap_filterstr_objectClass_pres;
 
 		op2.o_callback = &cb2;
 		cb2.sc_response = meta_back_conn_cb;
@@ -1594,6 +1592,7 @@
 		meta_back_print_conntree( mi, ">>> meta_back_getconn" );
 #endif /* META_BACK_PRINT_CONNTREE */
 
+		err = 0;
 		if ( LDAP_BACK_PCONN_ISPRIV( mc ) ) {
 			if ( mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num < mi->mi_conn_priv_max ) {
 				LDAP_TAILQ_INSERT_TAIL( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv, mc, mc_q );
@@ -1605,7 +1604,7 @@
 			}
 			rs->sr_err = 0;
 
-		} else {
+		} else if ( !( sendok & LDAP_BACK_BINDING ) ) {
 			err = avl_insert( &mi->mi_conninfo.lai_tree, ( caddr_t )mc,
 			       	meta_back_conndn_cmp, meta_back_conndn_dup );
 			LDAP_BACK_CONN_CACHED_SET( mc );
@@ -1691,7 +1690,7 @@
 	 * that are not privileged would live forever and pollute
 	 * the connection space (and eat up resources).  Maybe this
 	 * should be configurable... */
-	if ( LDAP_BACK_CONN_TAINTED( mc ) ) {
+	if ( LDAP_BACK_CONN_TAINTED( mc ) || !LDAP_BACK_CONN_CACHED( mc ) ) {
 #if META_BACK_PRINT_CONNTREE > 0
 		meta_back_print_conntree( mi, ">>> meta_back_release_conn" );
 #endif /* META_BACK_PRINT_CONNTREE */
@@ -1708,7 +1707,7 @@
 				assert( !LDAP_BACK_CONN_CACHED( mc ) );
 			}
 
-		} else {
+		} else if ( LDAP_BACK_CONN_CACHED( mc ) ) {
 			metaconn_t	*tmpmc;
 
 			tmpmc = avl_delete( &mi->mi_conninfo.lai_tree,
@@ -1770,7 +1769,7 @@
 			break;
 
 		case LDAP_BACK_FQ_RETRYING:
-			if ( StatslogTest( LDAP_DEBUG_ANY ) ) {
+			if ( LogTest( LDAP_DEBUG_ANY ) ) {
 				char	buf[ SLAP_TEXT_BUFLEN ];
 
 				snprintf( buf, sizeof( buf ),

Modified: openldap/trunk/servers/slapd/back-meta/delete.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/delete.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/delete.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/delete.c,v 1.19.2.15 2007/01/13 11:19:07 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/delete.c,v 1.37.2.5 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -67,8 +67,7 @@
 
 retry:;
 	ctrls = op->o_ctrls;
-	if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-		mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
+	if ( meta_back_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS )
 	{
 		send_ldap_result( op, rs );
 		goto cleanup;
@@ -82,13 +81,13 @@
 		do_retry = 0;
 		if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:;
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	if ( mdn.bv_val != op->o_req_dn.bv_val ) {
 		free( mdn.bv_val );

Modified: openldap/trunk/servers/slapd/back-meta/dncache.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/dncache.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/dncache.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/dncache.c,v 1.10.2.7 2007/01/02 21:44:04 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/dncache.c,v 1.16.2.2 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-meta/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/init.c,v 1.37.2.16 2007/01/26 22:05:36 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/init.c,v 1.58.2.5 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -23,6 +23,7 @@
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "config.h"
 #include "../back-ldap/back-ldap.h"
 #include "back-meta.h"
 
@@ -40,6 +41,20 @@
 meta_back_initialize(
 	BackendInfo	*bi )
 {
+	bi->bi_flags =
+#if 0
+	/* this is not (yet) set essentially because back-meta does not
+	 * directly support extended operations... */
+#ifdef LDAP_DYNAMIC_OBJECTS
+		/* this is set because all the support a proxy has to provide
+		 * is the capability to forward the refresh exop, and to
+		 * pass thru entries that contain the dynamicObject class
+		 * and the entryTtl attribute */
+		SLAP_BFLAG_DYNAMIC |
+#endif /* LDAP_DYNAMIC_OBJECTS */
+#endif
+		0;
+
 	bi->bi_open = meta_back_open;
 	bi->bi_config = 0;
 	bi->bi_close = 0;
@@ -73,7 +88,8 @@
 
 int
 meta_back_db_init(
-	Backend		*be )
+	Backend		*be,
+	ConfigReply	*cr)
 {
 	metainfo_t	*mi;
 	int		i;
@@ -92,6 +108,7 @@
 	mi->mi_bind_timeout.tv_usec = META_BIND_TIMEOUT;
 
 	mi->mi_rebind_f = meta_back_default_rebind;
+	mi->mi_urllist_f = meta_back_default_urllist;
 
 	ldap_pvt_thread_mutex_init( &mi->mi_conninfo.lai_mutex );
 	ldap_pvt_thread_mutex_init( &mi->mi_cache.mutex );
@@ -113,7 +130,8 @@
 
 int
 meta_back_db_open(
-	Backend		*be )
+	Backend		*be,
+	ConfigReply	*cr )
 {
 	metainfo_t	*mi = (metainfo_t *)be->be_private;
 
@@ -131,10 +149,16 @@
 	}
 
 	for ( i = 0; i < mi->mi_ntargets; i++ ) {
+		slap_bindconf	sb = { BER_BVNULL };
 		metatarget_t	*mt = mi->mi_targets[ i ];
 
+		ber_str2bv( mt->mt_uri, 0, 0, &sb.sb_uri );
+		sb.sb_version = mt->mt_version;
+		sb.sb_method = LDAP_AUTH_SIMPLE;
+		BER_BVSTR( &sb.sb_binddn, "" );
+
 		if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) {
-			rc = slap_discover_feature( mt->mt_uri, mt->mt_version,
+			rc = slap_discover_feature( &sb,
 					slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
 					LDAP_FEATURE_ABSOLUTE_FILTERS );
 			if ( rc == LDAP_COMPARE_TRUE ) {
@@ -143,7 +167,7 @@
 		}
 
 		if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) {
-			rc = slap_discover_feature( mt->mt_uri, mt->mt_version,
+			rc = slap_discover_feature( &sb,
 					slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
 					LDAP_EXOP_CANCEL );
 			if ( rc == LDAP_COMPARE_TRUE ) {
@@ -307,7 +331,8 @@
 
 int
 meta_back_db_destroy(
-	Backend		*be )
+	Backend		*be,
+	ConfigReply	*cr )
 {
 	metainfo_t	*mi;
 

Modified: openldap/trunk/servers/slapd/back-meta/map.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/map.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/map.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* map.c - ldap backend mapping routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/map.c,v 1.1.2.15 2007/10/04 20:18:59 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/map.c,v 1.15.2.6 2007/10/18 01:35:12 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -213,7 +213,6 @@
 		int			remap )
 {
 	struct berval		vtmp;
-	char			uuid[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
 	int			freeval = 0;
 
 	ldap_back_map( &dc->target->mt_rwmap.rwm_at, &ad->ad_cname, mapped_attr, remap );
@@ -260,13 +259,14 @@
 			return -1;
 		}
 
-	} else if ( ad->ad_type->sat_syntax == slap_schema.si_ad_entryUUID->ad_type->sat_syntax ) {
-		vtmp.bv_len = lutil_uuidstr_from_normalized( value->bv_val,
-			value->bv_len, uuid, LDAP_LUTIL_UUIDSTR_BUFSIZE );
-		if ( vtmp.bv_len < 0 ) {
+	} else if ( ad->ad_type->sat_equality->smr_usage & SLAP_MR_MUTATION_NORMALIZER ) {
+		if ( ad->ad_type->sat_equality->smr_normalize(
+			(SLAP_MR_DENORMALIZE|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX),
+			NULL, NULL, value, &vtmp, NULL ) )
+		{
 			return -1;
 		}
-		vtmp.bv_val = uuid;
+		freeval = 1;
 
 	} else if ( ad == slap_schema.si_ad_objectClass || ad == slap_schema.si_ad_structuralObjectClass ) {
 		ldap_back_map( &dc->target->mt_rwmap.rwm_oc, value, &vtmp, remap );

Modified: openldap/trunk/servers/slapd/back-meta/modify.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/modify.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/modify.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/modify.c,v 1.29.2.16 2007/01/13 11:19:07 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/modify.c,v 1.52.2.5 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -92,7 +92,7 @@
 	for ( i = 0, ml = op->orm_modlist; ml; ml = ml->sml_next ) {
 		int	j, is_oc = 0;
 
-		if ( !isupdate && !get_manageDIT( op ) && ml->sml_desc->ad_type->sat_no_user_mod  )
+		if ( !isupdate && !get_relax( op ) && ml->sml_desc->ad_type->sat_no_user_mod  )
 		{
 			continue;
 		}
@@ -178,8 +178,7 @@
 
 retry:;
 	ctrls = op->o_ctrls;
-	rc = ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-		mt->mt_version, &mt->mt_idassert, op, rs, &ctrls );
+	rc = meta_back_controls_add( op, rs, mc, candidate, &ctrls );
 	if ( rc != LDAP_SUCCESS ) {
 		send_ldap_result( op, rs );
 		goto cleanup;
@@ -193,13 +192,13 @@
 		do_retry = 0;
 		if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:;
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	if ( mdn.bv_val != op->o_req_dn.bv_val ) {
 		free( mdn.bv_val );

Modified: openldap/trunk/servers/slapd/back-meta/modrdn.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/modrdn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/modrdn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/modrdn.c,v 1.19.2.16 2007/01/13 11:19:07 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/modrdn.c,v 1.39.2.6 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -120,8 +120,7 @@
 
 retry:;
 	ctrls = op->o_ctrls;
-	if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-		mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
+	if ( meta_back_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS )
 	{
 		send_ldap_result( op, rs );
 		goto cleanup;
@@ -137,13 +136,13 @@
 		do_retry = 0;
 		if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 	}
 
 cleanup:;
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	if ( mdn.bv_val != op->o_req_dn.bv_val ) {
 		free( mdn.bv_val );

Modified: openldap/trunk/servers/slapd/back-meta/proto-meta.h
===================================================================
--- openldap/trunk/servers/slapd/back-meta/proto-meta.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/proto-meta.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/proto-meta.h,v 1.2.2.5 2007/01/02 21:44:04 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/proto-meta.h,v 1.5.2.2 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-meta/search.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/search.c,v 1.84.2.33 2007/08/14 09:59:44 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/search.c,v 1.146.2.7 2007/09/29 09:55:22 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -42,6 +42,7 @@
  */
 #define	META_MSGID_IGNORE	(-1)
 #define	META_MSGID_NEED_BIND	(-2)
+#define	META_MSGID_CONNECTING	(-3)
 
 static int
 meta_send_entry(
@@ -57,7 +58,8 @@
 	META_SEARCH_NOT_CANDIDATE,
 	META_SEARCH_CANDIDATE,
 	META_SEARCH_BINDING,
-	META_SEARCH_NEED_BIND
+	META_SEARCH_NEED_BIND,
+	META_SEARCH_CONNECTING
 } meta_search_candidate_t;
 
 /*
@@ -230,6 +232,9 @@
 
 	assert( msc->msc_ld != NULL );
 
+	/* connect must be async only the first time... */
+	ldap_set_option( msc->msc_ld, LDAP_OPT_CONNECT_ASYNC, LDAP_OPT_ON );
+
 retry:;
 	rc = ldap_sasl_bind( msc->msc_ld, binddn.bv_val, LDAP_SASL_SIMPLE, &cred,
 			NULL, NULL, &candidates[ candidate ].sr_msgid );
@@ -251,6 +256,14 @@
 		META_BINDING_SET( &candidates[ candidate ] );
 		return META_SEARCH_BINDING;
 
+	case LDAP_X_CONNECTING:
+		/* must retry, same conn */
+		candidates[ candidate ].sr_msgid = META_MSGID_CONNECTING;
+		ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+		LDAP_BACK_CONN_BINDING_CLEAR( msc );
+		ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
+		return META_SEARCH_CONNECTING;
+
 	case LDAP_SERVER_DOWN:
 down:;
 		/* This is the worst thing that could happen:
@@ -261,7 +274,7 @@
 			ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
 
 			assert( mc->mc_refcnt > 0 );
-			if ( StatslogTest( LDAP_DEBUG_ANY ) ) {
+			if ( LogTest( LDAP_DEBUG_ANY ) ) {
 				char	buf[ SLAP_TEXT_BUFLEN ];
 
 				/* this lock is required; however,
@@ -388,6 +401,9 @@
 			LDAP_BACK_CONN_ISBOUND_SET( msc );
 		}
 		retcode = META_SEARCH_CANDIDATE;
+
+		/* connect must be async */
+		ldap_set_option( msc->msc_ld, LDAP_OPT_CONNECT_ASYNC, LDAP_OPT_OFF );
 	}
 
 	candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
@@ -582,8 +598,7 @@
 
 retry:;
 	ctrls = op->o_ctrls;
-	if ( ldap_back_proxy_authz_ctrl( &msc->msc_bound_ndn,
-		mt->mt_version, &mt->mt_idassert, op, rs, &ctrls )
+	if ( meta_back_controls_add( op, rs, *mcp, candidate, &ctrls )
 		!= LDAP_SUCCESS )
 	{
 		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
@@ -609,7 +624,7 @@
 		if ( nretries && meta_back_retry( op, rs, mcp, candidate, LDAP_BACK_DONTSEND ) ) {
 			nretries = 0;
 			/* if the identity changed, there might be need to re-authz */
-			(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+			(void)ldap_back_controls_free( op, rs, &ctrls );
 			goto retry;
 		}
 
@@ -626,7 +641,7 @@
 	}
 
 done:;
-	(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+	(void)ldap_back_controls_free( op, rs, &ctrls );
 
 	if ( mapped_attrs ) {
 		free( mapped_attrs );
@@ -664,7 +679,7 @@
 	dncookie	dc;
 	int		is_ok = 0;
 	void		*savepriv;
-	SlapReply	*candidates = meta_back_candidates_get( op );
+	SlapReply	*candidates = NULL;
 
 	/*
 	 * controls are set in ldap_back_dobind()
@@ -681,6 +696,7 @@
 	dc.conn = op->o_conn;
 	dc.rs = rs;
 
+	if ( candidates == NULL ) candidates = meta_back_candidates_get( op );
 	/*
 	 * Inits searches
 	 */
@@ -730,6 +746,7 @@
 			++needbind;
 			/* fallthru */
 
+		case META_SEARCH_CONNECTING:
 		case META_SEARCH_CANDIDATE:
 		case META_SEARCH_BINDING:
 			candidates[ i ].sr_type = REP_INTERMEDIATE;
@@ -788,7 +805,7 @@
 
 	initial_candidates = ncandidates;
 
-	if ( StatslogTest( LDAP_DEBUG_TRACE ) ) {
+	if ( LogTest( LDAP_DEBUG_TRACE ) ) {
 		char	cnd[ SLAP_TEXT_BUFLEN ];
 		int	c;
 
@@ -895,7 +912,9 @@
 			}
 
 			/* if target still needs bind, retry */
-			if ( candidates[ i ].sr_msgid == META_MSGID_NEED_BIND ) {
+			if ( candidates[ i ].sr_msgid == META_MSGID_NEED_BIND
+				|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
+			{
 				/* initiate dobind */
 				retcode = meta_search_dobind_init( op, rs, &mc, i, candidates );
 
@@ -907,6 +926,7 @@
 					alreadybound--;
 					/* fallthru */
 
+				case META_SEARCH_CONNECTING:
 				case META_SEARCH_BINDING:
 					break;
 
@@ -1044,6 +1064,7 @@
 							continue;
 
 						case META_SEARCH_BINDING:
+						case META_SEARCH_CONNECTING:
 						case META_SEARCH_NEED_BIND:
 						case META_SEARCH_UNDEFINED:
 							assert( 0 );
@@ -1203,6 +1224,8 @@
 						candidates[ i ].sr_type = REP_RESULT;
 					}
 	
+					candidates[ i ].sr_msgid = META_MSGID_IGNORE;
+
 					/* NOTE: ignores response controls
 					 * (and intermediate response controls
 					 * as well, except for those with search
@@ -1311,7 +1334,7 @@
 	
 					sres = slap_map_api2result( rs );
 	
-					if ( StatslogTest( LDAP_DEBUG_TRACE | LDAP_DEBUG_ANY ) ) {
+					if ( LogTest( LDAP_DEBUG_TRACE | LDAP_DEBUG_ANY ) ) {
 						snprintf( buf, sizeof( buf ),
 							"%s meta_back_search[%ld] "
 							"match=\"%s\" err=%ld",
@@ -1389,7 +1412,6 @@
 					 * When no candidates are left,
 					 * the outer cycle finishes
 					 */
-					candidates[ i ].sr_msgid = META_MSGID_IGNORE;
 					assert( ncandidates > 0 );
 					--ncandidates;
 	
@@ -1446,10 +1468,16 @@
 		/* check for abandon */
 		if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( mc ) ) {
 			for ( i = 0; i < mi->mi_ntargets; i++ ) {
-				if ( candidates[ i ].sr_msgid >= 0 ) {
-					if ( META_IS_BINDING( &candidates[ i ] ) ) {
+				if ( candidates[ i ].sr_msgid >= 0
+					|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
+				{
+					if ( META_IS_BINDING( &candidates[ i ] )
+						|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
+					{
 						ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
-						if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) ) {
+						if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] )
+							|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
+						{
 							/* if still binding, destroy */
 
 #ifdef DEBUG_205
@@ -1646,23 +1674,35 @@
 			continue;
 		}
 
-		if ( mc && META_IS_BINDING( &candidates[ i ] ) ) {
-			ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
-			if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) ) {
-				assert( candidates[ i ].sr_msgid >= 0 );
-				assert( mc->mc_conns[ i ].msc_ld != NULL );
+		if ( mc ) {
+			if ( META_IS_BINDING( &candidates[ i ] )
+				|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
+			{
+				ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+				if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] )
+					|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING )
+				{
+					assert( candidates[ i ].sr_msgid >= 0
+						|| candidates[ i ].sr_msgid == META_MSGID_CONNECTING );
+					assert( mc->mc_conns[ i ].msc_ld != NULL );
 
 #ifdef DEBUG_205
-				Debug( LDAP_DEBUG_ANY, "### %s meta_back_search(cleanup) "
-					"ldap_unbind_ext[%ld] ld=%p\n",
-					op->o_log_prefix, i, (void *)mc->mc_conns[i].msc_ld );
+					Debug( LDAP_DEBUG_ANY, "### %s meta_back_search(cleanup) "
+						"ldap_unbind_ext[%ld] ld=%p\n",
+						op->o_log_prefix, i, (void *)mc->mc_conns[i].msc_ld );
 #endif /* DEBUG_205 */
 
-				/* if still binding, destroy */
-				meta_clear_one_candidate( op, mc, i );
+					/* if still binding, destroy */
+					meta_clear_one_candidate( op, mc, i );
+				}
+				ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
+				META_BINDING_CLEAR( &candidates[ i ] );
+
+			} else if ( candidates[ i ].sr_msgid >= 0 ) {
+				(void)meta_back_cancel( mc, op, rs,
+					candidates[ i ].sr_msgid, i,
+					LDAP_BACK_DONTSEND );
 			}
-			ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
-			META_BINDING_CLEAR( &candidates[ i ] );
 		}
 
 		if ( candidates[ i ].sr_matched ) {
@@ -1791,7 +1831,7 @@
 			/* will need to check for duplicate attrs */
 			check_duplicate_attrs++;
 		}
-		attr = ( Attribute * )ch_calloc( 1, sizeof( Attribute ) );
+		attr = attr_alloc( NULL );
 		if ( attr == NULL ) {
 			continue;
 		}
@@ -1809,7 +1849,7 @@
 					mapped.bv_val, text );
 
 				Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 );
-				ch_free( attr );
+				attr_free( attr );
 				continue;
 			}
 		}
@@ -1832,7 +1872,7 @@
 			 */
 			( void )ber_scanf( &ber, "x" /* [W] */ );
 
-			ch_free(attr);
+			attr_free(attr);
 			continue;
 		}
 
@@ -1845,6 +1885,7 @@
 			for ( last = 0; !BER_BVISNULL( &attr->a_vals[ last ] ); ++last )
 				;
 		}
+		attr->a_numvals = last;
 
 		validate = attr->a_desc->ad_type->sat_syntax->ssyn_validate;
 		pretty = attr->a_desc->ad_type->sat_syntax->ssyn_pretty;
@@ -2020,8 +2061,11 @@
 		}
 	}
 
+	ldap_get_entry_controls( mc->mc_conns[target].msc_ld,
+		e, &rs->sr_ctrls );
 	rs->sr_entry = &ent;
 	rs->sr_attrs = op->ors_attrs;
+	rs->sr_operational_attrs = NULL;
 	rs->sr_flags = 0;
 	rs->sr_err = LDAP_SUCCESS;
 	rc = send_search_entry( op, rs );
@@ -2032,7 +2076,10 @@
 	}
 	rs->sr_entry = NULL;
 	rs->sr_attrs = NULL;
-	
+	if ( rs->sr_ctrls != NULL ) {
+		ldap_controls_free( rs->sr_ctrls );
+		rs->sr_ctrls = NULL;
+	}
 	if ( !BER_BVISNULL( &ent.e_name ) ) {
 		free( ent.e_name.bv_val );
 		BER_BVZERO( &ent.e_name );

Modified: openldap/trunk/servers/slapd/back-meta/suffixmassage.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/suffixmassage.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/suffixmassage.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* suffixmassage.c - massages ldap backend dns */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/suffixmassage.c,v 1.1.2.7 2007/01/02 21:44:04 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/suffixmassage.c,v 1.7.2.2 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-meta/unbind.c
===================================================================
--- openldap/trunk/servers/slapd/back-meta/unbind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-meta/unbind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/unbind.c,v 1.11.2.14 2007/01/17 23:03:20 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/unbind.c,v 1.30.2.4 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-monitor/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-monitor
-# $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/Makefile.in,v 1.18.2.3 2007/01/02 21:44:04 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/Makefile.in,v 1.20.2.2 2007/08/31 23:14:03 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-monitor/back-monitor.h
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/back-monitor.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/back-monitor.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* back-monitor.h - ldap monitor back-end header file */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/back-monitor.h,v 1.39.2.7 2007/01/02 21:44:04 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/back-monitor.h,v 1.52.2.4 2007/09/29 09:27:01 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -39,9 +39,13 @@
 	int				(*mc_modify)( Operation *op, SlapReply *rs, Entry *e, void *priv );
 						/* modify callback
 						   for user-defined entries */
-	int				(*mc_free)( Entry *e, void *priv );
+	int				(*mc_free)( Entry *e, void **priv );
 						/* delete callback
 						   for user-defined entries */
+	void				(*mc_dispose)( void **priv );
+						/* dispose callback
+						   to dispose of the callback
+						   private data itself */
 	void				*mc_private;	/* opaque pointer to
 						   private data */
 	struct monitor_callback_t	*mc_next;
@@ -70,6 +74,8 @@
 	struct monitor_callback_t	*mp_cb;		/* callback sequence */
 } monitor_entry_t;
 
+struct entry_limbo_t;			/* in init.c */
+
 typedef struct monitor_info_t {
 
 	/*
@@ -83,6 +89,7 @@
 	 */
 	struct berval		mi_startTime;		/* don't free it! */
 	struct berval		mi_creatorsName;	/* don't free it! */
+	struct berval		mi_ncreatorsName;	/* don't free it! */
 
 	/*
 	 * Specific schema entities
@@ -130,7 +137,7 @@
 	AttributeDescription	*mi_ad_readOnly;
 	AttributeDescription	*mi_ad_restrictedOperation;
 
-	void			*mi_entry_limbo;
+	struct entry_limbo_t	*mi_entry_limbo;
 } monitor_info_t;
 
 /*
@@ -267,6 +274,37 @@
 /* increase this bufsize if entries in string form get too big */
 #define BACKMONITOR_BUFSIZE	8192
 
+typedef int (monitor_cbfunc)( struct berval *ndn, monitor_callback_t *cb,
+	struct berval *base, int scope, struct berval *filter );
+
+typedef int (monitor_cbafunc)( struct berval *ndn, Attribute *a,
+	monitor_callback_t *cb,
+	struct berval *base, int scope, struct berval *filter );
+
+typedef struct monitor_extra_t {
+	int (*is_configured)(void);
+	monitor_subsys_t * (*get_subsys)( const char *name );
+	monitor_subsys_t * (*get_subsys_by_dn)( struct berval *ndn, int sub );
+
+	int (*register_subsys)( monitor_subsys_t *ms );
+	int (*register_backend)( BackendInfo *bi );
+	int (*register_database)( BackendDB *be, struct berval *ndn );
+	int (*register_overlay_info)( slap_overinst *on );
+	int (*register_overlay)( BackendDB *be );
+	int (*register_entry)( Entry *e, monitor_callback_t *cb,
+		monitor_subsys_t *ms, unsigned long flags );
+	int (*register_entry_parent)( Entry *e, monitor_callback_t *cb,
+		monitor_subsys_t *ms, unsigned long flags,
+		struct berval *base, int scope, struct berval *filter );
+	monitor_cbafunc *register_entry_attrs;
+	monitor_cbfunc *register_entry_callback;
+
+	int (*unregister_entry)( struct berval *ndn );
+	monitor_cbfunc *unregister_entry_parent;
+	monitor_cbafunc *unregister_entry_attrs;
+	monitor_cbfunc *unregister_entry_callback;
+} monitor_extra_t;
+
 LDAP_END_DECL
 
 #include "proto-back-monitor.h"

Modified: openldap/trunk/servers/slapd/back-monitor/backend.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/backend.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/backend.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* backend.c - deals with backend subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/backend.c,v 1.33.2.5 2007/01/02 21:44:04 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/backend.c,v 1.41.2.2 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -79,32 +79,12 @@
 
 		i++;
 
-		snprintf( buf, sizeof( buf ),
-				"dn: cn=Backend %d,%s\n"
-				"objectClass: %s\n"
-				"structuralObjectClass: %s\n"
-				"cn: Backend %d\n"
-				"%s: %s\n"
-				"%s: %s\n"
-				"creatorsName: %s\n"
-				"modifiersName: %s\n"
-				"createTimestamp: %s\n"
-				"modifyTimestamp: %s\n",
-				i,
-				ms->mss_dn.bv_val,
-				mi->mi_oc_monitoredObject->soc_cname.bv_val,
-				mi->mi_oc_monitoredObject->soc_cname.bv_val,
-				i,
-				mi->mi_ad_monitoredInfo->ad_cname.bv_val,
-					bi->bi_type,
-				mi->mi_ad_monitorRuntimeConfig->ad_cname.bv_val,
-					bi->bi_cf_ocs == NULL ? "FALSE" : "TRUE",
-				mi->mi_creatorsName.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_startTime.bv_val,
-				mi->mi_startTime.bv_val );
-		
-		e = str2entry( buf );
+		bv.bv_len = snprintf( buf, sizeof( buf ), "cn=Backend %d", i );
+		bv.bv_val = buf;
+
+		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
+			mi->mi_oc_monitoredObject, mi, NULL, NULL );
+
 		if ( e == NULL ) {
 			Debug( LDAP_DEBUG_ANY,
 				"monitor_subsys_backend_init: "
@@ -114,9 +94,15 @@
 		}
 		
 		ber_str2bv( bi->bi_type, 0, 0, &bv );
+		attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
+				&bv, NULL );
 		attr_merge_normalize_one( e_backend, mi->mi_ad_monitoredInfo,
 				&bv, NULL );
 
+		attr_merge_normalize_one( e, mi->mi_ad_monitorRuntimeConfig,
+			bi->bi_cf_ocs == NULL ? (struct berval *)&slap_false_bv :
+				(struct berval *)&slap_true_bv, NULL );
+
 		if ( bi->bi_controls ) {
 			int j;
 

Modified: openldap/trunk/servers/slapd/back-monitor/bind.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* bind.c - monitor backend bind routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/bind.c,v 1.14.2.4 2007/01/02 21:44:04 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/bind.c,v 1.17.2.2 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -35,11 +35,8 @@
 {
 	Debug(LDAP_DEBUG_ARGS, "==> monitor_back_bind: dn: %s\n", 
 			op->o_req_dn.bv_val, 0, 0 );
-	
-	if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE 
-			&& be_isroot_pw( op ) )
-	{
-		ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
+
+	if ( be_isroot_pw( op ) ) {
 		return LDAP_SUCCESS;
 	}
 

Modified: openldap/trunk/servers/slapd/back-monitor/cache.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/cache.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/cache.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* cache.c - routines to maintain an in-core cache of entries */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/cache.c,v 1.19.2.6 2007/01/02 21:44:04 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/cache.c,v 1.27.2.3 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -120,6 +120,22 @@
 }
 
 /*
+ * tries to lock the entry (no r/w)
+ */
+int
+monitor_cache_trylock(
+	Entry		*e )
+{
+	monitor_entry_t *mp;
+
+	assert( e != NULL );
+	assert( e->e_private != NULL );
+
+	mp = ( monitor_entry_t * )e->e_private;
+	return ldap_pvt_thread_mutex_trylock( &mp->mp_mutex );
+}
+
+/*
  * gets an entry from the cache based on the normalized dn 
  * with mutex locked
  */
@@ -154,6 +170,112 @@
 }
 
 /*
+ * gets an entry from the cache based on the normalized dn 
+ * with mutex locked
+ */
+int
+monitor_cache_remove(
+	monitor_info_t	*mi,
+	struct berval	*ndn,
+	Entry		**ep )
+{
+	monitor_cache_t tmp_mc, *mc;
+	struct berval	pndn;
+
+	assert( mi != NULL );
+	assert( ndn != NULL );
+	assert( ep != NULL );
+
+	*ep = NULL;
+
+	dnParent( ndn, &pndn );
+
+retry:;
+	ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
+
+	tmp_mc.mc_ndn = *ndn;
+	mc = ( monitor_cache_t * )avl_find( mi->mi_cache,
+			( caddr_t )&tmp_mc, monitor_cache_cmp );
+
+	if ( mc != NULL ) {
+		monitor_cache_t *pmc;
+
+		if ( monitor_cache_trylock( mc->mc_e ) ) {
+			ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
+			goto retry;
+		}
+
+		tmp_mc.mc_ndn = pndn;
+		pmc = ( monitor_cache_t * )avl_find( mi->mi_cache,
+			( caddr_t )&tmp_mc, monitor_cache_cmp );
+		if ( pmc != NULL ) {
+			monitor_entry_t	*mp = (monitor_entry_t *)mc->mc_e->e_private,
+					*pmp = (monitor_entry_t *)pmc->mc_e->e_private;
+			Entry		**entryp;
+
+			if ( monitor_cache_trylock( pmc->mc_e ) ) {
+				monitor_cache_release( mi, mc->mc_e );
+				ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
+				goto retry;
+			}
+
+			for ( entryp = &pmp->mp_children; *entryp != NULL;  ) {
+				monitor_entry_t	*next = (monitor_entry_t *)(*entryp)->e_private;
+				if ( next == mp ) {
+					*entryp = next->mp_next;
+					entryp = NULL;
+					break;
+				}
+
+				entryp = &next->mp_next;
+			}
+
+			if ( entryp != NULL ) {
+				Debug( LDAP_DEBUG_ANY,
+					"monitor_cache_remove(\"%s\"): "
+					"not in parent's list\n",
+					ndn->bv_val, 0, 0 );
+			}
+
+			/* either succeeded, and the entry is no longer
+			 * in its parent's list, or failed, and the
+			 * entry is neither mucked with nor returned */
+			monitor_cache_release( mi, pmc->mc_e );
+
+			if ( entryp == NULL ) {
+				monitor_cache_t *tmpmc;
+
+				tmp_mc.mc_ndn = *ndn;
+				tmpmc = avl_delete( &mi->mi_cache,
+					( caddr_t )&tmp_mc, monitor_cache_cmp );
+				assert( tmpmc == mc );
+
+				*ep = mc->mc_e;
+				ch_free( mc );
+				mc = NULL;
+
+				/* NOTE: we destroy the mutex, but otherwise
+				 * leave the private data around; specifically,
+				 * callbacks need be freed by someone else */
+
+				ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
+				mp->mp_next = NULL;
+				mp->mp_children = NULL;
+			}
+
+		}
+
+		if ( mc ) {
+			monitor_cache_release( mi, mc->mc_e );
+		}
+	}
+
+	ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
+
+	return ( *ep == NULL ? -1 : 0 );
+}
+
+/*
  * If the entry exists in cache, it is returned in locked status;
  * otherwise, if the parent exists, if it may generate volatile 
  * descendants an attempt to generate the required entry is
@@ -277,11 +399,18 @@
 		mp = ( monitor_entry_t * )mc->mc_e->e_private;
 
 		if ( mp->mp_cb ) {
-			if ( mp->mp_cb->mc_free ) {
-				mp->mp_cb->mc_free( mc->mc_e,
-					mp->mp_cb->mc_private );
+			monitor_callback_t	*cb;
+
+			for ( cb = mp->mp_cb; cb != NULL; ) {
+				monitor_callback_t	*next = cb->mc_next;
+
+				if ( cb->mc_free ) {
+					(void)cb->mc_free( mc->mc_e, &cb->mc_private );
+				}
+				ch_free( mp->mp_cb );
+
+				cb = next;
 			}
-			ch_free( mp->mp_cb );
 		}
 
 		ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );

Modified: openldap/trunk/servers/slapd/back-monitor/compare.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* compare.c - monitor backend compare routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/compare.c,v 1.20.2.4 2007/01/02 21:44:04 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/compare.c,v 1.24.2.4 2007/09/29 09:55:22 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -27,7 +27,7 @@
 #include "back-monitor.h"
 
 int
-monitor_back_compare( struct slap_op *op, struct slap_rep *rs)
+monitor_back_compare( Operation *op, SlapReply *rs )
 {
 	monitor_info_t	*mi = ( monitor_info_t * ) op->o_bd->be_private;
 	Entry           *e, *matched = NULL;
@@ -39,15 +39,12 @@
 	if ( e == NULL ) {
 		rs->sr_err = LDAP_NO_SUCH_OBJECT;
 		if ( matched ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 			if ( !access_allowed_mask( op, matched,
 					slap_schema.si_ad_entry,
 					NULL, ACL_DISCLOSE, NULL, NULL ) )
 			{
 				/* do nothing */ ;
-			} else 
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-			{
+			} else {
 				rs->sr_matched = matched->e_dn;
 			}
 		}
@@ -74,10 +71,10 @@
 			a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc )) {
 		rs->sr_err = LDAP_COMPARE_FALSE;
 
-		if ( value_find_ex( op->oq_compare.rs_ava->aa_desc,
+		if ( attr_valfind( a,
 			SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
 				SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-			a->a_nvals, &op->oq_compare.rs_ava->aa_value,
+			&op->oq_compare.rs_ava->aa_value, NULL,
 			op->o_tmpmemctx ) == 0 )
 		{
 			rs->sr_err = LDAP_COMPARE_TRUE;
@@ -97,13 +94,11 @@
 		break;
 
 	default:
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 		if ( !access_allowed_mask( op, e, slap_schema.si_ad_entry,
 				NULL, ACL_DISCLOSE, NULL, NULL ) )
 		{
 			rs->sr_err = LDAP_NO_SUCH_OBJECT;
 		}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 		break;
 	}
 		

Modified: openldap/trunk/servers/slapd/back-monitor/conn.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/conn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/conn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* conn.c - deal with connection subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/conn.c,v 1.56.2.7 2007/01/23 00:34:13 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/conn.c,v 1.72.2.5 2007/10/08 09:48:15 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -28,10 +28,6 @@
 #include "lutil.h"
 #include "back-monitor.h"
 
-#ifndef LDAP_DEVEL
-#define MONITOR_LEGACY_CONN
-#endif
-
 static int
 monitor_subsys_conn_update(
 	Operation		*op,
@@ -77,26 +73,57 @@
 	ep = &mp->mp_children;
 
 	/*
+	 * Max file descriptors
+	 */
+	BER_BVSTR( &bv, "cn=Max File Descriptors" );
+	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
+		mi->mi_oc_monitorCounterObject, mi, NULL, NULL );
+	
+	if ( e == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_conn_init: "
+			"unable to create entry \"%s,%s\"\n",
+			bv.bv_val, ms->mss_ndn.bv_val, 0 );
+		return( -1 );
+	}
+
+	if ( dtblsize ) {
+		bv.bv_val = buf;
+		bv.bv_len = snprintf( buf, sizeof( buf ), "%d", dtblsize );
+
+	} else {
+		BER_BVSTR( &bv, "0" );
+	}
+	attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, &bv );
+	
+	mp = monitor_entrypriv_create();
+	if ( mp == NULL ) {
+		return -1;
+	}
+	e->e_private = ( void * )mp;
+	mp->mp_info = ms;
+	mp->mp_flags = ms->mss_flags \
+		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
+	mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
+
+	if ( monitor_cache_add( mi, e ) ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_conn_init: "
+			"unable to add entry \"cn=Total,%s\"\n",
+			ms->mss_ndn.bv_val, 0, 0 );
+		return( -1 );
+	}
+
+	*ep = e;
+	ep = &mp->mp_next;
+	
+	/*
 	 * Total conns
 	 */
-	snprintf( buf, sizeof( buf ),
-		"dn: cn=Total,%s\n"
-		"objectClass: %s\n"
-		"structuralObjectClass: %s\n"
-		"cn: Total\n"
-		"creatorsName: %s\n"
-		"modifiersName: %s\n"
-		"createTimestamp: %s\n"
-		"modifyTimestamp: %s\n",
-		ms->mss_dn.bv_val,
-		mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
-		mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
-		mi->mi_creatorsName.bv_val,
-		mi->mi_creatorsName.bv_val,
-		mi->mi_startTime.bv_val,
-		mi->mi_startTime.bv_val );
+	BER_BVSTR( &bv, "cn=Total" );
+	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
+		mi->mi_oc_monitorCounterObject, mi, NULL, NULL );
 	
-	e = str2entry( buf );
 	if ( e == NULL ) {
 		Debug( LDAP_DEBUG_ANY,
 			"monitor_subsys_conn_init: "
@@ -105,7 +132,7 @@
 		return( -1 );
 	}
 	
-	BER_BVSTR( &bv, "0" );
+	BER_BVSTR( &bv, "-1" );
 	attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, &bv );
 	
 	mp = monitor_entrypriv_create();
@@ -132,24 +159,10 @@
 	/*
 	 * Current conns
 	 */
-	snprintf( buf, sizeof( buf ),
-		"dn: cn=Current,%s\n"
-		"objectClass: %s\n"
-		"structuralObjectClass: %s\n"
-		"cn: Current\n"
-		"creatorsName: %s\n"
-		"modifiersName: %s\n"
-		"createTimestamp: %s\n"
-		"modifyTimestamp: %s\n",
-		ms->mss_dn.bv_val,
-		mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
-		mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
-		mi->mi_creatorsName.bv_val,
-		mi->mi_creatorsName.bv_val,
-		mi->mi_startTime.bv_val,
-		mi->mi_startTime.bv_val );
-	
-	e = str2entry( buf );
+	BER_BVSTR( &bv, "cn=Current" );
+	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
+		mi->mi_oc_monitorCounterObject, mi, NULL, NULL );
+
 	if ( e == NULL ) {
 		Debug( LDAP_DEBUG_ANY,
 			"monitor_subsys_conn_init: "
@@ -214,7 +227,8 @@
 
 		for ( n = 0, c = connection_first( &connindex );
 				c != NULL;
-				n++, c = connection_next( c, &connindex ) ) {
+				n++, c = connection_next( c, &connindex ) )
+		{
 			/* No Op */ ;
 		}
 		connection_done( c );
@@ -252,17 +266,20 @@
 	monitor_subsys_t	*ms )
 {
 	monitor_entry_t *mp;
-	struct tm	*ltm;
+	struct tm	*tm;
 	char		buf[ BACKMONITOR_BUFSIZE ];
 	char		buf2[ LDAP_LUTIL_GENTIME_BUFSIZE ];
 	char		buf3[ LDAP_LUTIL_GENTIME_BUFSIZE ];
 
+	struct berval bv, ctmbv, mtmbv, bv2, bv3;
+	struct berval bv_unknown= BER_BVC("unknown");
+
 	Entry		*e;
 
-	struct tm	*ctm;
+#ifdef HACK_LOCAL_TIME
 	char		ctmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
-	struct tm	*mtm;
 	char		mtmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
+#endif
 #ifdef HAVE_GMTIME_R
 	struct tm	tm_buf;
 #endif /* HAVE_GMTIME_R */
@@ -273,67 +290,69 @@
 #ifndef HAVE_GMTIME_R
 	ldap_pvt_thread_mutex_lock( &gmtime_mutex );
 #endif
+
+#ifdef HAVE_GMTIME_R
+	tm = gmtime_r( &c->c_starttime, &tm_buf );
+#else
+	tm = gmtime( &c->c_starttime );
+#endif
+	bv2.bv_len = lutil_gentime( buf2, sizeof( buf2 ), tm );
+	bv2.bv_val = buf2;
 #ifdef HACK_LOCAL_TIME
 # ifdef HAVE_LOCALTIME_R
-	ctm = localtime_r( &c->c_starttime, &tm_buf );
-	lutil_localtime( ctmbuf, sizeof( ctmbuf ), ctm, -timezone );
-	mtm = localtime_r( &c->c_activitytime, &tm_buf );
-	lutil_localtime( mtmbuf, sizeof( mtmbuf ), mtm, -timezone );
+	tm = localtime_r( &c->c_starttime, &tm_buf );
 # else
-	ctm = localtime( &c->c_starttime );
-	lutil_localtime( ctmbuf, sizeof( ctmbuf ), ctm, -timezone );
-	mtm = localtime( &c->c_activitytime );
-	lutil_localtime( mtmbuf, sizeof( mtmbuf ), mtm, -timezone );
-# endif /* HAVE_LOCALTIME_R */
+	tm = localtime( &c->c_starttime );
+# endif
+	ctmbv.bv_len = lutil_localtime( ctmbuf, sizeof( ctmbuf ), tm, -timezone );
+	ctmbv.bv_val = ctmbuf;
 #else /* !HACK_LOCAL_TIME */
-# ifdef HAVE_GMTIME_R
-	ctm = gmtime_r( &c->c_starttime, &tm_buf );
-	lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
-	mtm = gmtime_r( &c->c_activitytime, &tm_buf );
-	lutil_gentime( mtmbuf, sizeof( mtmbuf ), mtm );
-# else
-	ctm = gmtime( &c->c_starttime );
-	lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
-	mtm = gmtime( &c->c_activitytime );
-	lutil_gentime( mtmbuf, sizeof( mtmbuf ), mtm );
-# endif /* HAVE_GMTIME_R */
-#endif /* !HACK_LOCAL_TIME */
-#ifndef HAVE_GMTIME_R
-	ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
+	ctmbv = bv2;
 #endif
 
-#ifndef HAVE_GMTIME_R
-	ldap_pvt_thread_mutex_lock( &gmtime_mutex );
-#endif
-
 #ifdef HAVE_GMTIME_R
-	ltm = gmtime_r( &c->c_starttime, &tm_buf );
+	tm = gmtime_r( &c->c_activitytime, &tm_buf );
 #else
-	ltm = gmtime( &c->c_starttime );
+	tm = gmtime( &c->c_activitytime );
 #endif
-	lutil_gentime( buf2, sizeof( buf2 ), ltm );
-
-#ifdef HAVE_GMTIME_R
-	ltm = gmtime_r( &c->c_activitytime, &tm_buf );
-#else
-	ltm = gmtime( &c->c_activitytime );
+	bv3.bv_len = lutil_gentime( buf3, sizeof( buf3 ), tm );
+	bv3.bv_val = buf3;
+#ifdef HACK_LOCAL_TIME
+# ifdef HAVE_LOCALTIME_R
+	tm = localtime_r( &c->c_activitytime, &tm_buf );
+# else
+	tm = localtime( &c->c_activitytime );
+# endif /* HAVE_LOCALTIME_R */
+	mtmbv.bv_len = lutil_localtime( mtmbuf, sizeof( mtmbuf ), tm, -timezone );
+	mtmbv.bv_val = mtmbuf;
+#else /* !HACK_LOCAL_TIME */
+	mtmbv = bv3;
 #endif
-	lutil_gentime( buf3, sizeof( buf3 ), ltm );
 
 #ifndef HAVE_GMTIME_R
 	ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
-#endif /* HAVE_GMTIME_R */
+#endif
 
-	snprintf( buf, sizeof( buf ),
-		"dn: cn=Connection %ld,%s\n"
-		"objectClass: %s\n"
-		"structuralObjectClass: %s\n"
-		"cn: Connection %ld\n"
+	bv.bv_len = snprintf( buf, sizeof( buf ),
+		"cn=Connection %ld", c->c_connid );
+	bv.bv_val = buf;
+	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv, 
+		mi->mi_oc_monitorConnection, mi, &ctmbv, &mtmbv );
 
+	if ( e == NULL) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_conn_create: "
+			"unable to create entry "
+			"\"cn=Connection %ld,%s\"\n",
+			c->c_connid, 
+			ms->mss_dn.bv_val, 0 );
+		return( -1 );
+	}
+
 #ifdef MONITOR_LEGACY_CONN
-		/* NOTE: this will disappear, as the exploded data
-		 * has been moved to dedicated attributes */
-		"%s: "
+	/* NOTE: this will disappear, as the exploded data
+	 * has been moved to dedicated attributes */
+	bv.bv_len = snprintf( buf, sizeof( buf ),
 			"%ld "
 			": %ld "
 			": %ld/%ld/%ld/%ld "
@@ -345,44 +364,7 @@
 			": %s "
 			": %s "
 			": %s "
-			": %s\n"
-#endif /* MONITOR_LEGACY_CONN */
-
-		"%s: %lu\n"
-		"%s: %ld\n"
-
-		"%s: %ld\n"
-		"%s: %ld\n"
-		"%s: %ld\n"
-		"%s: %ld\n"
-
-		"%s: %ld\n"
-		"%s: %ld\n"
-		"%s: %ld\n"
-
-		"%s: %s%s%s%s%s%s\n"
-
-		"%s: %s\n"
-
-		"%s: %s\n"
-		"%s: %s\n"
-		"%s: %s\n"
-		"%s: %s\n"
-
-		"%s: %s\n"
-		"%s: %s\n"
-
-		"creatorsName: %s\n"
-		"modifiersName: %s\n"
-		"createTimestamp: %s\n"
-		"modifyTimestamp: %s\n",
-		c->c_connid, ms->mss_dn.bv_val,
-		mi->mi_oc_monitorConnection->soc_cname.bv_val,
-		mi->mi_oc_monitorConnection->soc_cname.bv_val,
-		c->c_connid,
-
-#ifdef MONITOR_LEGACY_CONN
-		mi->mi_ad_monitoredInfo->ad_cname.bv_val,
+			": %s",
 			c->c_connid,
 			(long) c->c_protocol,
 			c->c_n_ops_received, c->c_n_ops_executing,
@@ -408,73 +390,70 @@
 			c->c_sock_name.bv_val,
 			
 			buf2,
-			buf3,
+			buf3 );
+	attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
 #endif /* MONITOR_LEGACY_CONN */
 
-		mi->mi_ad_monitorConnectionNumber->ad_cname.bv_val,
-			c->c_connid,
-		mi->mi_ad_monitorConnectionProtocol->ad_cname.bv_val,
-			(long)c->c_protocol,
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", c->c_connid );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionNumber, &bv, NULL );
 
-		mi->mi_ad_monitorConnectionOpsReceived->ad_cname.bv_val,
-			c->c_n_ops_received,
-		mi->mi_ad_monitorConnectionOpsExecuting->ad_cname.bv_val,
-			c->c_n_ops_executing,
-		mi->mi_ad_monitorConnectionOpsPending->ad_cname.bv_val,
-			c->c_n_ops_pending,
-		mi->mi_ad_monitorConnectionOpsCompleted->ad_cname.bv_val,
-			c->c_n_ops_completed,
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", (long) c->c_protocol );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionProtocol, &bv, NULL );
 
-		mi->mi_ad_monitorConnectionGet->ad_cname.bv_val,
-			c->c_n_get,
-		mi->mi_ad_monitorConnectionRead->ad_cname.bv_val,
-			c->c_n_read,
-		mi->mi_ad_monitorConnectionWrite->ad_cname.bv_val,
-			c->c_n_write,
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_received );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionOpsReceived, &bv, NULL );
 
-		mi->mi_ad_monitorConnectionMask->ad_cname.bv_val,
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_executing );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionOpsExecuting, &bv, NULL );
+
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_pending );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionOpsPending, &bv, NULL );
+
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_completed );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionOpsCompleted, &bv, NULL );
+
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_get );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionGet, &bv, NULL );
+
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_read );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionRead, &bv, NULL );
+
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_write );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionWrite, &bv, NULL );
+
+	bv.bv_len = snprintf( buf, sizeof( buf ), "%s%s%s%s%s%s",
 			c->c_currentber ? "r" : "",
 			c->c_writewaiter ? "w" : "",
 			LDAP_STAILQ_EMPTY( &c->c_ops ) ? "" : "x",
 			LDAP_STAILQ_EMPTY( &c->c_pending_ops ) ? "" : "p",
 			connection_state2str( c->c_conn_state ),
-			c->c_sasl_bind_in_progress ? "S" : "",
-		
-		mi->mi_ad_monitorConnectionAuthzDN->ad_cname.bv_val,
-			c->c_dn.bv_len ? c->c_dn.bv_val : SLAPD_ANONYMOUS,
+			c->c_sasl_bind_in_progress ? "S" : "" );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionMask, &bv, NULL );
 
-		/* NOTE: client connections leave the c_peer_* fields NULL */
-		mi->mi_ad_monitorConnectionListener->ad_cname.bv_val,
-			c->c_listener_url.bv_val,
-		mi->mi_ad_monitorConnectionPeerDomain->ad_cname.bv_val,
-			BER_BVISNULL( &c->c_peer_domain ) ? "unknown" : c->c_peer_domain.bv_val,
-		mi->mi_ad_monitorConnectionLocalAddress->ad_cname.bv_val,
-			BER_BVISNULL( &c->c_peer_name ) ? "unknown" : c->c_peer_name.bv_val,
-		mi->mi_ad_monitorConnectionPeerAddress->ad_cname.bv_val,
-			c->c_sock_name.bv_val,
+	attr_merge_one( e, mi->mi_ad_monitorConnectionAuthzDN,
+		&c->c_dn, &c->c_ndn );
 
-		mi->mi_ad_monitorConnectionStartTime->ad_cname.bv_val,
-			buf2,
-		mi->mi_ad_monitorConnectionActivityTime->ad_cname.bv_val,
-			buf3,
+	/* NOTE: client connections leave the c_peer_* fields NULL */
+	assert( !BER_BVISNULL( &c->c_listener_url ) );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionListener,
+		&c->c_listener_url, NULL );
 
-		mi->mi_creatorsName.bv_val,
-		mi->mi_creatorsName.bv_val,
-		ctmbuf,
-		mtmbuf );
-		
-	e = str2entry( buf );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionPeerDomain,
+		BER_BVISNULL( &c->c_peer_domain ) ? &bv_unknown : &c->c_peer_domain,
+		NULL );
 
-	if ( e == NULL) {
-		Debug( LDAP_DEBUG_ANY,
-			"monitor_subsys_conn_create: "
-			"unable to create entry "
-			"\"cn=Connection %ld,%s\" entry\n",
-			c->c_connid, 
-			ms->mss_dn.bv_val, 0 );
-		return( -1 );
-	}
+	attr_merge_one( e, mi->mi_ad_monitorConnectionPeerAddress,
+		BER_BVISNULL( &c->c_peer_name ) ? &bv_unknown : &c->c_peer_name,
+		NULL );
 
+	assert( !BER_BVISNULL( &c->c_sock_name ) );
+	attr_merge_one( e, mi->mi_ad_monitorConnectionLocalAddress,
+		&c->c_sock_name, NULL );
+
+	attr_merge_one( e, mi->mi_ad_monitorConnectionStartTime, &bv2, NULL );
+
+	attr_merge_one( e, mi->mi_ad_monitorConnectionActivityTime, &bv3, NULL );
+
 	mp = monitor_entrypriv_create();
 	if ( mp == NULL ) {
 		return LDAP_OTHER;
@@ -498,9 +477,6 @@
 {
 	monitor_info_t	*mi = ( monitor_info_t * )op->o_bd->be_private;
 
-	Connection		*c;
-	int			connindex;
-	monitor_entry_t 	*mp;
 	int			rc = SLAP_CB_CONTINUE;
 	monitor_subsys_t	*ms;
 
@@ -513,14 +489,18 @@
 	*ep = NULL;
 
 	if ( ndn == NULL ) {
-		Entry	*e = NULL,
-			*e_tmp = NULL;
+		Connection	*c;
+		int		connindex;
+		Entry		*e = NULL,
+				*e_tmp = NULL;
 
 		/* create all the children of e_parent */
 		for ( c = connection_first( &connindex );
 				c != NULL;
 				c = connection_next( c, &connindex ) )
 		{
+			monitor_entry_t 	*mp;
+
 			if ( conn_create( mi, c, &e, ms ) != SLAP_CB_CONTINUE
 					|| e == NULL )
 			{
@@ -545,6 +525,8 @@
 		*ep = e;
 
 	} else {
+		Connection		*c;
+		int			connindex;
 		unsigned long 		connid;
 		char			*next = NULL;
 		static struct berval	nconn_bv = BER_BVC( "cn=connection " );

Modified: openldap/trunk/servers/slapd/back-monitor/database.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/database.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/database.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* database.c - deals with database subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/database.c,v 1.61.2.10 2007/01/05 09:47:11 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/database.c,v 1.80.2.7 2007/10/08 09:48:15 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -33,22 +33,6 @@
 static int monitor_back_add_plugin( monitor_info_t *mi, Backend *be, Entry *e );
 #endif /* defined(LDAP_SLAPI) */
 
-#if defined(SLAPD_BDB)
-#include "../back-bdb/back-bdb.h"
-#endif /* defined(SLAPD_BDB) */
-#if defined(SLAPD_HDB)
-#include "../back-hdb/back-bdb.h"
-#endif /* defined(SLAPD_HDB) */
-#if defined(SLAPD_LDAP) 
-#include "../back-ldap/back-ldap.h"
-#endif /* defined(SLAPD_LDAP) */
-#if 0 && defined(SLAPD_LDBM) 
-#include "../back-ldbm/back-ldbm.h"
-#endif /* defined(SLAPD_LDBM) */
-#if defined(SLAPD_META) 
-#include "../back-meta/back-meta.h"
-#endif /* defined(SLAPD_META) */
-
 /* for PATH_MAX on some systems (e.g. Solaris) */
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
@@ -79,8 +63,8 @@
 }, restricted_exops[] = {
 	{ BER_BVC( LDAP_EXOP_START_TLS ),	SLAP_RESTRICT_EXOP_START_TLS },
 	{ BER_BVC( LDAP_EXOP_MODIFY_PASSWD ),	SLAP_RESTRICT_EXOP_MODIFY_PASSWD },
-	{ BER_BVC( LDAP_EXOP_X_WHO_AM_I ),	SLAP_RESTRICT_EXOP_WHOAMI },
-	{ BER_BVC( LDAP_EXOP_X_CANCEL ),	SLAP_RESTRICT_EXOP_CANCEL },
+	{ BER_BVC( LDAP_EXOP_WHO_AM_I ),	SLAP_RESTRICT_EXOP_WHOAMI },
+	{ BER_BVC( LDAP_EXOP_CANCEL ),	SLAP_RESTRICT_EXOP_CANCEL },
 	{ BER_BVNULL,				0 }
 };
 
@@ -123,404 +107,433 @@
 	return LDAP_SUCCESS;
 }
 
-int
-monitor_subsys_database_init(
+static int
+monitor_subsys_database_init_one(
+	monitor_info_t		*mi,
 	BackendDB		*be,
-	monitor_subsys_t	*ms
-)
+	monitor_subsys_t	*ms,
+	monitor_subsys_t	*ms_backend,
+	monitor_subsys_t	*ms_overlay,
+	struct berval		*rdn,
+	Entry			*e_database,
+	Entry			***epp )
 {
-	monitor_info_t		*mi;
-	Entry			*e_database, **ep;
-	int			i;
+	char			buf[ BACKMONITOR_BUFSIZE ];
+	int			j;
+	slap_overinfo		*oi = NULL;
+	BackendInfo		*bi, *bi2;
+	Entry			*e;
 	monitor_entry_t		*mp;
-	monitor_subsys_t	*ms_backend,
-				*ms_overlay;
+	char			*rdnval = strchr( rdn->bv_val, '=' ) + 1;
+	struct berval		bv;
 
-	assert( be != NULL );
+	bi = be->bd_info;
 
-	ms->mss_modify = monitor_subsys_database_modify;
-
-	mi = ( monitor_info_t * )be->be_private;
-
-	ms_backend = monitor_back_get_subsys( SLAPD_MONITOR_BACKEND_NAME );
-	if ( ms_backend == NULL ) {
-		Debug( LDAP_DEBUG_ANY,
-			"monitor_subsys_database_init: "
-			"unable to get "
-			"\"" SLAPD_MONITOR_BACKEND_NAME "\" "
-			"subsystem\n",
-			0, 0, 0 );
-		return -1;
+	if ( overlay_is_over( be ) ) {
+		oi = (slap_overinfo *)be->bd_info->bi_private;
+		bi = oi->oi_orig;
 	}
 
-	ms_overlay = monitor_back_get_subsys( SLAPD_MONITOR_OVERLAY_NAME );
-	if ( ms_overlay == NULL ) {
-		Debug( LDAP_DEBUG_ANY,
-			"monitor_subsys_database_init: "
-			"unable to get "
-			"\"" SLAPD_MONITOR_OVERLAY_NAME "\" "
-			"subsystem\n",
-			0, 0, 0 );
-		return -1;
+	/* Subordinates are not exposed as their own naming context */
+	if ( SLAP_GLUE_SUBORDINATE( be ) ) {
+		return 0;
 	}
 
-	if ( monitor_cache_get( mi, &ms->mss_ndn, &e_database ) ) {
+	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, rdn,
+		mi->mi_oc_monitoredObject, mi, NULL, NULL );
+
+	if ( e == NULL ) {
 		Debug( LDAP_DEBUG_ANY,
 			"monitor_subsys_database_init: "
-			"unable to get entry \"%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
+			"unable to create entry \"%s,%s\"\n",
+			rdn->bv_val, ms->mss_dn.bv_val, 0 );
 		return( -1 );
 	}
 
-	(void)init_readOnly( mi, e_database, frontendDB->be_restrictops );
-	(void)init_restrictedOperation( mi, e_database, frontendDB->be_restrictops );
+	ber_str2bv( bi->bi_type, 0, 0, &bv );
+	attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
+	attr_merge_one( e, mi->mi_ad_monitorIsShadow,
+		SLAP_SHADOW( be ) ? (struct berval *)&slap_true_bv :
+			(struct berval *)&slap_false_bv, NULL );
 
-	mp = ( monitor_entry_t * )e_database->e_private;
-	mp->mp_children = NULL;
-	ep = &mp->mp_children;
+	if ( SLAP_MONITOR( be ) ) {
+		attr_merge( e, slap_schema.si_ad_monitorContext,
+				be->be_suffix, be->be_nsuffix );
+		attr_merge( e_database, slap_schema.si_ad_monitorContext,
+				be->be_suffix, be->be_nsuffix );
 
-	i = -1;
-	LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
-		char		buf[ BACKMONITOR_BUFSIZE ];
-		int		j;
-		slap_overinfo	*oi = NULL;
-		BackendInfo	*bi, *bi2;
-		Entry		*e;
+	} else {
+		if ( be->be_suffix == NULL ) {
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_subsys_database_init: "
+				"missing suffix for %s\n",
+				rdnval, 0, 0 );
+			return -1;
+		}
+		attr_merge( e, slap_schema.si_ad_namingContexts,
+				be->be_suffix, be->be_nsuffix );
+		attr_merge( e_database, slap_schema.si_ad_namingContexts,
+				be->be_suffix, be->be_nsuffix );
+	}
 
-		i++;
+	(void)init_readOnly( mi, e, be->be_restrictops );
+	(void)init_restrictedOperation( mi, e, be->be_restrictops );
 
-		bi = be->bd_info;
+	if ( SLAP_SHADOW( be ) && be->be_update_refs ) {
+		attr_merge_normalize( e, mi->mi_ad_monitorUpdateRef,
+				be->be_update_refs, NULL );
+	}
 
-		if ( overlay_is_over( be ) ) {
-			oi = (slap_overinfo *)be->bd_info->bi_private;
-			bi = oi->oi_orig;
-		}
+	if ( oi != NULL ) {
+		slap_overinst	*on = oi->oi_list,
+				*on1 = on;
 
-		/* Subordinates are not exposed as their own naming context */
-		if ( SLAP_GLUE_SUBORDINATE( be ) ) {
-			continue;
-		}
+		for ( ; on; on = on->on_next ) {
+			slap_overinst		*on2;
 
-		snprintf( buf, sizeof( buf ),
-				"dn: cn=Database %d,%s\n"
-				"objectClass: %s\n"
-				"structuralObjectClass: %s\n"
-				"cn: Database %d\n"
-				"%s: %s\n"
-				"%s: %s\n"
-				"creatorsName: %s\n"
-				"modifiersName: %s\n"
-				"createTimestamp: %s\n"
-				"modifyTimestamp: %s\n",
-				i,
-					ms->mss_dn.bv_val,
-				mi->mi_oc_monitoredObject->soc_cname.bv_val,
-				mi->mi_oc_monitoredObject->soc_cname.bv_val,
-				i,
-				mi->mi_ad_monitoredInfo->ad_cname.bv_val,
-					bi->bi_type,
-				mi->mi_ad_monitorIsShadow->ad_cname.bv_val,
-					SLAP_SHADOW( be ) ? slap_true_bv.bv_val : slap_false_bv.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_startTime.bv_val,
-				mi->mi_startTime.bv_val );
-		
-		e = str2entry( buf );
-		if ( e == NULL ) {
-			Debug( LDAP_DEBUG_ANY,
-				"monitor_subsys_database_init: "
-				"unable to create entry \"cn=Database %d,%s\"\n",
-				i, ms->mss_dn.bv_val, 0 );
-			return( -1 );
-		}
-		
-		if ( SLAP_MONITOR( be ) ) {
-			attr_merge( e, slap_schema.si_ad_monitorContext,
-					be->be_suffix, be->be_nsuffix );
-			attr_merge( e_database, slap_schema.si_ad_monitorContext,
-					be->be_suffix, be->be_nsuffix );
+			for ( on2 = on1; on2 != on; on2 = on2->on_next ) {
+				if ( on2->on_bi.bi_type == on->on_bi.bi_type ) {
+					break;
+				}
+			}
 
-		} else {
-			if ( be->be_suffix == NULL ) {
-				Debug( LDAP_DEBUG_ANY,
-					"monitor_subsys_database_init: "
-					"missing suffix for database %d\n",
-					i, 0, 0 );
-				return -1;
+			if ( on2 != on ) {
+				break;
 			}
-			attr_merge( e, slap_schema.si_ad_namingContexts,
-					be->be_suffix, be->be_nsuffix );
-			attr_merge( e_database, slap_schema.si_ad_namingContexts,
-					be->be_suffix, be->be_nsuffix );
-		}
+			
+			ber_str2bv( on->on_bi.bi_type, 0, 0, &bv );
+			attr_merge_normalize_one( e, mi->mi_ad_monitorOverlay,
+					&bv, NULL );
 
-		(void)init_readOnly( mi, e, be->be_restrictops );
-		(void)init_restrictedOperation( mi, e, be->be_restrictops );
+			/* find the overlay number, j */
+			for ( on2 = overlay_next( NULL ), j = 0; on2; on2 = overlay_next( on2 ), j++ ) {
+				if ( on2->on_bi.bi_type == on->on_bi.bi_type ) {
+					break;
+				}
+			}
+			assert( on2 != NULL );
 
-		if ( SLAP_SHADOW( be ) && be->be_update_refs ) {
-			attr_merge_normalize( e, mi->mi_ad_monitorUpdateRef,
-					be->be_update_refs, NULL );
+			snprintf( buf, sizeof( buf ), 
+				"cn=Overlay %d,%s", 
+				j, ms_overlay->mss_dn.bv_val );
+			ber_str2bv( buf, 0, 0, &bv );
+			attr_merge_normalize_one( e,
+					slap_schema.si_ad_seeAlso,
+					&bv, NULL );
 		}
+	}
 
-		if ( oi != NULL ) {
-			slap_overinst	*on = oi->oi_list,
-					*on1 = on;
+	j = -1;
+	LDAP_STAILQ_FOREACH( bi2, &backendInfo, bi_next ) {
+		j++;
+		if ( bi2->bi_type == bi->bi_type ) {
+			snprintf( buf, sizeof( buf ), 
+				"cn=Backend %d,%s", 
+				j, ms_backend->mss_dn.bv_val );
+			bv.bv_val = buf;
+			bv.bv_len = strlen( buf );
+			attr_merge_normalize_one( e,
+					slap_schema.si_ad_seeAlso,
+					&bv, NULL );
+			break;
+		}
+	}
+	/* we must find it! */
+	assert( j >= 0 );
 
-			for ( ; on; on = on->on_next ) {
-				struct berval		bv;
-				slap_overinst		*on2;
+	mp = monitor_entrypriv_create();
+	if ( mp == NULL ) {
+		return -1;
+	}
+	e->e_private = ( void * )mp;
+	mp->mp_info = ms;
+	mp->mp_flags = ms->mss_flags
+		| MONITOR_F_SUB;
 
-				for ( on2 = on1; on2 != on; on2 = on2->on_next ) {
-					if ( on2->on_bi.bi_type == on->on_bi.bi_type ) {
-						break;
-					}
-				}
+	if ( monitor_cache_add( mi, e ) ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_database_init: "
+			"unable to add entry \"%s,%s\"\n",
+			rdn->bv_val, ms->mss_dn.bv_val, 0 );
+		return( -1 );
+	}
 
-				if ( on2 != on ) {
+#if defined(LDAP_SLAPI)
+	monitor_back_add_plugin( mi, be, e );
+#endif /* defined(LDAP_SLAPI) */
+
+	if ( oi != NULL ) {
+		Entry		**ep_overlay = &mp->mp_children;
+		monitor_entry_t	*mp_overlay;
+		slap_overinst	*on = oi->oi_list;
+		int		o;
+
+		for ( o = 0; on; o++, on = on->on_next ) {
+			Entry			*e_overlay;
+			slap_overinst		*on2;
+
+			/* find the overlay number, j */
+			for ( on2 = overlay_next( NULL ), j = 0; on2; on2 = overlay_next( on2 ), j++ ) {
+				if ( on2->on_bi.bi_type == on->on_bi.bi_type ) {
 					break;
 				}
-				
-				ber_str2bv( on->on_bi.bi_type, 0, 0, &bv );
-				attr_merge_normalize_one( e, mi->mi_ad_monitorOverlay,
-						&bv, NULL );
+			}
+			assert( on2 != NULL );
 
-				/* find the overlay number, j */
-				for ( on2 = overlay_next( NULL ), j = 0; on2; on2 = overlay_next( on2 ), j++ ) {
-					if ( on2->on_bi.bi_type == on->on_bi.bi_type ) {
-						break;
-					}
-				}
-				assert( on2 != NULL );
+			bv.bv_len = snprintf( buf, sizeof( buf ), "cn=Overlay %d", o );
+			bv.bv_val = buf;
 
-				snprintf( buf, sizeof( buf ), 
-					"cn=Overlay %d,%s", 
-					j, ms_overlay->mss_dn.bv_val );
-				ber_str2bv( buf, 0, 0, &bv );
-				attr_merge_normalize_one( e,
-						slap_schema.si_ad_seeAlso,
-						&bv, NULL );
+			e_overlay = monitor_entry_stub( &e->e_name, &e->e_nname, &bv,
+				mi->mi_oc_monitoredObject, mi, NULL, NULL );
+
+			if ( e_overlay == NULL ) {
+				Debug( LDAP_DEBUG_ANY,
+					"monitor_subsys_database_init: "
+					"unable to create entry "
+					"\"cn=Overlay %d,%s,%s\"\n",
+					o, rdn->bv_val, ms->mss_dn.bv_val );
+				return( -1 );
 			}
-		}
+			ber_str2bv( on->on_bi.bi_type, 0, 0, &bv );
+			attr_merge_normalize_one( e_overlay, mi->mi_ad_monitoredInfo, &bv, NULL );
 
+			bv.bv_len = snprintf( buf, sizeof( buf ), "cn=Overlay %d,%s",
+				j, ms_overlay->mss_dn.bv_val );
+			bv.bv_val = buf;
+			attr_merge_normalize_one( e_overlay, slap_schema.si_ad_seeAlso,
+				&bv, NULL );
 
-		if ( 0 ) {
-			assert( 0 );
+			if ( SLAP_MONITOR( be ) ) {
+				attr_merge( e_overlay, slap_schema.si_ad_monitorContext,
+						be->be_suffix, be->be_nsuffix );
 
-#if defined(SLAPD_BDB) || defined(SLAPD_HDB) 
-		} else if ( strcmp( bi->bi_type, "bdb" ) == 0
-				|| strcmp( bi->bi_type, "hdb" ) == 0 )
-		{
-			struct berval	bv;
-			ber_len_t	pathlen = 0, len = 0;
-			char		path[ PATH_MAX ] = { '\0' };
-			struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-			char		*fname = bdb->bi_dbenv_home;
-
-			len = strlen( fname );
-			if ( fname[ 0 ] != '/' ) {
-				/* get full path name */
-				getcwd( path, sizeof( path ) );
-				pathlen = strlen( path );
-
-				if ( fname[ 0 ] == '.' && fname[ 1 ] == '/' ) {
-					fname += 2;
-					len -= 2;
-				}
+			} else {
+				attr_merge( e_overlay, slap_schema.si_ad_namingContexts,
+						be->be_suffix, be->be_nsuffix );
 			}
 
-			bv.bv_len = STRLENOF( "file://" ) + pathlen
-				+ STRLENOF( "/" ) + len;
-			bv.bv_val = ch_malloc( bv.bv_len + STRLENOF( "/" ) + 1 );
-			AC_MEMCPY( bv.bv_val, "file://", STRLENOF( "file://" ) );
-			if ( pathlen ) {
-				AC_MEMCPY( &bv.bv_val[ STRLENOF( "file://" ) ],
-						path, pathlen );
-				bv.bv_val[ STRLENOF( "file://" ) + pathlen ] = '/';
-				pathlen++;
+			mp_overlay = monitor_entrypriv_create();
+			if ( mp_overlay == NULL ) {
+				return -1;
 			}
-			AC_MEMCPY( &bv.bv_val[ STRLENOF( "file://" ) + pathlen ],
-					fname, len );
-			if ( bv.bv_val[ bv.bv_len - 1 ] != '/' ) {
-				bv.bv_val[ bv.bv_len ] = '/';
-				bv.bv_len++;
+			e_overlay->e_private = ( void * )mp_overlay;
+			mp_overlay->mp_info = ms;
+			mp_overlay->mp_flags = ms->mss_flags
+				| MONITOR_F_SUB;
+	
+			if ( monitor_cache_add( mi, e_overlay ) ) {
+				Debug( LDAP_DEBUG_ANY,
+					"monitor_subsys_database_init: "
+					"unable to add entry "
+					"\"cn=Overlay %d,%s,%s\"\n",
+					o, rdn->bv_val, ms->mss_dn.bv_val );
+				return( -1 );
 			}
-			bv.bv_val[ bv.bv_len ] = '\0';
 
-			attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI,
-					&bv, NULL );
+			*ep_overlay = e_overlay;
+			ep_overlay = &mp_overlay->mp_next;
+		}
+	}
 
-			ch_free( bv.bv_val );
+	**epp = e;
+	*epp = &mp->mp_next;
 
-#endif /* defined(SLAPD_BDB) || defined(SLAPD_HDB) */
-#if defined(SLAPD_LDAP) 
-		} else if ( strcmp( bi->bi_type, "ldap" ) == 0 ) {
-			ldapinfo_t	*li = (ldapinfo_t *)be->be_private;
-#if 0
-			attr_merge_normalize( e, slap_schema.si_ad_labeledURI,
-					li->li_bvuri, NULL );
-#else
-			char		**urls = ldap_str2charray( li->li_uri, " " );
-			int		u;
+	return 0;
+}
 
-			for ( u = 0; urls[ u ] != NULL; u++ ) {
-				struct berval	bv;
+int
+monitor_back_register_database(
+	BackendDB		*be,
+	struct berval	*ndn )
+{
+	monitor_info_t		*mi;
+	Entry			*e_database, **ep;
+	int			i, rc;
+	monitor_entry_t		*mp;
+	monitor_subsys_t	*ms_backend,
+				*ms_database,
+				*ms_overlay;
+	struct berval		bv;
+	char			buf[ BACKMONITOR_BUFSIZE ];
 
-				ber_str2bv( urls[ u ], 0, 0, &bv );
+	assert( be_monitor != NULL );
 
-				attr_merge_normalize_one( e,
-						slap_schema.si_ad_labeledURI,
-						&bv, NULL );
-			}
+	if ( !monitor_subsys_is_opened() ) {
+		return monitor_back_register_database_limbo( be, ndn );
+	}
 
-			ldap_charray_free( urls );
-#endif
+	mi = ( monitor_info_t * )be_monitor->be_private;
 
-#endif /* defined(SLAPD_LDAP) */
-#if defined(SLAPD_META) 
-		} else if ( strcmp( bi->bi_type, "meta" ) == 0 ) {
-			metainfo_t	*mi = (metainfo_t *)be->be_private;
-			int		t;
+	ms_backend = monitor_back_get_subsys( SLAPD_MONITOR_BACKEND_NAME );
+	if ( ms_backend == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_back_register_database: "
+			"unable to get "
+			"\"" SLAPD_MONITOR_BACKEND_NAME "\" "
+			"subsystem\n",
+			0, 0, 0 );
+		return -1;
+	}
 
-			for ( t = 0; t < mi->mi_ntargets; t++ ) {
-				char		**urls = ldap_str2charray( mi->mi_targets[ t ]->mt_uri, " " );
-				int		u;
+	ms_database = monitor_back_get_subsys( SLAPD_MONITOR_DATABASE_NAME );
+	if ( ms_database == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_back_register_database: "
+			"unable to get "
+			"\"" SLAPD_MONITOR_DATABASE_NAME "\" "
+			"subsystem\n",
+			0, 0, 0 );
+		return -1;
+	}
 
-				for ( u = 0; urls[ u ] != NULL; u++ ) {
-					struct berval	bv;
+	ms_overlay = monitor_back_get_subsys( SLAPD_MONITOR_OVERLAY_NAME );
+	if ( ms_overlay == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_back_register_database: "
+			"unable to get "
+			"\"" SLAPD_MONITOR_OVERLAY_NAME "\" "
+			"subsystem\n",
+			0, 0, 0 );
+		return -1;
+	}
 
-					ber_str2bv( urls[ u ], 0, 0, &bv );
+	if ( monitor_cache_get( mi, &ms_database->mss_ndn, &e_database ) ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_database_init: "
+			"unable to get entry \"%s\"\n",
+			ms_database->mss_ndn.bv_val, 0, 0 );
+		return( -1 );
+	}
 
-					attr_merge_normalize_one( e,
-						slap_schema.si_ad_labeledURI,
-						&bv, NULL );
+	mp = ( monitor_entry_t * )e_database->e_private;
+	for ( i = -1, ep = &mp->mp_children; *ep; i++ ) {
+		Attribute	*a;
+
+		a = attr_find( (*ep)->e_attrs, slap_schema.si_ad_namingContexts );
+		if ( a ) {
+			int		j, k;
+
+			for ( j = 0; !BER_BVISNULL( &a->a_nvals[ j ] ); j++ ) {
+				for ( k = 0; !BER_BVISNULL( &be->be_nsuffix[ k ] ); k++ ) {
+					if ( dn_match( &a->a_nvals[ j ], &be->be_nsuffix[ k ] ) ) {
+						rc = 0;
+						goto done;
+					}
 				}
-				ldap_charray_free( urls );
 			}
-#endif /* defined(SLAPD_META) */
 		}
 
-		j = -1;
-		LDAP_STAILQ_FOREACH( bi2, &backendInfo, bi_next ) {
-			j++;
-			if ( bi2->bi_type == bi->bi_type ) {
-				struct berval 		bv;
+		mp = ( monitor_entry_t * )(*ep)->e_private;
 
-				snprintf( buf, sizeof( buf ), 
-					"cn=Backend %d,%s", 
-					j, ms_backend->mss_dn.bv_val );
-				bv.bv_val = buf;
-				bv.bv_len = strlen( buf );
-				attr_merge_normalize_one( e,
-						slap_schema.si_ad_seeAlso,
-						&bv, NULL );
-				break;
-			}
-		}
-		/* we must find it! */
-		assert( j >= 0 );
+		assert( mp != NULL );
+		ep = &mp->mp_next;
+	}
 
-		mp = monitor_entrypriv_create();
-		if ( mp == NULL ) {
-			return -1;
-		}
-		e->e_private = ( void * )mp;
-		mp->mp_info = ms;
-		mp->mp_flags = ms->mss_flags
-			| MONITOR_F_SUB;
+	bv.bv_val = buf;
+	bv.bv_len = snprintf( buf, sizeof( buf ), "cn=Database %d", i );
+	if ( bv.bv_len >= sizeof( buf ) ) {
+		rc = -1;
+		goto done;
+	}
+	
+	rc = monitor_subsys_database_init_one( mi, be,
+		ms_database, ms_backend, ms_overlay, &bv, e_database, &ep );
+	if ( rc != 0 ) {
+		goto done;
+	}
+	/* database_init_one advanced ep past where we want.
+	 * But it stored the entry we want in mp->mp_next.
+	 */
+	ep = &mp->mp_next;
 
-		if ( monitor_cache_add( mi, e ) ) {
-			Debug( LDAP_DEBUG_ANY,
-				"monitor_subsys_database_init: "
-				"unable to add entry \"cn=Database %d,%s\"\n",
-				i, ms->mss_dn.bv_val, 0 );
-			return( -1 );
-		}
+done:;
+	monitor_cache_release( mi, e_database );
+	if ( rc == 0 && ndn && ep && *ep ) {
+		*ndn = (*ep)->e_nname;
+	}
 
-#if defined(LDAP_SLAPI)
-		monitor_back_add_plugin( mi, be, e );
-#endif /* defined(LDAP_SLAPI) */
+	return rc;
+}
 
-		if ( oi != NULL ) {
-			Entry		**ep_overlay = &mp->mp_children;
-			monitor_entry_t	*mp_overlay;
-			slap_overinst	*on = oi->oi_list;
-			int		o;
+int
+monitor_subsys_database_init(
+	BackendDB		*be,
+	monitor_subsys_t	*ms )
+{
+	monitor_info_t		*mi;
+	Entry			*e_database, **ep;
+	int			i, rc;
+	monitor_entry_t		*mp;
+	monitor_subsys_t	*ms_backend,
+				*ms_overlay;
+	struct berval		bv;
 
-			for ( o = 0; on; o++, on = on->on_next ) {
-				Entry			*e_overlay;
-				slap_overinst		*on2;
+	assert( be != NULL );
 
-				/* find the overlay number, j */
-				for ( on2 = overlay_next( NULL ), j = 0; on2; on2 = overlay_next( on2 ), j++ ) {
-					if ( on2->on_bi.bi_type == on->on_bi.bi_type ) {
-						break;
-					}
-				}
-				assert( on2 != NULL );
+	ms->mss_modify = monitor_subsys_database_modify;
 
-				snprintf( buf, sizeof( buf ),
-						"dn: cn=Overlay %d,cn=Database %d,%s\n"
-						"objectClass: %s\n"
-						"structuralObjectClass: %s\n"
-						"cn: Overlay %d\n"
-						"%s: %s\n"
-						"seeAlso: cn=Overlay %d,%s\n"
-						"creatorsName: %s\n"
-						"modifiersName: %s\n"
-						"createTimestamp: %s\n"
-						"modifyTimestamp: %s\n",
-						o,
-						i,
-						ms->mss_dn.bv_val,
-						mi->mi_oc_monitoredObject->soc_cname.bv_val,
-						mi->mi_oc_monitoredObject->soc_cname.bv_val,
-						o,
-						mi->mi_ad_monitoredInfo->ad_cname.bv_val,
-						on->on_bi.bi_type,
-						j,
-						ms_overlay->mss_dn.bv_val,
-						mi->mi_creatorsName.bv_val,
-						mi->mi_creatorsName.bv_val,
-						mi->mi_startTime.bv_val,
-						mi->mi_startTime.bv_val );
-				
-				e_overlay = str2entry( buf );
-				if ( e_overlay == NULL ) {
-					Debug( LDAP_DEBUG_ANY,
-						"monitor_subsys_database_init: "
-						"unable to create entry "
-						"\"cn=Overlay %d,cn=Database %d,%s\"\n",
-						o, i, ms->mss_dn.bv_val );
-					return( -1 );
-				}
+	mi = ( monitor_info_t * )be->be_private;
 
-				mp_overlay = monitor_entrypriv_create();
-				if ( mp_overlay == NULL ) {
-					return -1;
-				}
-				e_overlay->e_private = ( void * )mp_overlay;
-				mp_overlay->mp_info = ms;
-				mp_overlay->mp_flags = ms->mss_flags
-					| MONITOR_F_SUB;
-		
-				if ( monitor_cache_add( mi, e_overlay ) ) {
-					Debug( LDAP_DEBUG_ANY,
-						"monitor_subsys_database_init: "
-						"unable to add entry "
-						"\"cn=Overlay %d,cn=Database %d,%s\"\n",
-						o, i, ms->mss_dn.bv_val );
-					return( -1 );
-				}
+	ms_backend = monitor_back_get_subsys( SLAPD_MONITOR_BACKEND_NAME );
+	if ( ms_backend == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_database_init: "
+			"unable to get "
+			"\"" SLAPD_MONITOR_BACKEND_NAME "\" "
+			"subsystem\n",
+			0, 0, 0 );
+		return -1;
+	}
 
-				*ep_overlay = e_overlay;
-				ep_overlay = &mp_overlay->mp_next;
-			}
-		}
+	ms_overlay = monitor_back_get_subsys( SLAPD_MONITOR_OVERLAY_NAME );
+	if ( ms_overlay == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_database_init: "
+			"unable to get "
+			"\"" SLAPD_MONITOR_OVERLAY_NAME "\" "
+			"subsystem\n",
+			0, 0, 0 );
+		return -1;
+	}
 
-		*ep = e;
-		ep = &mp->mp_next;
+	if ( monitor_cache_get( mi, &ms->mss_ndn, &e_database ) ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_database_init: "
+			"unable to get entry \"%s\"\n",
+			ms->mss_ndn.bv_val, 0, 0 );
+		return( -1 );
 	}
+
+	(void)init_readOnly( mi, e_database, frontendDB->be_restrictops );
+	(void)init_restrictedOperation( mi, e_database, frontendDB->be_restrictops );
+
+	mp = ( monitor_entry_t * )e_database->e_private;
+	mp->mp_children = NULL;
+	ep = &mp->mp_children;
+
+	BER_BVSTR( &bv, "cn=Frontend" );
+	rc = monitor_subsys_database_init_one( mi, frontendDB,
+		ms, ms_backend, ms_overlay, &bv, e_database, &ep );
+	if ( rc != 0 ) {
+		return rc;
+	}
+
+	i = -1;
+	LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
+		char		buf[ BACKMONITOR_BUFSIZE ];
+
+		bv.bv_val = buf;
+		bv.bv_len = snprintf( buf, sizeof( buf ), "cn=Database %d", ++i );
+		if ( bv.bv_len >= sizeof( buf ) ) {
+			return -1;
+		}
+		
+		rc = monitor_subsys_database_init_one( mi, be,
+			ms, ms_backend, ms_overlay, &bv, e_database, &ep );
+		if ( rc != 0 ) {
+			return rc;
+		}
+	}
 	
 	monitor_cache_release( mi, e_database );
 
@@ -913,18 +926,22 @@
 		if ( rc != LDAP_SUCCESS ) {
 			goto done;
 		}
+		if ( srchdesc ) {
+			snprintf( buf, sizeof(buf),
+					"plugin %d name: %s; "
+					"vendor: %s; "
+					"version: %s; "
+					"description: %s", 
+					i,
+					srchdesc->spd_id,
+					srchdesc->spd_vendor,
+					srchdesc->spd_version,
+					srchdesc->spd_description );
+		} else {
+			snprintf( buf, sizeof(buf),
+					"plugin %d name: <no description available>", i );
+		}
 
-		snprintf( buf, sizeof(buf),
-				"plugin %d name: %s; "
-				"vendor: %s; "
-				"version: %s; "
-				"description: %s", 
-				i,
-				srchdesc->spd_id,
-				srchdesc->spd_vendor,
-				srchdesc->spd_version,
-				srchdesc->spd_description );
-
 		ber_str2bv( buf, 0, 0, &bv );
 		attr_merge_normalize_one( e_database,
 				mi->mi_ad_monitoredInfo, &bv, NULL );

Modified: openldap/trunk/servers/slapd/back-monitor/entry.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/entry.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/entry.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* entry.c - monitor backend entry handling routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/entry.c,v 1.14.2.7 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/entry.c,v 1.21.2.4 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -167,3 +167,55 @@
 
 	return mp;
 }
+
+Entry *
+monitor_entry_stub(
+	struct berval *pdn,
+	struct berval *pndn,
+	struct berval *rdn,
+	ObjectClass *oc,
+	monitor_info_t	*mi,
+	struct berval *create,
+	struct berval *modify
+)
+{
+	AttributeDescription *nad = NULL;
+	Entry *e;
+	struct berval nat;
+	char *ptr;
+	const char *text;
+	int rc;
+
+	nat = *rdn;
+	ptr = strchr( nat.bv_val, '=' );
+	nat.bv_len = ptr - nat.bv_val;
+	rc = slap_bv2ad( &nat, &nad, &text );
+	if ( rc )
+		return NULL;
+
+	e = entry_alloc();
+	if ( e ) {
+		struct berval nrdn;
+
+		rdnNormalize( 0, NULL, NULL, rdn, &nrdn, NULL );
+		build_new_dn( &e->e_name, pdn, rdn, NULL );
+		build_new_dn( &e->e_nname, pndn, &nrdn, NULL );
+		ber_memfree( nrdn.bv_val );
+		nat.bv_val = ptr + 1;
+		nat.bv_len = rdn->bv_len - ( nat.bv_val - rdn->bv_val );
+		attr_merge_normalize_one( e, slap_schema.si_ad_objectClass,
+			&oc->soc_cname, NULL );
+		attr_merge_normalize_one( e, slap_schema.si_ad_structuralObjectClass,
+			&oc->soc_cname, NULL );
+		attr_merge_normalize_one( e, nad, &nat, NULL );
+		attr_merge_one( e, slap_schema.si_ad_creatorsName, &mi->mi_creatorsName,
+			&mi->mi_ncreatorsName );
+		attr_merge_one( e, slap_schema.si_ad_modifiersName, &mi->mi_creatorsName,
+			&mi->mi_ncreatorsName );
+		attr_merge_normalize_one( e, slap_schema.si_ad_createTimestamp,
+			create ? create : &mi->mi_startTime, NULL );
+		attr_merge_normalize_one( e, slap_schema.si_ad_modifyTimestamp,
+			modify ? modify : &mi->mi_startTime, NULL );
+	}
+	return e;
+}

Modified: openldap/trunk/servers/slapd/back-monitor/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* init.c - initialize monitor backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/init.c,v 1.89.2.18 2007/01/25 12:42:38 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/init.c,v 1.125.2.4 2007/09/29 09:27:01 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -30,6 +30,8 @@
 #include "lber_pvt.h"
 #include "back-monitor.h"
 
+#include "config.h"
+
 #undef INTEGRATE_CORE_SCHEMA
 
 /*
@@ -44,7 +46,28 @@
 static struct monitor_subsys_t	**monitor_subsys;
 static int			monitor_subsys_opened;
 static monitor_info_t		monitor_info;
+static const monitor_extra_t monitor_extra = {
+	monitor_back_is_configured,
+	monitor_back_get_subsys,
+	monitor_back_get_subsys_by_dn,
 
+	monitor_back_register_subsys,
+	monitor_back_register_backend,
+	monitor_back_register_database,
+	monitor_back_register_overlay_info,
+	monitor_back_register_overlay,
+	monitor_back_register_entry,
+	monitor_back_register_entry_parent,
+	monitor_back_register_entry_attrs,
+	monitor_back_register_entry_callback,
+
+	monitor_back_unregister_entry,
+	monitor_back_unregister_entry_parent,
+	monitor_back_unregister_entry_attrs,
+	monitor_back_unregister_entry_callback
+};
+	
+
 /*
  * subsystem data
  *
@@ -203,6 +226,12 @@
 };
 
 int
+monitor_subsys_is_opened( void )
+{
+	return monitor_subsys_opened;
+}
+
+int
 monitor_back_register_subsys(
 	monitor_subsys_t	*ms )
 {
@@ -226,7 +255,7 @@
 	/* if a subsystem is registered __AFTER__ subsystem 
 	 * initialization (depending on the sequence the databases
 	 * are listed in slapd.conf), init it */
-	if ( monitor_subsys_opened ) {
+	if ( monitor_subsys_is_opened() ) {
 
 		/* FIXME: this should only be possible
 		 * if be_monitor is already initialized */
@@ -246,18 +275,29 @@
 	LIMBO_ENTRY,
 	LIMBO_ENTRY_PARENT,
 	LIMBO_ATTRS,
-	LIMBO_CB
+	LIMBO_CB,
+	LIMBO_BACKEND,
+	LIMBO_DATABASE,
+	LIMBO_OVERLAY_INFO,
+	LIMBO_OVERLAY,
+
+	LIMBO_LAST
 };
 
 typedef struct entry_limbo_t {
 	int			el_type;
+	BackendInfo		*el_bi;
+	BackendDB		*el_be;
+	slap_overinst		*el_on;
 	Entry			*el_e;
 	Attribute		*el_a;
-	struct berval		el_ndn;
-	struct berval		el_base;
+	struct berval		*el_ndn;
+	struct berval		el_nbase;
 	int			el_scope;
 	struct berval		el_filter;
 	monitor_callback_t	*el_cb;
+	monitor_subsys_t	*el_mss;
+	unsigned long		el_flags;
 	struct entry_limbo_t	*el_next;
 } entry_limbo_t;
 
@@ -268,9 +308,90 @@
 }
 
 int
+monitor_back_register_backend(
+	BackendInfo		*bi )
+{
+	return -1;
+}
+
+int
+monitor_back_register_overlay_info(
+	slap_overinst		*on )
+{
+	return -1;
+}
+
+int
+monitor_back_register_overlay(
+	BackendDB		*be )
+{
+	return -1;
+}
+
+int
+monitor_back_register_backend_limbo(
+	BackendInfo		*bi )
+{
+	return -1;
+}
+
+int
+monitor_back_register_database_limbo(
+	BackendDB		*be,
+	struct berval	*ndn )
+{
+	entry_limbo_t	**elpp, el = { 0 };
+	monitor_info_t 	*mi;
+
+	if ( be_monitor == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_back_register_database_limbo: "
+			"monitor database not configured.\n",
+			0, 0, 0 );
+		return -1;
+	}
+
+	mi = ( monitor_info_t * )be_monitor->be_private;
+
+
+	el.el_type = LIMBO_DATABASE;
+
+	el.el_be = be;
+	el.el_ndn = ndn;
+	
+	for ( elpp = &mi->mi_entry_limbo;
+			*elpp;
+			elpp = &(*elpp)->el_next )
+		/* go to last */;
+
+	*elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
+
+	el.el_next = NULL;
+	**elpp = el;
+
+	return 0;
+}
+
+int
+monitor_back_register_overlay_info_limbo(
+	slap_overinst		*on )
+{
+	return -1;
+}
+
+int
+monitor_back_register_overlay_limbo(
+	BackendDB		*be )
+{
+	return -1;
+}
+
+int
 monitor_back_register_entry(
 	Entry			*e,
-	monitor_callback_t	*cb )
+	monitor_callback_t	*cb,
+	monitor_subsys_t	*mss,
+	unsigned long		flags )
 {
 	monitor_info_t 	*mi;
 
@@ -288,7 +409,7 @@
 	assert( e != NULL );
 	assert( e->e_private == NULL );
 	
-	if ( monitor_subsys_opened ) {
+	if ( monitor_subsys_is_opened() ) {
 		Entry		*e_parent = NULL,
 				*e_new = NULL,
 				**ep = NULL;
@@ -351,8 +472,14 @@
 		}
 		
 		e_new->e_private = ( void * )mp;
-		mp->mp_info = mp_parent->mp_info;
-		mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB;
+		if ( mss != NULL ) {
+			mp->mp_info = mss;
+			mp->mp_flags = flags;
+
+		} else {
+			mp->mp_info = mp_parent->mp_info;
+			mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB;
+		}
 		mp->mp_cb = cb;
 
 		ep = &mp_parent->mp_children;
@@ -401,8 +528,10 @@
 		}
 		
 		el.el_cb = cb;
+		el.el_mss = mss;
+		el.el_flags = flags;
 
-		for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+		for ( elpp = &mi->mi_entry_limbo;
 				*elpp;
 				elpp = &(*elpp)->el_next )
 			/* go to last */;
@@ -425,7 +554,9 @@
 monitor_back_register_entry_parent(
 	Entry			*e,
 	monitor_callback_t	*cb,
-	struct berval		*base,
+	monitor_subsys_t	*mss,
+	unsigned long		flags,
+	struct berval		*nbase,
 	int			scope,
 	struct berval		*filter )
 {
@@ -436,8 +567,8 @@
 		Debug( LDAP_DEBUG_ANY,
 			"monitor_back_register_entry_parent(base=\"%s\" scope=%s filter=\"%s\"): "
 			"monitor database not configured.\n",
-			BER_BVISNULL( base ) ? "" : base->bv_val,
-			scope == LDAP_SCOPE_BASE ? "base" : ( scope == LDAP_SCOPE_ONELEVEL ? "one" : "subtree" ),
+			BER_BVISNULL( nbase ) ? "" : nbase->bv_val,
+			ldap_pvt_scope2str( scope ),
 			BER_BVISNULL( filter ) ? "" : filter->bv_val );
 		return -1;
 	}
@@ -457,7 +588,7 @@
 		return -1;
 	}
 
-	if ( monitor_subsys_opened ) {
+	if ( monitor_subsys_is_opened() ) {
 		Entry		*e_parent = NULL,
 				*e_new = NULL,
 				**ep = NULL;
@@ -467,14 +598,15 @@
 				*mp_parent = NULL;
 		int		rc = 0;
 
-		if ( monitor_filter2ndn( base, scope, filter, &ndn ) ) {
+		if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) {
 			/* entry does not exist */
 			Debug( LDAP_DEBUG_ANY,
 				"monitor_back_register_entry_parent(\"\"): "
-				"base=%s scope=%d filter=%s : "
+				"base=\"%s\" scope=%s filter=\"%s\": "
 				"unable to find entry\n",
-				base->bv_val ? base->bv_val : "\"\"",
-				scope, filter->bv_val );
+				nbase->bv_val ? nbase->bv_val : "\"\"",
+				ldap_pvt_scope2str( scope ),
+				filter->bv_val );
 			return -1;
 		}
 
@@ -511,6 +643,7 @@
 				"entry already exists\n",
 				e_name.bv_val, 0, 0 );
 			monitor_cache_release( mi, e_new );
+			e_new = NULL;
 			rc = -1;
 			goto done;
 		}
@@ -540,8 +673,14 @@
 		e_new->e_nname = e_nname;
 		
 		e_new->e_private = ( void * )mp;
-		mp->mp_info = mp_parent->mp_info;
-		mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB;
+		if ( mss != NULL ) {
+			mp->mp_info = mss;
+			mp->mp_flags = flags;
+
+		} else {
+			mp->mp_info = mp_parent->mp_info;
+			mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB;
+		}
 		mp->mp_cb = cb;
 
 		ep = &mp_parent->mp_children;
@@ -580,7 +719,7 @@
 		}
 
 	} else {
-		entry_limbo_t	**elpp, el = { 0 };
+		entry_limbo_t	**elpp = NULL, el = { 0 };
 
 		el.el_type = LIMBO_ENTRY_PARENT;
 
@@ -590,43 +729,64 @@
 				"monitor_back_register_entry(\"%s\"): "
 				"entry_dup() failed\n",
 				e->e_name.bv_val, 0, 0 );
-			return -1;
+			goto done_limbo;
 		}
 		
-		if ( !BER_BVISNULL( base ) ) {
-			ber_dupbv( &el.el_base, base );
+		if ( !BER_BVISNULL( nbase ) ) {
+			ber_dupbv( &el.el_nbase, nbase );
 		}
+
 		el.el_scope = scope;
 		if ( !BER_BVISNULL( filter ) ) {
-			ber_dupbv( &el.el_filter, filter );
+			ber_dupbv( &el.el_filter, filter  );
 		}
 
 		el.el_cb = cb;
+		el.el_mss = mss;
+		el.el_flags = flags;
 
-		for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+		for ( elpp = &mi->mi_entry_limbo;
 				*elpp;
 				elpp = &(*elpp)->el_next )
 			/* go to last */;
 
 		*elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
 		if ( *elpp == NULL ) {
-			el.el_e->e_private = NULL;
+			goto done_limbo;
+		}
+
+done_limbo:;
+		if ( *elpp != NULL ) {
+			el.el_next = NULL;
+			**elpp = el;
+
+		} else {
+			if ( !BER_BVISNULL( &el.el_filter ) ) {
+				ch_free( el.el_filter.bv_val );
+			}
+			if ( !BER_BVISNULL( &el.el_nbase ) ) {
+				ch_free( el.el_nbase.bv_val );
+			}
 			entry_free( el.el_e );
 			return -1;
 		}
-
-		el.el_next = NULL;
-		**elpp = el;
 	}
 
 	return 0;
 }
 
 static int
-monitor_filter2ndn_cb( Operation *op, SlapReply *rs )
+monitor_search2ndn_cb( Operation *op, SlapReply *rs )
 {
 	if ( rs->sr_type == REP_SEARCH ) {
 		struct berval	*ndn = op->o_callback->sc_private;
+
+		if ( !BER_BVISNULL( ndn ) ) {
+			rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
+			ch_free( ndn->bv_val );
+			BER_BVZERO( ndn );
+			return rs->sr_err;
+		}
 		
 		ber_dupbv( ndn, &rs->sr_entry->e_nname );
 	}
@@ -635,8 +795,8 @@
 }
 
 int
-monitor_filter2ndn(
-	struct berval	*base,
+monitor_search2ndn(
+	struct berval	*nbase,
 	int		scope,
 	struct berval	*filter,
 	struct berval	*ndn )
@@ -646,7 +806,7 @@
 	Operation	*op;
 	void	*thrctx;
 	SlapReply	rs = { 0 };
-	slap_callback	cb = { NULL, monitor_filter2ndn_cb, NULL, NULL };
+	slap_callback	cb = { NULL, monitor_search2ndn_cb, NULL, NULL };
 	int		rc;
 
 	BER_BVZERO( ndn );
@@ -655,21 +815,27 @@
 		return -1;
 	}
 
-	op = (Operation *) &opbuf;
 	thrctx = ldap_pvt_thread_pool_context();
-	connection_fake_init( &conn, op, thrctx );
+	connection_fake_init( &conn, &opbuf, thrctx );
+	op = &opbuf.ob_op;
 
 	op->o_tag = LDAP_REQ_SEARCH;
 
+	/* use global malloc for now */
+	if ( op->o_tmpmemctx ) {
+		op->o_tmpmemctx = NULL;
+	}
+	op->o_tmpmfuncs = &ch_mfuncs;
+
 	op->o_bd = be_monitor;
-	if ( base == NULL || BER_BVISNULL( base ) ) {
+	if ( nbase == NULL || BER_BVISNULL( nbase ) ) {
 		ber_dupbv_x( &op->o_req_dn, &op->o_bd->be_suffix[ 0 ],
 				op->o_tmpmemctx );
 		ber_dupbv_x( &op->o_req_ndn, &op->o_bd->be_nsuffix[ 0 ],
 				op->o_tmpmemctx );
 
 	} else {
-		if ( dnPrettyNormal( NULL, base, &op->o_req_dn, &op->o_req_ndn,
+		if ( dnPrettyNormal( NULL, nbase, &op->o_req_dn, &op->o_req_ndn,
 					op->o_tmpmemctx ) ) {
 			return -1;
 		}
@@ -679,8 +845,12 @@
 	cb.sc_private = (void *)ndn;
 
 	op->ors_scope = scope;
+	op->ors_filter = str2filter_x( op, filter->bv_val );
+	if ( op->ors_filter == NULL ) {
+		rc = LDAP_OTHER;
+		goto cleanup;
+	}
 	ber_dupbv_x( &op->ors_filterstr, filter, op->o_tmpmemctx );
-	op->ors_filter = str2filter_x( op, filter->bv_val );
 	op->ors_attrs = slap_anlist_no_attrs;
 	op->ors_attrsonly = 0;
 	op->ors_tlimit = SLAP_NO_LIMIT;
@@ -696,10 +866,19 @@
 
 	rc = op->o_bd->be_search( op, &rs );
 
-	filter_free_x( op, op->ors_filter );
-	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
-	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
-	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+cleanup:;
+	if ( op->ors_filter != NULL ) {
+		filter_free_x( op, op->ors_filter );
+	}
+	if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
+		op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
+	}
+	if ( !BER_BVISNULL( &op->o_req_dn ) ) {
+		op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	}
+	if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
+		op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+	}
 
 	if ( rc != 0 ) {
 		return rc;
@@ -730,7 +909,7 @@
 	struct berval		*ndn_in,
 	Attribute		*a,
 	monitor_callback_t	*cb,
-	struct berval		*base,
+	struct berval		*nbase,
 	int			scope,
 	struct berval		*filter )
 {
@@ -745,8 +924,8 @@
 			"monitor_back_register_entry_%s(base=\"%s\" scope=%s filter=\"%s\"): "
 			"monitor database not configured.\n",
 			fname,
-			BER_BVISNULL( base ) ? "" : base->bv_val,
-			scope == LDAP_SCOPE_BASE ? "base" : ( scope == LDAP_SCOPE_ONELEVEL ? "one" : "subtree" ),
+			BER_BVISNULL( nbase ) ? "" : nbase->bv_val,
+			ldap_pvt_scope2str( scope ),
 			BER_BVISNULL( filter ) ? "" : filter->bv_val );
 		Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
 
@@ -777,7 +956,7 @@
 		return -1;
 	}
 
-	if ( monitor_subsys_opened ) {
+	if ( monitor_subsys_is_opened() ) {
 		Entry			*e = NULL;
 		Attribute		**atp = NULL;
 		monitor_entry_t 	*mp = NULL;
@@ -786,16 +965,17 @@
 		int			freeit = 0;
 
 		if ( BER_BVISNULL( &ndn ) ) {
-			if ( monitor_filter2ndn( base, scope, filter, &ndn ) ) {
+			if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) {
 				char		buf[ SLAP_TEXT_BUFLEN ];
 
 				snprintf( buf, sizeof( buf ),
 					"monitor_back_register_entry_%s(\"\"): "
-					"base=%s scope=%d filter=%s : "
+					"base=\"%s\" scope=%s filter=\"%s\": "
 					"unable to find entry\n",
 					fname,
-					base->bv_val ? base->bv_val : "\"\"",
-					scope, filter->bv_val );
+					nbase->bv_val ? nbase->bv_val : "\"\"",
+					ldap_pvt_scope2str( scope ),
+					filter->bv_val );
 
 				/* entry does not exist */
 				Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
@@ -832,14 +1012,26 @@
 			for ( atp = &e->e_attrs; *atp; atp = &(*atp)->a_next )
 				/* just get to last */ ;
 
-			*atp = attrs_dup( a );
-			if ( *atp == NULL ) {
-				Debug( LDAP_DEBUG_ANY,
-					"monitor_back_register_entry_%s(\"%s\"): "
-					"attrs_dup() failed\n",
-					fname, e->e_name.bv_val, 0 );
-				rc = -1;
-				goto done;
+			for ( ; a != NULL; a = a->a_next ) {
+				assert( a->a_desc != NULL );
+				assert( a->a_vals != NULL );
+
+				if ( attr_find( e->e_attrs, a->a_desc ) ) {
+					attr_merge( e, a->a_desc, a->a_vals,
+						a->a_nvals == a->a_vals ? NULL : a->a_nvals );
+
+				} else {
+					*atp = attr_dup( a );
+					if ( *atp == NULL ) {
+						Debug( LDAP_DEBUG_ANY,
+							"monitor_back_register_entry_%s(\"%s\"): "
+							"attr_dup() failed\n",
+							fname, e->e_name.bv_val, 0 );
+						rc = -1;
+						goto done;
+					}
+					atp = &(*atp)->a_next;
+				}
 			}
 		}
 
@@ -854,7 +1046,7 @@
 
 done:;
 		if ( rc ) {
-			if ( *atp ) {
+			if ( atp && *atp ) {
 				attrs_free( *atp );
 				*atp = NULL;
 			}
@@ -872,21 +1064,19 @@
 		entry_limbo_t	**elpp, el = { 0 };
 
 		el.el_type = LIMBO_ATTRS;
-		if ( !BER_BVISNULL( &ndn ) ) {
-			ber_dupbv( &el.el_ndn, &ndn );
+		el.el_ndn = ndn_in;
+		if ( !BER_BVISNULL( nbase ) ) {
+			ber_dupbv( &el.el_nbase, nbase);
 		}
-		if ( !BER_BVISNULL( base ) ) {
-			ber_dupbv( &el.el_base, base);
-		}
 		el.el_scope = scope;
 		if ( !BER_BVISNULL( filter ) ) {
-			ber_dupbv( &el.el_filter, filter );
+			ber_dupbv( &el.el_filter, filter  );
 		}
 
 		el.el_a = attrs_dup( a );
 		el.el_cb = cb;
 
-		for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+		for ( elpp = &mi->mi_entry_limbo;
 				*elpp;
 				elpp = &(*elpp)->el_next )
 			/* go to last */;
@@ -898,8 +1088,22 @@
 			return -1;
 		}
 
-		el.el_next = NULL;
-		**elpp = el;
+		if ( *elpp != NULL ) {
+			el.el_next = NULL;
+			**elpp = el;
+
+		} else {
+			if ( !BER_BVISNULL( &el.el_filter ) ) {
+				ch_free( el.el_filter.bv_val );
+			}
+			if ( el.el_a != NULL ) {
+				attrs_free( el.el_a );
+			}
+			if ( !BER_BVISNULL( &el.el_nbase ) ) {
+				ch_free( &el.el_nbase.bv_val );
+			}
+			return -1;
+		}
 	}
 
 	return 0;
@@ -909,14 +1113,459 @@
 monitor_back_register_entry_callback(
 	struct berval		*ndn,
 	monitor_callback_t	*cb,
-	struct berval		*base,
+	struct berval		*nbase,
 	int			scope,
 	struct berval		*filter )
 {
 	return monitor_back_register_entry_attrs( ndn, NULL, cb,
-			base, scope, filter );
+			nbase, scope, filter );
 }
 
+/*
+ * TODO: add corresponding calls to remove installed callbacks, entries
+ * and so, in case the entity that installed them is removed (e.g. a 
+ * database, via back-config)
+ */
+int
+monitor_back_unregister_entry(
+	struct berval	*ndn )
+{
+	monitor_info_t 	*mi;
+
+	if ( be_monitor == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_back_unregister_entry(\"%s\"): "
+			"monitor database not configured.\n",
+			ndn->bv_val, 0, 0 );
+
+		return -1;
+	}
+
+	/* entry will be regularly freed, and resources released
+	 * according to callbacks */
+	if ( slapd_shutdown ) {
+		return 0;
+	}
+
+	mi = ( monitor_info_t * )be_monitor->be_private;
+
+	assert( mi != NULL );
+
+	if ( monitor_subsys_is_opened() ) {
+		Entry			*e = NULL;
+		monitor_entry_t 	*mp = NULL;
+		monitor_callback_t	*cb = NULL;
+
+		if ( monitor_cache_remove( mi, ndn, &e ) != 0 ) {
+			/* entry does not exist */
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_unregister_entry(\"%s\"): "
+				"entry removal failed.\n",
+				ndn->bv_val, 0, 0 );
+			return -1;
+		}
+
+		mp = (monitor_entry_t *)e->e_private;
+		assert( mp != NULL );
+
+		for ( cb = mp->mp_cb; cb != NULL; ) {
+			monitor_callback_t	*next = cb->mc_next;
+
+			if ( cb->mc_free ) {
+				(void)cb->mc_free( e, &cb->mc_private );
+			}
+			ch_free( cb );
+
+			cb = next;
+		}
+
+		ch_free( mp );
+		e->e_private = NULL;
+		entry_free( e );
+
+	} else {
+		entry_limbo_t	**elpp;
+
+		for ( elpp = &mi->mi_entry_limbo;
+			*elpp;
+			elpp = &(*elpp)->el_next )
+		{
+			entry_limbo_t	*elp = *elpp;
+
+			if ( elp->el_type == LIMBO_ENTRY
+				&& dn_match( ndn, &elp->el_e->e_nname ) )
+			{
+				monitor_callback_t	*cb, *next;
+
+				for ( cb = elp->el_cb; cb; cb = next ) {
+					/* FIXME: call callbacks? */
+					next = cb->mc_next;
+					if ( cb->mc_dispose ) {
+						cb->mc_dispose( &cb->mc_private );
+					}
+					ch_free( cb );
+				}
+				assert( elp->el_e != NULL );
+				elp->el_e->e_private = NULL;
+				entry_free( elp->el_e );
+				*elpp = elp->el_next;
+				ch_free( elp );
+				elpp = NULL;
+				break;
+			}
+		}
+
+		if ( elpp != NULL ) {
+			/* not found!  where did it go? */
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+int
+monitor_back_unregister_entry_parent(
+	struct berval		*nrdn,
+	monitor_callback_t	*target_cb,
+	struct berval		*nbase,
+	int			scope,
+	struct berval		*filter )
+{
+	monitor_info_t 	*mi;
+	struct berval	ndn = BER_BVNULL;
+
+	if ( be_monitor == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_back_unregister_entry_parent(base=\"%s\" scope=%s filter=\"%s\"): "
+			"monitor database not configured.\n",
+			BER_BVISNULL( nbase ) ? "" : nbase->bv_val,
+			ldap_pvt_scope2str( scope ),
+			BER_BVISNULL( filter ) ? "" : filter->bv_val );
+
+		return -1;
+	}
+
+	/* entry will be regularly freed, and resources released
+	 * according to callbacks */
+	if ( slapd_shutdown ) {
+		return 0;
+	}
+
+	mi = ( monitor_info_t * )be_monitor->be_private;
+
+	assert( mi != NULL );
+
+	if ( ( nrdn == NULL || BER_BVISNULL( nrdn ) )
+			&& BER_BVISNULL( filter ) )
+	{
+		/* need a filter */
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_back_unregister_entry_parent(\"\"): "
+			"need a valid filter\n",
+			0, 0, 0 );
+		return -1;
+	}
+
+	if ( monitor_subsys_is_opened() ) {
+		Entry			*e = NULL;
+		monitor_entry_t 	*mp = NULL;
+
+		if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) {
+			/* entry does not exist */
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_unregister_entry_parent(\"\"): "
+				"base=\"%s\" scope=%s filter=\"%s\": "
+				"unable to find entry\n",
+				nbase->bv_val ? nbase->bv_val : "\"\"",
+				ldap_pvt_scope2str( scope ),
+				filter->bv_val );
+			return -1;
+		}
+
+		if ( monitor_cache_remove( mi, &ndn, &e ) != 0 ) {
+			/* entry does not exist */
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_unregister_entry(\"%s\"): "
+				"entry removal failed.\n",
+				ndn.bv_val, 0, 0 );
+			ber_memfree( ndn.bv_val );
+			return -1;
+		}
+		ber_memfree( ndn.bv_val );
+
+		mp = (monitor_entry_t *)e->e_private;
+		assert( mp != NULL );
+
+		if ( target_cb != NULL ) {
+			monitor_callback_t	**cbp;
+
+			for ( cbp = &mp->mp_cb; *cbp != NULL; cbp = &(*cbp)->mc_next ) {
+				if ( *cbp == target_cb ) {
+					if ( (*cbp)->mc_free ) {
+						(void)(*cbp)->mc_free( e, &(*cbp)->mc_private );
+					}
+					*cbp = (*cbp)->mc_next;
+					ch_free( target_cb );
+					break;
+				}
+			}
+		}
+
+
+		ch_free( mp );
+		e->e_private = NULL;
+		entry_free( e );
+
+	} else {
+		entry_limbo_t	**elpp;
+
+		for ( elpp = &mi->mi_entry_limbo;
+			*elpp;
+			elpp = &(*elpp)->el_next )
+		{
+			entry_limbo_t	*elp = *elpp;
+
+			if ( elp->el_type == LIMBO_ENTRY_PARENT
+				&& dn_match( nrdn, &elp->el_e->e_nname )
+				&& dn_match( nbase, &elp->el_nbase )
+				&& scope == elp->el_scope
+				&& bvmatch( filter, &elp->el_filter ) )
+			{
+				monitor_callback_t	*cb, *next;
+
+				for ( cb = elp->el_cb; cb; cb = next ) {
+					/* FIXME: call callbacks? */
+					next = cb->mc_next;
+					if ( cb->mc_dispose ) {
+						cb->mc_dispose( &cb->mc_private );
+					}
+					ch_free( cb );
+				}
+				assert( elp->el_e != NULL );
+				elp->el_e->e_private = NULL;
+				entry_free( elp->el_e );
+				if ( !BER_BVISNULL( &elp->el_nbase ) ) {
+					ch_free( elp->el_nbase.bv_val );
+				}
+				if ( !BER_BVISNULL( &elp->el_filter ) ) {
+					ch_free( elp->el_filter.bv_val );
+				}
+				*elpp = elp->el_next;
+				ch_free( elp );
+				elpp = NULL;
+				break;
+			}
+		}
+
+		if ( elpp != NULL ) {
+			/* not found!  where did it go? */
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+int
+monitor_back_unregister_entry_attrs(
+	struct berval		*ndn_in,
+	Attribute		*target_a,
+	monitor_callback_t	*target_cb,
+	struct berval		*nbase,
+	int			scope,
+	struct berval		*filter )
+{
+	monitor_info_t 	*mi;
+	struct berval	ndn = BER_BVNULL;
+	char		*fname = ( target_a == NULL ? "callback" : "attrs" );
+
+	if ( be_monitor == NULL ) {
+		char		buf[ SLAP_TEXT_BUFLEN ];
+
+		snprintf( buf, sizeof( buf ),
+			"monitor_back_unregister_entry_%s(base=\"%s\" scope=%s filter=\"%s\"): "
+			"monitor database not configured.\n",
+			fname,
+			BER_BVISNULL( nbase ) ? "" : nbase->bv_val,
+			ldap_pvt_scope2str( scope ),
+			BER_BVISNULL( filter ) ? "" : filter->bv_val );
+		Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
+
+		return -1;
+	}
+
+	/* entry will be regularly freed, and resources released
+	 * according to callbacks */
+	if ( slapd_shutdown ) {
+		return 0;
+	}
+
+	mi = ( monitor_info_t * )be_monitor->be_private;
+
+	assert( mi != NULL );
+
+	if ( ndn_in != NULL ) {
+		ndn = *ndn_in;
+	}
+
+	if ( target_a == NULL && target_cb == NULL ) {
+		/* nothing to do */
+		return -1;
+	}
+
+	if ( ( ndn_in == NULL || BER_BVISNULL( &ndn ) )
+			&& BER_BVISNULL( filter ) )
+	{
+		/* need a filter */
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_back_unregister_entry_%s(\"\"): "
+			"need a valid filter\n",
+			fname, 0, 0 );
+		return -1;
+	}
+
+	if ( monitor_subsys_is_opened() ) {
+		Entry			*e = NULL;
+		monitor_entry_t 	*mp = NULL;
+		int			freeit = 0;
+
+		if ( BER_BVISNULL( &ndn ) ) {
+			if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) {
+				char		buf[ SLAP_TEXT_BUFLEN ];
+
+				snprintf( buf, sizeof( buf ),
+					"monitor_back_unregister_entry_%s(\"\"): "
+					"base=\"%s\" scope=%d filter=\"%s\": "
+					"unable to find entry\n",
+					fname,
+					nbase->bv_val ? nbase->bv_val : "\"\"",
+					scope, filter->bv_val );
+
+				/* entry does not exist */
+				Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
+				return -1;
+			}
+
+			freeit = 1;
+		}
+
+		if ( monitor_cache_get( mi, &ndn, &e ) != 0 ) {
+			/* entry does not exist */
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_unregister_entry(\"%s\"): "
+				"entry removal failed.\n",
+				ndn.bv_val, 0, 0 );
+			return -1;
+		}
+
+		mp = (monitor_entry_t *)e->e_private;
+		assert( mp != NULL );
+
+		if ( target_cb != NULL ) {
+			monitor_callback_t	**cbp;
+
+			for ( cbp = &mp->mp_cb; *cbp != NULL; cbp = &(*cbp)->mc_next ) {
+				if ( *cbp == target_cb ) {
+					if ( (*cbp)->mc_free ) {
+						(void)(*cbp)->mc_free( e, &(*cbp)->mc_private );
+					}
+					*cbp = (*cbp)->mc_next;
+					ch_free( target_cb );
+					break;
+				}
+			}
+		}
+
+		if ( target_a != NULL ) {
+			Attribute	*a;
+
+			for ( a = target_a; a != NULL; a = a->a_next ) {
+				Modification	mod = { 0 };
+				const char	*text;
+				char		textbuf[ SLAP_TEXT_BUFLEN ];
+
+				mod.sm_op = LDAP_MOD_DELETE;
+				mod.sm_desc = a->a_desc;
+				mod.sm_values = a->a_vals;
+				mod.sm_nvalues = a->a_nvals;
+
+				(void)modify_delete_values( e, &mod, 1,
+					&text, textbuf, sizeof( textbuf ) );
+			}
+		}
+
+		if ( freeit ) {
+			ber_memfree( ndn.bv_val );
+		}
+
+		monitor_cache_release( mi, e );
+
+	} else {
+		entry_limbo_t	**elpp;
+
+		for ( elpp = &mi->mi_entry_limbo;
+			*elpp;
+			elpp = &(*elpp)->el_next )
+		{
+			entry_limbo_t	*elp = *elpp;
+
+			if ( elp->el_type == LIMBO_ATTRS
+				&& dn_match( nbase, &elp->el_nbase )
+				&& scope == elp->el_scope
+				&& bvmatch( filter, &elp->el_filter ) )
+			{
+				monitor_callback_t	*cb, *next;
+
+				for ( cb = elp->el_cb; cb; cb = next ) {
+					/* FIXME: call callbacks? */
+					next = cb->mc_next;
+					if ( cb->mc_dispose ) {
+						cb->mc_dispose( &cb->mc_private );
+					}
+					ch_free( cb );
+				}
+				assert( elp->el_e == NULL );
+				if ( elp->el_a != NULL ) {
+					attrs_free( elp->el_a );
+				}
+				if ( !BER_BVISNULL( &elp->el_nbase ) ) {
+					ch_free( elp->el_nbase.bv_val );
+				}
+				if ( !BER_BVISNULL( &elp->el_filter ) ) {
+					ch_free( elp->el_filter.bv_val );
+				}
+				*elpp = elp->el_next;
+				ch_free( elp );
+				elpp = NULL;
+				break;
+			}
+		}
+
+		if ( elpp != NULL ) {
+			/* not found!  where did it go? */
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+int
+monitor_back_unregister_entry_callback(
+	struct berval		*ndn,
+	monitor_callback_t	*cb,
+	struct berval		*nbase,
+	int			scope,
+	struct berval		*filter )
+{
+	/* TODO: lookup entry (by ndn, if not NULL, and/or by callback);
+	 * unregister the callback; if a is not null, unregister the
+	 * given attrs.  In any case, call cb->cb_free */
+	return monitor_back_unregister_entry_attrs( ndn,
+		NULL, cb, nbase, scope, filter );
+}
+
 monitor_subsys_t *
 monitor_back_get_subsys( const char *name )
 {
@@ -985,12 +1634,11 @@
 	};
 
 	struct m_s {
-		char	*name;
 		char	*schema;
 		slap_mask_t flags;
 		int	offset;
 	} moc[] = {
-		{ "monitor", "( 1.3.6.1.4.1.4203.666.3.16.1 "
+		{ "( 1.3.6.1.4.1.4203.666.3.16.1 "
 			"NAME 'monitor' "
 			"DESC 'OpenLDAP system monitoring' "
 			"SUP top STRUCTURAL "
@@ -1004,44 +1652,44 @@
 				"$ monitorOverlay "
 			") )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 			offsetof(monitor_info_t, mi_oc_monitor) },
-		{ "monitorServer", "( 1.3.6.1.4.1.4203.666.3.16.2 "
+		{ "( 1.3.6.1.4.1.4203.666.3.16.2 "
 			"NAME 'monitorServer' "
 			"DESC 'Server monitoring root entry' "
 			"SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 			offsetof(monitor_info_t, mi_oc_monitorServer) },
-		{ "monitorContainer", "( 1.3.6.1.4.1.4203.666.3.16.3 "
+		{ "( 1.3.6.1.4.1.4203.666.3.16.3 "
 			"NAME 'monitorContainer' "
 			"DESC 'monitor container class' "
 			"SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 			offsetof(monitor_info_t, mi_oc_monitorContainer) },
-		{ "monitorCounterObject", "( 1.3.6.1.4.1.4203.666.3.16.4 "
+		{ "( 1.3.6.1.4.1.4203.666.3.16.4 "
 			"NAME 'monitorCounterObject' "
 			"DESC 'monitor counter class' "
 			"SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 			offsetof(monitor_info_t, mi_oc_monitorCounterObject) },
-		{ "monitorOperation", "( 1.3.6.1.4.1.4203.666.3.16.5 "
+		{ "( 1.3.6.1.4.1.4203.666.3.16.5 "
 			"NAME 'monitorOperation' "
 			"DESC 'monitor operation class' "
 			"SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 			offsetof(monitor_info_t, mi_oc_monitorOperation) },
-		{ "monitorConnection", "( 1.3.6.1.4.1.4203.666.3.16.6 "
+		{ "( 1.3.6.1.4.1.4203.666.3.16.6 "
 			"NAME 'monitorConnection' "
 			"DESC 'monitor connection class' "
 			"SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 			offsetof(monitor_info_t, mi_oc_monitorConnection) },
-		{ "managedObject", "( 1.3.6.1.4.1.4203.666.3.16.7 "
+		{ "( 1.3.6.1.4.1.4203.666.3.16.7 "
 			"NAME 'managedObject' "
 			"DESC 'monitor managed entity class' "
 			"SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 			offsetof(monitor_info_t, mi_oc_managedObject) },
-		{ "monitoredObject", "( 1.3.6.1.4.1.4203.666.3.16.8 "
+		{ "( 1.3.6.1.4.1.4203.666.3.16.8 "
 			"NAME 'monitoredObject' "
 			"DESC 'monitor monitored entity class' "
 			"SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
 			offsetof(monitor_info_t, mi_oc_monitoredObject) },
-		{ NULL, NULL, 0, -1 }
+		{ NULL, 0, -1 }
 	}, mat[] = {
-		{ "monitoredInfo", "( 1.3.6.1.4.1.4203.666.1.55.1 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.1 "
 			"NAME 'monitoredInfo' "
 			"DESC 'monitored info' "
 			/* "SUP name " */
@@ -1049,67 +1697,67 @@
 			"SUBSTR caseIgnoreSubstringsMatch "
 			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitoredInfo) },
-		{ "managedInfo", "( 1.3.6.1.4.1.4203.666.1.55.2 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.2 "
 			"NAME 'managedInfo' "
 			"DESC 'monitor managed info' "
 			"SUP name )", SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_managedInfo) },
-		{ "monitorCounter", "( 1.3.6.1.4.1.4203.666.1.55.3 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.3 "
 			"NAME 'monitorCounter' "
 			"DESC 'monitor counter' "
 			"EQUALITY integerMatch "
 			"ORDERING integerOrderingMatch "
 			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorCounter) },
-		{ "monitorOpCompleted", "( 1.3.6.1.4.1.4203.666.1.55.4 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.4 "
 			"NAME 'monitorOpCompleted' "
 			"DESC 'monitor completed operations' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorOpCompleted) },
-		{ "monitorOpInitiated", "( 1.3.6.1.4.1.4203.666.1.55.5 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.5 "
 			"NAME 'monitorOpInitiated' "
 			"DESC 'monitor initiated operations' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorOpInitiated) },
-		{ "monitorConnectionNumber", "( 1.3.6.1.4.1.4203.666.1.55.6 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.6 "
 			"NAME 'monitorConnectionNumber' "
 			"DESC 'monitor connection number' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionNumber) },
-		{ "monitorConnectionAuthzDN", "( 1.3.6.1.4.1.4203.666.1.55.7 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.7 "
 			"NAME 'monitorConnectionAuthzDN' "
 			"DESC 'monitor connection authorization DN' "
 			/* "SUP distinguishedName " */
 			"EQUALITY distinguishedNameMatch "
 			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionAuthzDN) },
-		{ "monitorConnectionLocalAddress", "( 1.3.6.1.4.1.4203.666.1.55.8 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.8 "
 			"NAME 'monitorConnectionLocalAddress' "
 			"DESC 'monitor connection local address' "
 			"SUP monitoredInfo "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionLocalAddress) },
-		{ "monitorConnectionPeerAddress", "( 1.3.6.1.4.1.4203.666.1.55.9 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.9 "
 			"NAME 'monitorConnectionPeerAddress' "
 			"DESC 'monitor connection peer address' "
 			"SUP monitoredInfo "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionPeerAddress) },
-		{ "monitorTimestamp", "( 1.3.6.1.4.1.4203.666.1.55.10 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.10 "
 			"NAME 'monitorTimestamp' "
 			"DESC 'monitor timestamp' "
 			"EQUALITY generalizedTimeMatch "
@@ -1117,238 +1765,228 @@
 			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
 			"SINGLE-VALUE "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorTimestamp) },
-		{ "monitorOverlay", "( 1.3.6.1.4.1.4203.666.1.55.11 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.11 "
 			"NAME 'monitorOverlay' "
 			"DESC 'name of overlays defined for a given database' "
 			"SUP monitoredInfo "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorOverlay) },
-		{ "readOnly", "( 1.3.6.1.4.1.4203.666.1.55.12 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.12 "
 			"NAME 'readOnly' "
 			"DESC 'read/write status of a given database' "
 			"EQUALITY booleanMatch "
 			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
 			"SINGLE-VALUE "
-			"USAGE directoryOperation )", SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_readOnly) },
-		{ "restrictedOperation", "( 1.3.6.1.4.1.4203.666.1.55.13 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.13 "
 			"NAME 'restrictedOperation' "
 			"DESC 'name of restricted operation for a given database' "
 			"SUP managedInfo )", SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_restrictedOperation ) },
-		{ "monitorConnectionProtocol", "( 1.3.6.1.4.1.4203.666.1.55.14 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.14 "
 			"NAME 'monitorConnectionProtocol' "
 			"DESC 'monitor connection protocol' "
 			"SUP monitoredInfo "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionProtocol) },
-		{ "monitorConnectionOpsReceived", "( 1.3.6.1.4.1.4203.666.1.55.15 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.15 "
 			"NAME 'monitorConnectionOpsReceived' "
 			"DESC 'monitor number of operations received by the connection' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionOpsReceived) },
-		{ "monitorConnectionOpsExecuting", "( 1.3.6.1.4.1.4203.666.1.55.16 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.16 "
 			"NAME 'monitorConnectionOpsExecuting' "
 			"DESC 'monitor number of operations in execution within the connection' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionOpsExecuting) },
-		{ "monitorConnectionOpsPending", "( 1.3.6.1.4.1.4203.666.1.55.17 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.17 "
 			"NAME 'monitorConnectionOpsPending' "
 			"DESC 'monitor number of pending operations within the connection' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionOpsPending) },
-		{ "monitorConnectionOpsCompleted", "( 1.3.6.1.4.1.4203.666.1.55.18 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.18 "
 			"NAME 'monitorConnectionOpsCompleted' "
 			"DESC 'monitor number of operations completed within the connection' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionOpsCompleted) },
-		{ "monitorConnectionGet", "( 1.3.6.1.4.1.4203.666.1.55.19 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.19 "
 			"NAME 'monitorConnectionGet' "
 			"DESC 'number of times connection_get() was called so far' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionGet) },
-		{ "monitorConnectionRead", "( 1.3.6.1.4.1.4203.666.1.55.20 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.20 "
 			"NAME 'monitorConnectionRead' "
 			"DESC 'number of times connection_read() was called so far' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionRead) },
-		{ "monitorConnectionWrite", "( 1.3.6.1.4.1.4203.666.1.55.21 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.21 "
 			"NAME 'monitorConnectionWrite' "
 			"DESC 'number of times connection_write() was called so far' "
 			"SUP monitorCounter "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionWrite) },
-		{ "monitorConnectionMask", "( 1.3.6.1.4.1.4203.666.1.55.22 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.22 "
 			"NAME 'monitorConnectionMask' "
 			"DESC 'monitor connection mask' "
 			"SUP monitoredInfo "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionMask) },
-		{ "monitorConnectionListener", "( 1.3.6.1.4.1.4203.666.1.55.23 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.23 "
 			"NAME 'monitorConnectionListener' "
 			"DESC 'monitor connection listener' "
 			"SUP monitoredInfo "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionListener) },
-		{ "monitorConnectionPeerDomain", "( 1.3.6.1.4.1.4203.666.1.55.24 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.24 "
 			"NAME 'monitorConnectionPeerDomain' "
 			"DESC 'monitor connection peer domain' "
 			"SUP monitoredInfo "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionPeerDomain) },
-		{ "monitorConnectionStartTime", "( 1.3.6.1.4.1.4203.666.1.55.25 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.25 "
 			"NAME 'monitorConnectionStartTime' "
 			"DESC 'monitor connection start time' "
 			"SUP monitorTimestamp "
 			"SINGLE-VALUE "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionStartTime) },
-		{ "monitorConnectionActivityTime", "( 1.3.6.1.4.1.4203.666.1.55.26 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.26 "
 			"NAME 'monitorConnectionActivityTime' "
 			"DESC 'monitor connection activity time' "
 			"SUP monitorTimestamp "
 			"SINGLE-VALUE "
 			"NO-USER-MODIFICATION "
-			"USAGE directoryOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorConnectionActivityTime) },
-		{ "monitorIsShadow", "( 1.3.6.1.4.1.4203.666.1.55.27 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.27 "
 			"NAME 'monitorIsShadow' "
 			"DESC 'TRUE if the database is shadow' "
 			"EQUALITY booleanMatch "
 			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
 			"SINGLE-VALUE "
-			"USAGE directoryOperation )", SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorIsShadow) },
-		{ "monitorUpdateRef", "( 1.3.6.1.4.1.4203.666.1.55.28 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.28 "
 			"NAME 'monitorUpdateRef' "
 			"DESC 'update referral for shadow databases' "
 			"SUP monitoredInfo "
 			"SINGLE-VALUE "
-			"USAGE directoryOperation )", SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorUpdateRef) },
-		{ "monitorRuntimeConfig", "( 1.3.6.1.4.1.4203.666.1.55.29 "
+		{ "( 1.3.6.1.4.1.4203.666.1.55.29 "
 			"NAME 'monitorRuntimeConfig' "
 			"DESC 'TRUE if component allows runtime configuration' "
 			"EQUALITY booleanMatch "
 			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
 			"SINGLE-VALUE "
-			"USAGE directoryOperation )", SLAP_AT_HIDE,
+			"USAGE dSAOperation )", SLAP_AT_HIDE,
 			offsetof(monitor_info_t, mi_ad_monitorRuntimeConfig) },
-		{ NULL, NULL, 0, -1 }
+		{ NULL, 0, -1 }
 	};
 
+	static struct {
+		char			*name;
+		char			*oid;
+	}		s_oid[] = {
+		{ "olmAttributes",			"1.3.6.1.4.1.4203.666.1.55" },
+		{ "olmSubSystemAttributes",		"olmAttributes:0" },
+		{ "olmGenericAttributes",		"olmSubSystemAttributes:0" },
+		{ "olmDatabaseAttributes",		"olmSubSystemAttributes:1" },
+
+		/* for example, back-bdb specific attrs
+		 * are in "olmDatabaseAttributes:1"
+		 *
+		 * NOTE: developers, please record here OID assignments
+		 * for other modules */
+
+		{ "olmObjectClasses",			"1.3.6.1.4.1.4203.666.3.16" },
+		{ "olmSubSystemObjectClasses",		"olmObjectClasses:0" },
+		{ "olmGenericObjectClasses",		"olmSubSystemObjectClasses:0" },
+		{ "olmDatabaseObjectClasses",		"olmSubSystemObjectClasses:1" },
+
+		/* for example, back-bdb specific objectClasses
+		 * are in "olmDatabaseObjectClasses:1"
+		 *
+		 * NOTE: developers, please record here OID assignments
+		 * for other modules */
+
+		{ NULL }
+	};
+
 	int			i, rc;
-	const char		*text;
 	monitor_info_t		*mi = &monitor_info;
+	ConfigArgs c;
+	char	*argv[ 3 ];
 
+	argv[ 0 ] = "monitor";
+	c.argv = argv;
+	c.argc = 3;
+	c.fname = argv[0];
+
+	for ( i = 0; s_oid[ i ].name; i++ ) {
+		argv[ 1 ] = s_oid[ i ].name;
+		argv[ 2 ] = s_oid[ i ].oid;
+
+		if ( parse_oidm( &c, 0, NULL ) != 0 ) {
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_initialize: unable to add "
+				"objectIdentifier \"%s=%s\"\n",
+				s_oid[ i ].name, s_oid[ i ].oid, 0 );
+			return 1;
+		}
+	}
+
 	/* schema integration */
-	for ( i = 0; mat[ i ].name; i++ ) {
-		LDAPAttributeType	*at;
+	for ( i = 0; mat[ i ].schema; i++ ) {
 		int			code;
-		const char		*err;
-		AttributeDescription	**ad;
+		AttributeDescription **ad =
+			((AttributeDescription **)&(((char *)mi)[ mat[ i ].offset ]));
 
-		at = ldap_str2attributetype( mat[ i ].schema, &code,
-			&err, LDAP_SCHEMA_ALLOW_ALL );
-		if ( !at ) {
-			Debug( LDAP_DEBUG_ANY, "monitor_back_db_init: "
-				"in AttributeType \"%s\" %s before %s\n",
-				mat[ i ].name, ldap_scherr2str(code), err );
-			return -1;
-		}
+		*ad = NULL;
+		code = register_at( mat[ i ].schema, ad, 0 );
 
-		if ( at->at_oid == NULL ) {
-			Debug( LDAP_DEBUG_ANY, "monitor_back_db_init: "
-				"null OID for attributeType \"%s\"\n",
-				mat[ i ].name, 0, 0 );
-			return -1;
-		}
-
-		code = at_add(at, 0, NULL, &err);
 		if ( code ) {
-			Debug( LDAP_DEBUG_ANY, "monitor_back_db_init: "
-				"%s in attributeType \"%s\"\n",
-				scherr2str(code), mat[ i ].name, 0 );
-			return -1;
-		}
-		ldap_memfree(at);
-
-		ad = ((AttributeDescription **)&(((char *)mi)[ mat[ i ].offset ]));
-		ad[ 0 ] = NULL;
-		if ( slap_str2ad( mat[ i ].name, ad, &text ) ) {
 			Debug( LDAP_DEBUG_ANY,
-				"monitor_back_db_init: %s\n", text, 0, 0 );
+				"monitor_back_db_init: register_at failed\n", 0, 0, 0 );
 			return -1;
 		}
-
 		(*ad)->ad_type->sat_flags |= mat[ i ].flags;
 	}
 
-	for ( i = 0; moc[ i ].name; i++ ) {
-		LDAPObjectClass		*oc;
+	for ( i = 0; moc[ i ].schema; i++ ) {
 		int			code;
-		const char		*err;
-		ObjectClass		*Oc;
+		ObjectClass		**Oc =
+			((ObjectClass **)&(((char *)mi)[ moc[ i ].offset ]));
 
-		oc = ldap_str2objectclass(moc[ i ].schema, &code, &err,
-				LDAP_SCHEMA_ALLOW_ALL );
-		if ( !oc ) {
-			Debug( LDAP_DEBUG_ANY,
-				"unable to parse monitor objectclass \"%s\": "
-				"%s before %s\n" , moc[ i ].name,
-				ldap_scherr2str(code), err );
-			return -1;
-		}
-
-		if ( oc->oc_oid == NULL ) {
-			Debug( LDAP_DEBUG_ANY,
-				"objectclass \"%s\" has no OID\n" ,
-				moc[ i ].name, 0, 0 );
-			return -1;
-		}
-
-		code = oc_add(oc, 0, NULL, &err);
+		code = register_oc( moc[ i ].schema, Oc, 0 );
 		if ( code ) {
 			Debug( LDAP_DEBUG_ANY,
-				"objectclass \"%s\": %s \"%s\"\n" ,
-				moc[ i ].name, scherr2str(code), err );
+				"monitor_back_db_init: register_oc failed\n", 0, 0, 0 );
 			return -1;
 		}
-
-		ldap_memfree(oc);
-
-		Oc = oc_find( moc[ i ].name );
-		if ( Oc == NULL ) {
-			Debug( LDAP_DEBUG_ANY, "monitor_back_db_init: "
-					"unable to find objectClass %s "
-					"(just added)\n", moc[ i ].name, 0, 0 );
-			return -1;
-		}
-
-		Oc->soc_flags |= moc[ i ].flags;
-
-		((ObjectClass **)&(((char *)mi)[ moc[ i ].offset ]))[ 0 ] = Oc;
+		(*Oc)->soc_flags |= moc[ i ].flags;
 	}
 
 	bi->bi_controls = controls;
@@ -1395,12 +2033,13 @@
 	bi->bi_tool_entry_reindex = 0;
 	bi->bi_tool_sync = 0;
 	bi->bi_tool_dn2id_get = 0;
-	bi->bi_tool_id2entry_get = 0;
 	bi->bi_tool_entry_modify = 0;
 
 	bi->bi_connection_init = 0;
 	bi->bi_connection_destroy = 0;
 
+	bi->bi_extra = (void *)&monitor_extra;
+
 	/*
 	 * configuration objectClasses (fake)
 	 */
@@ -1416,7 +2055,8 @@
 
 int
 monitor_back_db_init(
-	BackendDB	*be )
+	BackendDB	*be,
+	ConfigReply	*c)
 {
 	int			rc;
 	struct berval		dn = BER_BVC( SLAPD_MONITOR_DN ),
@@ -1427,6 +2067,17 @@
 	monitor_subsys_t	*ms;
 
 	/*
+	 * database monitor can be defined once only
+	 */
+	if ( be_monitor != NULL ) {
+		if (c) {
+			snprintf(c->msg, sizeof(c->msg),"only one monitor database allowed");
+		}
+		return( -1 );
+	}
+	be_monitor = be;
+
+	/*
 	 * register subsys
 	 */
 	for ( ms = known_monitor_subsys; ms->mss_name != NULL; ms++ ) {
@@ -1435,16 +2086,6 @@
 		}
 	}
 
-	/*
-	 * database monitor can be defined once only
-	 */
-	if ( be_monitor != NULL ) {
-		Debug( LDAP_DEBUG_ANY,
-			"only one monitor database is allowed\n", 0, 0, 0 );
-		return( -1 );
-	}
-	be_monitor = be;
-
 	/* indicate system schema supported */
 	SLAP_BFLAGS(be) |= SLAP_BFLAG_MONITOR;
 
@@ -1465,7 +2106,7 @@
 
 	be->be_private = &monitor_info;
 
-	be2 = select_backend( &ndn, 0, 0 );
+	be2 = select_backend( &ndn, 0 );
 	if ( be2 != be ) {
 		char	*type = be2->bd_info->bi_type;
 
@@ -1474,33 +2115,78 @@
 			type = oi->oi_orig->bi_type;
 		}
 
-		Debug( LDAP_DEBUG_ANY,
-			"\"monitor\" database serving namingContext \"%s\" "
-			"is hidden by \"%s\" database serving namingContext \"%s\".\n",
-			pdn.bv_val, type, be2->be_nsuffix[ 0 ].bv_val );
+		if (c) {
+			snprintf(c->msg, sizeof(c->msg),
+					"\"monitor\" database serving namingContext \"%s\" "
+					"is hidden by \"%s\" database serving namingContext \"%s\".\n",
+					pdn.bv_val, type, be2->be_nsuffix[ 0 ].bv_val );
+		}
 		return -1;
 	}
 
 	return 0;
 }
 
+static void
+monitor_back_destroy_limbo_entry(
+	entry_limbo_t	*el,
+	int		dispose )
+{
+	if ( el->el_e ) {
+		entry_free( el->el_e );
+	}
+	if ( el->el_a ) {
+		attrs_free( el->el_a );
+	}
+	if ( !BER_BVISNULL( &el->el_nbase ) ) {
+		ber_memfree( el->el_nbase.bv_val );
+	}
+	if ( !BER_BVISNULL( &el->el_filter ) ) {
+		ber_memfree( el->el_filter.bv_val );
+	}
+
+	/* NOTE: callbacks are not copied; so only free them
+	 * if disposing of */
+	if ( el->el_cb && dispose != 0 ) {
+		monitor_callback_t *next;
+
+		for ( ; el->el_cb; el->el_cb = next ) {
+			next = el->el_cb->mc_next;
+			if ( el->el_cb->mc_dispose ) {
+				el->el_cb->mc_dispose( &el->el_cb->mc_private );
+			}
+			ch_free( el->el_cb );
+		}
+	}
+
+	ch_free( el );
+}
+
 int
 monitor_back_db_open(
-	BackendDB	*be )
+	BackendDB	*be,
+	ConfigReply	*cr)
 {
 	monitor_info_t 		*mi = (monitor_info_t *)be->be_private;
 	struct monitor_subsys_t	**ms;
-	Entry 			*e, **ep;
+	Entry 			*e, **ep, *root;
 	monitor_entry_t		*mp;
 	int			i;
-	char 			buf[ BACKMONITOR_BUFSIZE ];
-	struct berval		bv;
+	struct berval		bv, rdn = BER_BVC(SLAPD_MONITOR_DN);
 	struct tm		*tms;
 #ifdef HAVE_GMTIME_R
 	struct tm		tm_buf;
 #endif
 	static char		tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
+	struct berval	desc[] = {
+		BER_BVC("This subtree contains monitoring/managing objects."),
+		BER_BVC("This object contains information about this server."),
+		BER_BVC("Most of the information is held in operational"
+		" attributes, which must be explicitly requested."),
+		BER_BVNULL };
 
+	int			retcode = 0;
+
 	assert( be_monitor != NULL );
 	if ( be != be_monitor ) {
 		be_monitor = be;
@@ -1536,35 +2222,18 @@
 
 	if ( BER_BVISEMPTY( &be->be_rootdn ) ) {
 		BER_BVSTR( &mi->mi_creatorsName, SLAPD_ANONYMOUS );
+		BER_BVSTR( &mi->mi_ncreatorsName, SLAPD_ANONYMOUS );
 	} else {
 		mi->mi_creatorsName = be->be_rootdn;
+		mi->mi_ncreatorsName = be->be_rootndn;
 	}
 
 	/*
 	 * creates the "cn=Monitor" entry 
 	 */
-	snprintf( buf, sizeof( buf ), 
-		"dn: %s\n"
-		"objectClass: %s\n"
-		"structuralObjectClass: %s\n"
-		"cn: Monitor\n"
-		"description: This subtree contains monitoring/managing objects.\n"
-		"description: This object contains information about this server.\n"
-		"description: Most of the information is held in operational"
-		" attributes, which must be explicitly requested.\n"
-		"creatorsName: %s\n"
-		"modifiersName: %s\n"
-		"createTimestamp: %s\n"
-		"modifyTimestamp: %s\n",
-		SLAPD_MONITOR_DN,
-		mi->mi_oc_monitorServer->soc_cname.bv_val,
-		mi->mi_oc_monitorServer->soc_cname.bv_val,
-		mi->mi_creatorsName.bv_val,
-		mi->mi_creatorsName.bv_val,
-		mi->mi_startTime.bv_val,
-		mi->mi_startTime.bv_val );
+	e = monitor_entry_stub( NULL, NULL, &rdn, mi->mi_oc_monitorServer, mi,
+		NULL, NULL );
 
-	e = str2entry( buf );
 	if ( e == NULL) {
 		Debug( LDAP_DEBUG_ANY,
 			"unable to create \"%s\" entry\n",
@@ -1572,6 +2241,8 @@
 		return( -1 );
 	}
 
+	attr_merge_normalize( e, slap_schema.si_ad_description, desc, NULL );
+
 	bv.bv_val = strchr( (char *) Versionstr, '$' );
 	if ( bv.bv_val != NULL ) {
 		char	*end;
@@ -1617,6 +2288,7 @@
 			SLAPD_MONITOR_DN, 0, 0 );
 		return -1;
 	}
+	root = e;
 
 	/*	
 	 * Create all the subsystem specific entries
@@ -1639,46 +2311,18 @@
 			return( -1 );
 		}
 
-		dn.bv_len += sizeof( SLAPD_MONITOR_DN ); /* 1 for the , */
-		dn.bv_val = ch_malloc( dn.bv_len + 1 );
-		strcpy( dn.bv_val , monitor_subsys[ i ]->mss_rdn.bv_val );
-		strcat( dn.bv_val, "," SLAPD_MONITOR_DN );
-		rc = dnPrettyNormal( NULL, &dn, &monitor_subsys[ i ]->mss_dn,
-			&monitor_subsys[ i ]->mss_ndn, NULL );
-		free( dn.bv_val );
-		if ( rc != LDAP_SUCCESS ) {
-			Debug( LDAP_DEBUG_ANY,
-				"monitor DN \"%s\" is invalid\n", 
-				dn.bv_val, 0, 0 );
-			return( -1 );
-		}
+		e = monitor_entry_stub( &root->e_name, &root->e_nname,
+			&monitor_subsys[ i ]->mss_rdn, mi->mi_oc_monitorContainer, mi,
+			NULL, NULL );
 
-		snprintf( buf, sizeof( buf ),
-				"dn: %s\n"
-				"objectClass: %s\n"
-				"structuralObjectClass: %s\n"
-				"cn: %s\n"
-				"creatorsName: %s\n"
-				"modifiersName: %s\n"
-				"createTimestamp: %s\n"
-				"modifyTimestamp: %s\n",
-				monitor_subsys[ i ]->mss_dn.bv_val,
-				mi->mi_oc_monitorContainer->soc_cname.bv_val,
-				mi->mi_oc_monitorContainer->soc_cname.bv_val,
-				monitor_subsys[ i ]->mss_name,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_startTime.bv_val,
-				mi->mi_startTime.bv_val );
-		
-		e = str2entry( buf );
-		
 		if ( e == NULL) {
 			Debug( LDAP_DEBUG_ANY,
 				"unable to create \"%s\" entry\n", 
 				monitor_subsys[ i ]->mss_dn.bv_val, 0, 0 );
 			return( -1 );
 		}
+		monitor_subsys[i]->mss_dn = e->e_name;
+		monitor_subsys[i]->mss_ndn = e->e_nname;
 
 		if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_desc[ 0 ] ) ) {
 			attr_merge_normalize( e, slap_schema.si_ad_description,
@@ -1722,76 +2366,86 @@
 	monitor_subsys_opened = 1;
 
 	if ( mi->mi_entry_limbo ) {
-		entry_limbo_t	*el = (entry_limbo_t *)mi->mi_entry_limbo;
+		entry_limbo_t	*el = mi->mi_entry_limbo;
 
 		for ( ; el; ) {
 			entry_limbo_t	*tmp;
+			int		rc;
 
 			switch ( el->el_type ) {
 			case LIMBO_ENTRY:
-				monitor_back_register_entry(
+				rc = monitor_back_register_entry(
 						el->el_e,
-						el->el_cb );
+						el->el_cb,
+						el->el_mss,
+						el->el_flags );
 				break;
 
 			case LIMBO_ENTRY_PARENT:
-				monitor_back_register_entry_parent(
+				rc = monitor_back_register_entry_parent(
 						el->el_e,
 						el->el_cb,
-						&el->el_base,
+						el->el_mss,
+						el->el_flags,
+						&el->el_nbase,
 						el->el_scope,
 						&el->el_filter );
 				break;
 				
 
 			case LIMBO_ATTRS:
-				monitor_back_register_entry_attrs(
-						&el->el_ndn,
+				rc = monitor_back_register_entry_attrs(
+						el->el_ndn,
 						el->el_a,
 						el->el_cb,
-						&el->el_base,
+						&el->el_nbase,
 						el->el_scope,
 						&el->el_filter );
 				break;
 
 			case LIMBO_CB:
-				monitor_back_register_entry_callback(
-						&el->el_ndn,
+				rc = monitor_back_register_entry_callback(
+						el->el_ndn,
 						el->el_cb,
-						&el->el_base,
+						&el->el_nbase,
 						el->el_scope,
 						&el->el_filter );
 				break;
 
+			case LIMBO_BACKEND:
+				rc = monitor_back_register_backend( el->el_bi );
+				break;
+
+			case LIMBO_DATABASE:
+				rc = monitor_back_register_database( el->el_be, el->el_ndn );
+				break;
+
+			case LIMBO_OVERLAY_INFO:
+				rc = monitor_back_register_overlay_info( el->el_on );
+				break;
+
+			case LIMBO_OVERLAY:
+				rc = monitor_back_register_overlay( el->el_be );
+				break;
+
 			default:
 				assert( 0 );
 			}
 
-			if ( el->el_e ) {
-				entry_free( el->el_e );
-			}
-			if ( el->el_a ) {
-				attrs_free( el->el_a );
-			}
-			if ( !BER_BVISNULL( &el->el_ndn ) ) {
-				ber_memfree( el->el_ndn.bv_val );
-			}
-			if ( !BER_BVISNULL( &el->el_base ) ) {
-				ber_memfree( el->el_base.bv_val );
-			}
-			if ( !BER_BVISNULL( &el->el_filter ) ) {
-				ber_memfree( el->el_filter.bv_val );
-			}
-
 			tmp = el;
 			el = el->el_next;
-			ch_free( tmp );
+			monitor_back_destroy_limbo_entry( tmp, rc );
+
+			if ( rc != 0 ) {
+				/* try all, but report error at end */
+				retcode = 1;
+			}
 		}
 
 		mi->mi_entry_limbo = NULL;
 	}
 
-	return( 0 );
+	return retcode;
 }
 
 int
@@ -1828,7 +2482,8 @@
 
 int
 monitor_back_db_destroy(
-	BackendDB	*be )
+	BackendDB	*be,
+	ConfigReply	*cr)
 {
 	monitor_info_t	*mi = ( monitor_info_t * )be->be_private;
 
@@ -1854,18 +2509,20 @@
 			if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_rdn ) ) {
 				ch_free( monitor_subsys[ i ]->mss_rdn.bv_val );
 			}
-
-			if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_dn ) ) {
-				ch_free( monitor_subsys[ i ]->mss_dn.bv_val );
-			}
-
-			if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_ndn ) ) {
-				ch_free( monitor_subsys[ i ]->mss_ndn.bv_val );
-			}
 		}
 
 		ch_free( monitor_subsys );
 	}
+
+	if ( mi->mi_entry_limbo ) {
+		entry_limbo_t	*el = mi->mi_entry_limbo;
+
+		for ( ; el; ) {
+			entry_limbo_t *tmp = el;
+			el = el->el_next;
+			monitor_back_destroy_limbo_entry( tmp, 1 );
+		}
+	}
 	
 	ldap_pvt_thread_mutex_destroy( &monitor_info.mi_cache_mutex );
 

Modified: openldap/trunk/servers/slapd/back-monitor/listener.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/listener.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/listener.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* listener.c - deals with listener subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/listener.c,v 1.27.2.4 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/listener.c,v 1.31.2.2 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -69,32 +69,14 @@
 	for ( i = 0; l[ i ]; i++ ) {
 		char 		buf[ BACKMONITOR_BUFSIZE ];
 		Entry		*e;
+		struct berval bv;
 
-		snprintf( buf, sizeof( buf ),
-				"dn: cn=Listener %d,%s\n"
-				"objectClass: %s\n"
-				"structuralObjectClass: %s\n"
-				"cn: Listener %d\n"
-				"%s: %s\n"
-				"labeledURI: %s\n"
-				"creatorsName: %s\n"
-				"modifiersName: %s\n"
-				"createTimestamp: %s\n"
-				"modifyTimestamp: %s\n",
-				i,
-				ms->mss_dn.bv_val,
-				mi->mi_oc_monitoredObject->soc_cname.bv_val,
-				mi->mi_oc_monitoredObject->soc_cname.bv_val,
-				i,
-				mi->mi_ad_monitorConnectionLocalAddress->ad_cname.bv_val,
-				l[ i ]->sl_name.bv_val,
-				l[ i ]->sl_url.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_startTime.bv_val,
-				mi->mi_startTime.bv_val );
-		
-		e = str2entry( buf );
+		bv.bv_len = snprintf( buf, sizeof( buf ),
+				"cn=Listener %d", i );
+		bv.bv_val = buf;
+		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
+			mi->mi_oc_monitoredObject, mi, NULL, NULL );
+
 		if ( e == NULL ) {
 			Debug( LDAP_DEBUG_ANY,
 				"monitor_subsys_listener_init: "
@@ -103,6 +85,12 @@
 			return( -1 );
 		}
 
+		attr_merge_normalize_one( e, mi->mi_ad_monitorConnectionLocalAddress,
+				&l[ i ]->sl_name, NULL );
+
+		attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI,
+				&l[ i ]->sl_url, NULL );
+
 #ifdef HAVE_TLS
 		if ( l[ i ]->sl_is_tls ) {
 			struct berval bv;

Modified: openldap/trunk/servers/slapd/back-monitor/log.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/log.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/log.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* log.c - deal with log subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/log.c,v 1.45.2.7 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/log.c,v 1.56.2.2 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -111,7 +111,7 @@
 	int		rc = LDAP_OTHER;
 	int		newlevel = ldap_syslog;
 	Attribute	*save_attrs;
-	Modifications	*modlist = op->oq_modify.rs_modlist;
+	Modifications	*modlist = op->orm_modlist;
 	Modifications	*ml;
 
 	ldap_pvt_thread_mutex_lock( &monitor_log_mutex );
@@ -181,7 +181,7 @@
 		}
 
 		/* check that the entry still obeys the schema */
-		rc = entry_schema_check( op, e, save_attrs, 0,
+		rc = entry_schema_check( op, e, save_attrs, 0, 0,
 			&text, textbuf, sizeof( textbuf ) );
 		if ( rc != LDAP_SUCCESS ) {
 			rs->sr_err = rc;

Modified: openldap/trunk/servers/slapd/back-monitor/modify.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/modify.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/modify.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* modify.c - monitor backend modify routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/modify.c,v 1.17.2.6 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/modify.c,v 1.24.2.3 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -45,15 +45,12 @@
 	if ( e == NULL ) {
 		rs->sr_err = LDAP_NO_SUCH_OBJECT;
 		if ( matched ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 			if ( !access_allowed_mask( op, matched,
 					slap_schema.si_ad_entry,
 					NULL, ACL_DISCLOSE, NULL, NULL ) )
 			{
 				/* do nothing */ ;
-			} else 
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-			{
+			} else {
 				rs->sr_matched = matched->e_dn;
 			}
 		}
@@ -65,7 +62,7 @@
 		return rs->sr_err;
 	}
 
-	if ( !acl_check_modlist( op, e, op->oq_modify.rs_modlist )) {
+	if ( !acl_check_modlist( op, e, op->orm_modlist )) {
 		rc = LDAP_INSUFFICIENT_ACCESS;
 
 	} else {
@@ -75,7 +72,6 @@
 		rc = monitor_entry_modify( op, rs, e );
 	}
 
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 	if ( rc != LDAP_SUCCESS ) {
 		if ( !access_allowed_mask( op, e, slap_schema.si_ad_entry,
 				NULL, ACL_DISCLOSE, NULL, NULL ) )
@@ -83,7 +79,6 @@
 			rc = LDAP_NO_SUCH_OBJECT;
 		}
 	}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 
 	rs->sr_err = rc;
 	send_ldap_result( op, rs );

Modified: openldap/trunk/servers/slapd/back-monitor/operation.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/operation.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/operation.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* operation.c - deal with operation subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/operation.c,v 1.36.2.6 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/operation.c,v 1.46.2.3 2007/11/07 20:58:38 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -34,12 +34,12 @@
 } monitor_op[] = {
 	{ BER_BVC( "cn=Bind" ),		BER_BVNULL },
 	{ BER_BVC( "cn=Unbind" ),	BER_BVNULL },
+	{ BER_BVC( "cn=Search" ),	BER_BVNULL },
+	{ BER_BVC( "cn=Compare" ),	BER_BVNULL },
+	{ BER_BVC( "cn=Modify" ),	BER_BVNULL },
+	{ BER_BVC( "cn=Modrdn" ),	BER_BVNULL },
 	{ BER_BVC( "cn=Add" ),		BER_BVNULL },
 	{ BER_BVC( "cn=Delete" ),	BER_BVNULL },
-	{ BER_BVC( "cn=Modrdn" ),	BER_BVNULL },
-	{ BER_BVC( "cn=Modify" ),	BER_BVNULL },
-	{ BER_BVC( "cn=Compare" ),	BER_BVNULL },
-	{ BER_BVC( "cn=Search" ),	BER_BVNULL },
 	{ BER_BVC( "cn=Abandon" ),	BER_BVNULL },
 	{ BER_BVC( "cn=Extended" ),	BER_BVNULL },
 	{ BER_BVNULL,			BER_BVNULL }
@@ -65,7 +65,6 @@
 	
 	Entry		*e_op, **ep;
 	monitor_entry_t	*mp;
-	char		buf[ BACKMONITOR_BUFSIZE ];
 	int 		i;
 	struct berval	bv_zero = BER_BVC( "0" );
 
@@ -97,34 +96,14 @@
 	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
 		struct berval	rdn;
 		Entry		*e;
+		struct berval bv;
 
 		/*
 		 * Initiated ops
 		 */
-		snprintf( buf, sizeof( buf ),
-				"dn: %s,%s\n"
-				"objectClass: %s\n"
-				"structuralObjectClass: %s\n"
-				"cn: %s\n"
-				"%s: 0\n"
-				"%s: 0\n"
-				"creatorsName: %s\n"
-				"modifiersName: %s\n"
-				"createTimestamp: %s\n"
-				"modifyTimestamp: %s\n",
-				monitor_op[ i ].rdn.bv_val,
-				ms->mss_dn.bv_val,
-				mi->mi_oc_monitorOperation->soc_cname.bv_val,
-				mi->mi_oc_monitorOperation->soc_cname.bv_val,
-				&monitor_op[ i ].rdn.bv_val[ STRLENOF( "cn=" ) ],
-				mi->mi_ad_monitorOpInitiated->ad_cname.bv_val,
-				mi->mi_ad_monitorOpCompleted->ad_cname.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_startTime.bv_val,
-				mi->mi_startTime.bv_val );
+		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &monitor_op[i].rdn,
+			mi->mi_oc_monitorOperation, mi, NULL, NULL );
 
-		e = str2entry( buf );
 		if ( e == NULL ) {
 			Debug( LDAP_DEBUG_ANY,
 				"monitor_subsys_ops_init: "
@@ -133,7 +112,11 @@
 				ms->mss_ndn.bv_val, 0 );
 			return( -1 );
 		}
-	
+
+		BER_BVSTR( &bv, "0" );
+		attr_merge_one( e, mi->mi_ad_monitorOpInitiated, &bv, NULL );
+		attr_merge_one( e, mi->mi_ad_monitorOpCompleted, &bv, NULL );
+
 		/* steal normalized RDN */
 		dnRdn( &e->e_nname, &rdn );
 		ber_dupbv( &monitor_op[ i ].nrdn, &rdn );
@@ -194,6 +177,7 @@
 	struct berval		rdn;
 	int 			i;
 	Attribute		*a;
+	slap_counters_t *sc;
 	static struct berval	bv_ops = BER_BVC( "cn=operations" );
 
 	assert( mi != NULL );
@@ -205,21 +189,35 @@
 		ldap_pvt_mp_init( nInitiated );
 		ldap_pvt_mp_init( nCompleted );
 
-		ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
+		ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
 		for ( i = 0; i < SLAP_OP_LAST; i++ ) {
 			ldap_pvt_mp_add( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
 			ldap_pvt_mp_add( nCompleted, slap_counters.sc_ops_completed_[ i ] );
 		}
-		ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
+		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+			for ( i = 0; i < SLAP_OP_LAST; i++ ) {
+				ldap_pvt_mp_add( nInitiated, sc->sc_ops_initiated_[ i ] );
+				ldap_pvt_mp_add( nCompleted, sc->sc_ops_completed_[ i ] );
+			}
+			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+		}
+		ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
 		
 	} else {
 		for ( i = 0; i < SLAP_OP_LAST; i++ ) {
 			if ( dn_match( &rdn, &monitor_op[ i ].nrdn ) )
 			{
-				ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
+				ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
 				ldap_pvt_mp_init_set( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
 				ldap_pvt_mp_init_set( nCompleted, slap_counters.sc_ops_completed_[ i ] );
-				ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
+				for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+					ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+					ldap_pvt_mp_add( nInitiated, sc->sc_ops_initiated_[ i ] );
+					ldap_pvt_mp_add( nCompleted, sc->sc_ops_completed_[ i ] );
+					ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+				}
+				ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
 				break;
 			}
 		}

Modified: openldap/trunk/servers/slapd/back-monitor/operational.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/operational.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/operational.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* operational.c - monitor backend operational attributes function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/operational.c,v 1.14.2.4 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/operational.c,v 1.17.2.2 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-monitor/overlay.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/overlay.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/overlay.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -75,32 +75,10 @@
 		Entry		*e;
 		BackendDB	*be;
 
-		snprintf( buf, sizeof( buf ),
-				"dn: cn=Overlay %d,%s\n"
-				"objectClass: %s\n"
-				"structuralObjectClass: %s\n"
-				"cn: Overlay %d\n"
-				"%s: %s\n"
-				"%s: %s\n"
-				"creatorsName: %s\n"
-				"modifiersName: %s\n"
-				"createTimestamp: %s\n"
-				"modifyTimestamp: %s\n",
-				i,
-				ms->mss_dn.bv_val,
-				mi->mi_oc_monitoredObject->soc_cname.bv_val,
-				mi->mi_oc_monitoredObject->soc_cname.bv_val,
-				i,
-				mi->mi_ad_monitoredInfo->ad_cname.bv_val,
-					on->on_bi.bi_type,
-				mi->mi_ad_monitorRuntimeConfig->ad_cname.bv_val,
-					on->on_bi.bi_cf_ocs ? "TRUE" : "FALSE",
-				mi->mi_creatorsName.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_startTime.bv_val,
-				mi->mi_startTime.bv_val );
-		
-		e = str2entry( buf );
+		bv.bv_len = snprintf( buf, sizeof( buf ), "cn=Overlay %d", i );
+		bv.bv_val = buf;
+		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
+			mi->mi_oc_monitoredObject, mi, NULL, NULL );
 		if ( e == NULL ) {
 			Debug( LDAP_DEBUG_ANY,
 				"monitor_subsys_overlay_init: "
@@ -108,8 +86,12 @@
 				i, ms->mss_ndn.bv_val, 0 );
 			return( -1 );
 		}
-		
 		ber_str2bv( on->on_bi.bi_type, 0, 0, &bv );
+		attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
+		attr_merge_normalize_one( e, mi->mi_ad_monitorRuntimeConfig,
+			on->on_bi.bi_cf_ocs ? (struct berval *)&slap_true_bv :
+				(struct berval *)&slap_false_bv, NULL );
+		
 		attr_merge_normalize_one( e_overlay, mi->mi_ad_monitoredInfo,
 				&bv, NULL );
 

Modified: openldap/trunk/servers/slapd/back-monitor/proto-back-monitor.h
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/proto-back-monitor.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/proto-back-monitor.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/proto-back-monitor.h,v 1.25.2.7 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/proto-back-monitor.h,v 1.33.2.4 2007/09/29 09:27:01 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -54,6 +54,11 @@
 	struct berval		*ndn,
 	Entry			**ep ));
 extern int
+monitor_cache_remove LDAP_P((
+	monitor_info_t		*mi,
+	struct berval		*ndn,
+	Entry			**ep ));
+extern int
 monitor_cache_dn2entry LDAP_P((
 	Operation		*op,
 	SlapReply		*rs,
@@ -116,12 +121,51 @@
 monitor_entrypriv_create LDAP_P((
 	void ));
 
+extern Entry *
+monitor_entry_stub LDAP_P((
+	struct berval	*pdn,
+	struct berval	*pndn,
+	struct berval	*rdn,
+	ObjectClass		*oc,
+	monitor_info_t	*mi,
+	struct berval	*create,
+	struct berval	*modify));
+
 /*
  * init
  */
 extern int
+monitor_subsys_is_opened LDAP_P((
+	void ));
+extern int
 monitor_back_register_subsys LDAP_P((
 	monitor_subsys_t	*ms ));
+extern int
+monitor_back_register_backend LDAP_P((
+	BackendInfo		*bi ));
+extern int
+monitor_back_register_database LDAP_P((
+	BackendDB		*be,
+	struct berval	*ndn ));
+extern int
+monitor_back_register_overlay_info LDAP_P((
+	slap_overinst		*on ));
+extern int
+monitor_back_register_overlay LDAP_P((
+	BackendDB		*be ));
+extern int
+monitor_back_register_backend_limbo LDAP_P((
+	BackendInfo		*bi ));
+extern int
+monitor_back_register_database_limbo LDAP_P((
+	BackendDB		*be,
+	struct berval	*ndn ));
+extern int
+monitor_back_register_overlay_info_limbo LDAP_P((
+	slap_overinst		*on ));
+extern int
+monitor_back_register_overlay_limbo LDAP_P((
+	BackendDB		*be ));
 extern monitor_subsys_t *
 monitor_back_get_subsys LDAP_P((
 	const char		*name ));
@@ -134,16 +178,20 @@
 extern int
 monitor_back_register_entry LDAP_P((
 	Entry			*e,
-	monitor_callback_t	*cb ));
+	monitor_callback_t	*cb,
+	monitor_subsys_t	*mss,
+	unsigned long		flags ));
 extern int
 monitor_back_register_entry_parent LDAP_P((
 	Entry			*e,
 	monitor_callback_t	*cb,
+	monitor_subsys_t	*mss,
+	unsigned long		flags,
 	struct berval		*base,
 	int			scope,
 	struct berval		*filter ));
 extern int
-monitor_filter2ndn LDAP_P((
+monitor_search2ndn LDAP_P((
 	struct berval		*base,
 	int			scope,
 	struct berval		*filter,
@@ -163,6 +211,31 @@
 	struct berval		*base,
 	int			scope,
 	struct berval		*filter ));
+extern int
+monitor_back_unregister_entry LDAP_P((
+	struct berval		*ndn ));
+extern int
+monitor_back_unregister_entry_parent LDAP_P((
+	struct berval		*nrdn,
+	monitor_callback_t	*target_cb,
+	struct berval		*base,
+	int			scope,
+	struct berval		*filter ));
+extern int
+monitor_back_unregister_entry_attrs LDAP_P((
+	struct berval		*ndn,
+	Attribute		*a,
+	monitor_callback_t	*cb,
+	struct berval		*base,
+	int			scope,
+	struct berval		*filter ));
+extern int
+monitor_back_unregister_entry_callback LDAP_P((
+	struct berval		*ndn,
+	monitor_callback_t	*cb,
+	struct berval		*base,
+	int			scope,
+	struct berval		*filter ));
 
 /*
  * listener

Modified: openldap/trunk/servers/slapd/back-monitor/rww.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/rww.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/rww.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* readw.c - deal with read waiters subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/rww.c,v 1.26.2.6 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/rww.c,v 1.36.2.2 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -86,30 +86,11 @@
 	ep = &mp->mp_children;
 
 	for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
-		char			buf[ BACKMONITOR_BUFSIZE ];
 		struct berval		nrdn, bv;
 		Entry			*e;
 		
-		snprintf( buf, sizeof( buf ),
-			"dn: %s,%s\n"
-			"objectClass: %s\n"
-			"structuralObjectClass: %s\n"
-			"cn: %s\n"
-			"creatorsName: %s\n"
-			"modifiersName: %s\n"
-			"createTimestamp: %s\n"
-			"modifyTimestamp: %s\n",
-			monitor_rww[ i ].rdn.bv_val,
-			ms->mss_dn.bv_val,
-			mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
-			mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
-			&monitor_rww[ i ].rdn.bv_val[ STRLENOF( "cn=" ) ],
-			mi->mi_creatorsName.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_startTime.bv_val,
-			mi->mi_startTime.bv_val );
-	
-		e = str2entry( buf );
+		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &monitor_rww[i].rdn,
+			mi->mi_oc_monitorCounterObject, mi, NULL, NULL );
 		if ( e == NULL ) {
 			Debug( LDAP_DEBUG_ANY,
 				"monitor_subsys_rww_init: "
@@ -123,7 +104,7 @@
 		ber_dupbv( &monitor_rww[ i ].nrdn, &nrdn );
 	
 		BER_BVSTR( &bv, "0" );
-		attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, &bv );
+		attr_merge_normalize_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
 	
 		mp = monitor_entrypriv_create();
 		if ( mp == NULL ) {

Modified: openldap/trunk/servers/slapd/back-monitor/search.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* search.c - monitor backend search function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/search.c,v 1.32.2.7 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/search.c,v 1.39.2.4 2007/08/31 23:14:03 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -174,15 +174,12 @@
 	if ( e == NULL ) {
 		rs->sr_err = LDAP_NO_SUCH_OBJECT;
 		if ( matched ) {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 			if ( !access_allowed_mask( op, matched,
 					slap_schema.si_ad_entry,
 					NULL, ACL_DISCLOSE, NULL, NULL ) )
 			{
 				/* do nothing */ ;
-			} else 
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-			{
+			} else {
 				rs->sr_matched = matched->e_dn;
 			}
 		}
@@ -203,12 +200,9 @@
 	{
 		monitor_cache_release( mi, e );
 
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 		if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) {
 			rs->sr_err = LDAP_NO_SUCH_OBJECT;
-		} else 
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
-		{
+		} else {
 			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
 		}
 

Modified: openldap/trunk/servers/slapd/back-monitor/sent.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/sent.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/sent.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* sent.c - deal with data sent subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/sent.c,v 1.33.2.5 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/sent.c,v 1.42.2.3 2007/11/07 20:58:38 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -89,30 +89,13 @@
 	ep = &mp->mp_children;
 
 	for ( i = 0; i < MONITOR_SENT_LAST; i++ ) {
-		char			buf[ BACKMONITOR_BUFSIZE ];
 		struct berval		nrdn, bv;
 		Entry			*e;
 
-		snprintf( buf, sizeof( buf ),
-				"dn: %s,%s\n"
-				"objectClass: %s\n"
-				"structuralObjectClass: %s\n"
-				"cn: %s\n"
-				"creatorsName: %s\n"
-				"modifiersName: %s\n"
-				"createTimestamp: %s\n"
-				"modifyTimestamp: %s\n",
-				monitor_sent[ i ].rdn.bv_val,
-				ms->mss_dn.bv_val,
-				mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
-				mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
-				&monitor_sent[ i ].rdn.bv_val[ STRLENOF( "cn=" ) ],
-				mi->mi_creatorsName.bv_val,
-				mi->mi_creatorsName.bv_val,
-				mi->mi_startTime.bv_val,
-				mi->mi_startTime.bv_val );
-
-		e = str2entry( buf );
+		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn,
+			&monitor_sent[i].rdn, mi->mi_oc_monitorCounterObject,
+			mi, NULL, NULL );
+			
 		if ( e == NULL ) {
 			Debug( LDAP_DEBUG_ANY,
 				"monitor_subsys_sent_init: "
@@ -127,7 +110,7 @@
 		ber_dupbv( &monitor_sent[ i ].nrdn, &nrdn );
 	
 		BER_BVSTR( &bv, "0" );
-		attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, &bv );
+		attr_merge_normalize_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
 	
 		mp = monitor_entrypriv_create();
 		if ( mp == NULL ) {
@@ -183,6 +166,7 @@
 	struct berval		nrdn;
 	ldap_pvt_mp_t		n;
 	Attribute		*a;
+	slap_counters_t *sc;
 	int			i;
 
 	assert( mi != NULL );
@@ -200,28 +184,48 @@
 		return SLAP_CB_CONTINUE;
 	}
 
-	ldap_pvt_thread_mutex_lock(&slap_counters.sc_sent_mutex);
+	ldap_pvt_thread_mutex_lock(&slap_counters.sc_mutex);
 	switch ( i ) {
 	case MONITOR_SENT_ENTRIES:
 		ldap_pvt_mp_init_set( n, slap_counters.sc_entries );
+		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+			ldap_pvt_mp_add( n, sc->sc_entries );
+			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+		}
 		break;
 
 	case MONITOR_SENT_REFERRALS:
 		ldap_pvt_mp_init_set( n, slap_counters.sc_refs );
+		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+			ldap_pvt_mp_add( n, sc->sc_refs );
+			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+		}
 		break;
 
 	case MONITOR_SENT_PDU:
 		ldap_pvt_mp_init_set( n, slap_counters.sc_pdu );
+		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+			ldap_pvt_mp_add( n, sc->sc_pdu );
+			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+		}
 		break;
 
 	case MONITOR_SENT_BYTES:
 		ldap_pvt_mp_init_set( n, slap_counters.sc_bytes );
+		for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+			ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+			ldap_pvt_mp_add( n, sc->sc_bytes );
+			ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+		}
 		break;
 
 	default:
 		assert(0);
 	}
-	ldap_pvt_thread_mutex_unlock(&slap_counters.sc_sent_mutex);
+	ldap_pvt_thread_mutex_unlock(&slap_counters.sc_mutex);
 	
 	a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
 	assert( a != NULL );

Modified: openldap/trunk/servers/slapd/back-monitor/thread.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/thread.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/thread.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* thread.c - deal with thread subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/thread.c,v 1.29.2.6 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/thread.c,v 1.38.2.5 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -29,11 +29,74 @@
 
 #include <ldap_rq.h>
 
+#ifndef NO_THREADS
+typedef enum {
+	MT_UNKNOWN,
+	MT_RUNQUEUE,
+	MT_TASKLIST,
+
+	MT_LAST
+} monitor_thread_t;
+
+static struct {
+	struct berval			rdn;
+	struct berval			desc;
+	struct berval			nrdn;
+	ldap_pvt_thread_pool_param_t	param;
+	monitor_thread_t		mt;
+}		mt[] = {
+	{ BER_BVC( "cn=Max" ),
+		BER_BVC("Maximum number of threads as configured"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_MAX,		MT_UNKNOWN },
+	{ BER_BVC( "cn=Max Pending" ),
+		BER_BVC("Maximum number of pending threads"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_MAX_PENDING,	MT_UNKNOWN },
+	{ BER_BVC( "cn=Open" ),		
+		BER_BVC("Number of open threads"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_OPEN,	MT_UNKNOWN },
+	{ BER_BVC( "cn=Starting" ),	
+		BER_BVC("Number of threads being started"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_STARTING,	MT_UNKNOWN },
+	{ BER_BVC( "cn=Active" ),	
+		BER_BVC("Number of active threads"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_ACTIVE,	MT_UNKNOWN },
+	{ BER_BVC( "cn=Pending" ),	
+		BER_BVC("Number of pending threads"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_PENDING,	MT_UNKNOWN },
+	{ BER_BVC( "cn=Backload" ),	
+		BER_BVC("Number of active plus pending threads"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD,	MT_UNKNOWN },
+#if 0	/* not meaningful right now */
+	{ BER_BVC( "cn=Active Max" ),
+		BER_BVNULL,
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_ACTIVE_MAX,	MT_UNKNOWN },
+	{ BER_BVC( "cn=Pending Max" ),
+		BER_BVNULL,
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_PENDING_MAX,	MT_UNKNOWN },
+	{ BER_BVC( "cn=Backload Max" ),
+		BER_BVNULL,
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD_MAX,MT_UNKNOWN },
+#endif
+	{ BER_BVC( "cn=State" ),
+		BER_BVC("Thread pool state"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_STATE,	MT_UNKNOWN },
+
+	{ BER_BVC( "cn=Runqueue" ),
+		BER_BVC("Queue of running threads - besides those handling operations"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN,	MT_RUNQUEUE },
+	{ BER_BVC( "cn=Tasklist" ),
+		BER_BVC("List of running plus standby threads - besides those handling operations"),
+		BER_BVNULL,	LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN,	MT_TASKLIST },
+
+	{ BER_BVNULL }
+};
+
 static int 
 monitor_subsys_thread_update( 
 	Operation		*op,
 	SlapReply		*rs,
 	Entry 			*e );
+#endif /* ! NO_THREADS */
 
 /*
  * initializes log subentry
@@ -41,13 +104,13 @@
 int
 monitor_subsys_thread_init(
 	BackendDB       	*be,
-	monitor_subsys_t	*ms
-)
+	monitor_subsys_t	*ms )
 {
+#ifndef NO_THREADS
 	monitor_info_t	*mi;
 	monitor_entry_t	*mp;
 	Entry		*e, **ep, *e_thread;
-	static char	buf[ BACKMONITOR_BUFSIZE ];
+	int		i;
 
 	ms->mss_update = monitor_subsys_thread_update;
 
@@ -56,7 +119,7 @@
 	if ( monitor_cache_get( mi, &ms->mss_ndn, &e_thread ) ) {
 		Debug( LDAP_DEBUG_ANY,
 			"monitor_subsys_thread_init: unable to get entry \"%s\"\n",
-			ms->mss_ndn.bv_val, 
+			ms->mss_dn.bv_val, 
 			0, 0 );
 		return( -1 );
 	}
@@ -65,165 +128,94 @@
 	mp->mp_children = NULL;
 	ep = &mp->mp_children;
 
-	/*
-	 * Max
-	 */
-	snprintf( buf, sizeof( buf ),
-			"dn: cn=Max,%s\n"
-			"objectClass: %s\n"
-			"structuralObjectClass: %s\n"
-			"cn: Max\n"
-			"%s: %d\n"
-			"creatorsName: %s\n"
-			"modifiersName: %s\n"
-			"createTimestamp: %s\n"
-			"modifyTimestamp: %s\n", 
-			ms->mss_dn.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_ad_monitoredInfo->ad_cname.bv_val,
-			connection_pool_max,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_startTime.bv_val,
-			mi->mi_startTime.bv_val );
+	for ( i = 0; !BER_BVISNULL( &mt[ i ].rdn ); i++ ) {
+		static char	buf[ BACKMONITOR_BUFSIZE ];
+		int		count = -1;
+		char		*state = NULL;
+		struct berval	bv = BER_BVNULL;
 
-	e = str2entry( buf );
-	if ( e == NULL ) {
-		Debug( LDAP_DEBUG_ANY,
-			"monitor_subsys_thread_init: "
-			"unable to create entry \"cn=Max,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
-		return( -1 );
-	}
-	
-	mp = monitor_entrypriv_create();
-	if ( mp == NULL ) {
-		return -1;
-	}
-	e->e_private = ( void * )mp;
-	mp->mp_info = ms;
-	mp->mp_flags = ms->mss_flags \
-		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
+		/*
+		 * Max
+		 */
+		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn,
+			&mt[ i ].rdn,
+			mi->mi_oc_monitoredObject, mi, NULL, NULL );
+		if ( e == NULL ) {
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_subsys_thread_init: "
+				"unable to create entry \"%s,%s\"\n",
+				mt[ i ].rdn.bv_val,
+				ms->mss_ndn.bv_val, 0 );
+			return( -1 );
+		}
 
-	if ( monitor_cache_add( mi, e ) ) {
-		Debug( LDAP_DEBUG_ANY,
-			"monitor_subsys_thread_init: "
-			"unable to add entry \"cn=Max,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
-		return( -1 );
-	}
-	
-	*ep = e;
-	ep = &mp->mp_next;
+		/* NOTE: reference to the normalized DN of the entry,
+		 * under the assumption it's not modified */
+		dnRdn( &e->e_nname, &mt[ i ].nrdn );
 
-	/*
-	 * Backload
-	 */
-	snprintf( buf, sizeof( buf ),
-			"dn: cn=Backload,%s\n"
-			"objectClass: %s\n"
-			"structuralObjectClass: %s\n"
-			"cn: Backload\n"
-			"%s: 0\n"
-			"creatorsName: %s\n"
-			"modifiersName: %s\n"
-			"createTimestamp: %s\n"
-			"modifyTimestamp: %s\n",
-			ms->mss_dn.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_ad_monitoredInfo->ad_cname.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_startTime.bv_val,
-			mi->mi_startTime.bv_val );
+		switch ( mt[ i ].param ) {
+		case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN:
+			break;
 
-	e = str2entry( buf );
-	if ( e == NULL ) {
-		Debug( LDAP_DEBUG_ANY,
-			"monitor_subsys_thread_init: "
-			"unable to create entry \"cn=Backload,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
-		return( -1 );
-	}
+		case LDAP_PVT_THREAD_POOL_PARAM_STATE:
+			if ( ldap_pvt_thread_pool_query( &connection_pool,
+				mt[ i ].param, (void *)&state ) == 0 )
+			{
+				ber_str2bv( state, 0, 0, &bv );
 
-	mp = monitor_entrypriv_create();
-	if ( mp == NULL ) {
-		return -1;
-	}
-	e->e_private = ( void * )mp;
-	mp->mp_info = ms;
-	mp->mp_flags = ms->mss_flags \
-		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
+			} else {
+				BER_BVSTR( &bv, "unknown" );
+			}
+			break;
 
-	if ( monitor_cache_add( mi, e ) ) {
-		Debug( LDAP_DEBUG_ANY,
-			"monitor_subsys_thread_init: "
-			"unable to add entry \"cn=Backload,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
-		return( -1 );
-	}
-	
-	*ep = e;
-	ep = &mp->mp_next;
+		default:
+			/* NOTE: in case of error, it'll be set to -1 */
+			(void)ldap_pvt_thread_pool_query( &connection_pool,
+				mt[ i ].param, (void *)&count );
+			bv.bv_val = buf;
+			bv.bv_len = snprintf( buf, sizeof( buf ), "%d", count );
+			break;
+		}
 
-	/*
-	 * Runqueue runners
-	 */
-	snprintf( buf, sizeof( buf ),
-			"dn: cn=Runqueue,%s\n"
-			"objectClass: %s\n"
-			"structuralObjectClass: %s\n"
-			"cn: Runqueue\n"
-			"%s: 0\n"
-			"creatorsName: %s\n"
-			"modifiersName: %s\n"
-			"createTimestamp: %s\n"
-			"modifyTimestamp: %s\n",
-			ms->mss_dn.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_ad_monitoredInfo->ad_cname.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_startTime.bv_val,
-			mi->mi_startTime.bv_val );
+		if ( !BER_BVISNULL( &bv ) ) {
+			attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
+		}
 
-	e = str2entry( buf );
-	if ( e == NULL ) {
-		Debug( LDAP_DEBUG_ANY,
-			"monitor_subsys_thread_init: "
-			"unable to create entry \"cn=Runqueue,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
-		return( -1 );
-	}
+		if ( !BER_BVISNULL( &mt[ i ].desc ) ) {
+			attr_merge_normalize_one( e,
+				slap_schema.si_ad_description,
+				&mt[ i ].desc, NULL );
+		}
+	
+		mp = monitor_entrypriv_create();
+		if ( mp == NULL ) {
+			return -1;
+		}
+		e->e_private = ( void * )mp;
+		mp->mp_info = ms;
+		mp->mp_flags = ms->mss_flags \
+			| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
 
-	mp = monitor_entrypriv_create();
-	if ( mp == NULL ) {
-		return -1;
+		if ( monitor_cache_add( mi, e ) ) {
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_subsys_thread_init: "
+				"unable to add entry \"%s,%s\"\n",
+				mt[ i ].rdn.bv_val,
+				ms->mss_dn.bv_val, 0 );
+			return( -1 );
+		}
+	
+		*ep = e;
+		ep = &mp->mp_next;
 	}
-	e->e_private = ( void * )mp;
-	mp->mp_info = ms;
-	mp->mp_flags = ms->mss_flags \
-		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
 
-	if ( monitor_cache_add( mi, e ) ) {
-		Debug( LDAP_DEBUG_ANY,
-			"monitor_subsys_thread_init: "
-			"unable to add entry \"cn=Runqueue,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
-		return( -1 );
-	}
-	
-	*ep = e;
-	ep = &mp->mp_next;
-
 	monitor_cache_release( mi, e_thread );
 
+#endif /* ! NO_THREADS */
 	return( 0 );
 }
 
+#ifndef NO_THREADS
 static int 
 monitor_subsys_thread_update( 
 	Operation		*op,
@@ -232,63 +224,128 @@
 {
 	monitor_info_t	*mi = ( monitor_info_t * )op->o_bd->be_private;
 	Attribute		*a;
+	BerVarray		vals = NULL;
 	char 			buf[ BACKMONITOR_BUFSIZE ];
-	static struct berval	backload_bv = BER_BVC( "cn=backload" );
-	static struct berval	runqueue_bv = BER_BVC( "cn=runqueue" );
 	struct berval		rdn, bv;
-	ber_len_t		len;
-	int which = 0, i;
-	struct re_s *re;
+	int			which, i;
+	struct re_s		*re;
+	int			count = -1;
+	char			*state = NULL;
 
 	assert( mi != NULL );
 
 	dnRdn( &e->e_nname, &rdn );
-	if ( dn_match( &rdn, &backload_bv ) ) {
-		which = 1;
 
-	} else if ( dn_match( &rdn, &runqueue_bv ) ) {
-		which = 2;
+	for ( i = 0; !BER_BVISNULL( &mt[ i ].nrdn ); i++ ) {
+		if ( dn_match( &mt[ i ].nrdn, &rdn ) ) {
+			break;
+		}
+	}
 
-	} else {
+	which = i;
+	if ( BER_BVISNULL( &mt[ which ].nrdn ) ) {
 		return SLAP_CB_CONTINUE;
 	}
 
 	a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
-	if ( a == NULL ) {
-		return rs->sr_err = LDAP_OTHER;
-	}
 
-	switch ( which ) {
-	case 1:
-		snprintf( buf, sizeof( buf ), "%d", 
-			ldap_pvt_thread_pool_backload( &connection_pool ) );
-		len = strlen( buf );
-		if ( len > a->a_vals[ 0 ].bv_len ) {
-			a->a_vals[ 0 ].bv_val = ber_memrealloc( a->a_vals[ 0 ].bv_val, len + 1 );
+	switch ( mt[ which ].param ) {
+	case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN:
+		switch ( mt[ which ].mt ) {
+		case MT_RUNQUEUE:
+			if ( a != NULL ) {
+				if ( a->a_nvals != a->a_vals ) {
+					ber_bvarray_free( a->a_nvals );
+				}
+				ber_bvarray_free( a->a_vals );
+				a->a_vals = NULL;
+				a->a_nvals = NULL;
+			}
+
+			i = 0;
+			bv.bv_val = buf;
+			ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+			LDAP_STAILQ_FOREACH( re, &slapd_rq.run_list, rnext ) {
+				bv.bv_len = snprintf( buf, sizeof( buf ), "{%d}%s(%s)",
+					i, re->tname, re->tspec );
+				if ( bv.bv_len < sizeof( buf ) ) {
+					value_add_one( &vals, &bv );
+				}
+				i++;
+			}
+			ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+	
+			if ( vals ) {
+				attr_merge_normalize( e, mi->mi_ad_monitoredInfo, vals, NULL );
+				ber_bvarray_free( vals );
+
+			} else {
+				attr_delete( &e->e_attrs, mi->mi_ad_monitoredInfo );
+			}
+			break;
+
+		case MT_TASKLIST:
+			if ( a != NULL ) {
+				if ( a->a_nvals != a->a_vals ) {
+					ber_bvarray_free( a->a_nvals );
+				}
+				ber_bvarray_free( a->a_vals );
+				a->a_vals = NULL;
+				a->a_nvals = NULL;
+			}
+	
+			i = 0;
+			bv.bv_val = buf;
+			ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+			LDAP_STAILQ_FOREACH( re, &slapd_rq.task_list, tnext ) {
+				bv.bv_len = snprintf( buf, sizeof( buf ), "{%d}%s(%s)",
+					i, re->tname, re->tspec );
+				if ( bv.bv_len < sizeof( buf ) ) {
+					value_add_one( &vals, &bv );
+				}
+				i++;
+			}
+			ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+	
+			if ( vals ) {
+				attr_merge_normalize( e, mi->mi_ad_monitoredInfo, vals, NULL );
+				ber_bvarray_free( vals );
+
+			} else {
+				attr_delete( &e->e_attrs, mi->mi_ad_monitoredInfo );
+			}
+			break;
+
+		default:
+			assert( 0 );
 		}
-		a->a_vals[ 0 ].bv_len = len;
-		AC_MEMCPY( a->a_vals[ 0 ].bv_val, buf, len + 1 );
 		break;
 
-	case 2:
-		for ( i = 0; !BER_BVISNULL( &a->a_vals[ i ] ); i++ ) {
-			ch_free( a->a_vals[i].bv_val );
-			BER_BVZERO( &a->a_vals[ i ] );
+	case LDAP_PVT_THREAD_POOL_PARAM_STATE:
+		if ( a == NULL ) {
+			return rs->sr_err = LDAP_OTHER;
 		}
-		bv.bv_val = buf;
-		ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
-		LDAP_STAILQ_FOREACH( re, &slapd_rq.run_list, rnext ) {
-			bv.bv_len = snprintf( buf, sizeof( buf ), "%s(%s)",
-				re->tname, re->tspec );
-			value_add_one( &a->a_vals, &bv );
+		if ( ldap_pvt_thread_pool_query( &connection_pool,
+			mt[ i ].param, (void *)&state ) == 0 )
+		{
+			ber_str2bv( state, 0, 0, &bv );
+			ber_bvreplace( &a->a_vals[ 0 ], &bv );
 		}
-		ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+		break;
 
-		/* don't leave 'round attributes with no values */
-		if ( BER_BVISNULL( &a->a_vals[ 0 ] ) ) {
-			BER_BVSTR( &bv, "()" );
-			value_add_one( &a->a_vals, &bv );
+	default:
+		if ( a == NULL ) {
+			return rs->sr_err = LDAP_OTHER;
 		}
+		if ( ldap_pvt_thread_pool_query( &connection_pool,
+			mt[ i ].param, (void *)&count ) == 0 )
+		{
+			bv.bv_val = buf;
+			bv.bv_len = snprintf( buf, sizeof( buf ), "%d", count );
+			if ( bv.bv_len < sizeof( buf ) ) {
+				ber_bvreplace( &a->a_vals[ 0 ], &bv );
+			}
+		}
 		break;
 	}
 
@@ -296,4 +353,4 @@
 
 	return SLAP_CB_CONTINUE;
 }
-
+#endif /* ! NO_THREADS */

Modified: openldap/trunk/servers/slapd/back-monitor/time.c
===================================================================
--- openldap/trunk/servers/slapd/back-monitor/time.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-monitor/time.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* time.c - deal with time subsystem */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/time.c,v 1.29.2.5 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/time.c,v 1.37.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -46,7 +46,7 @@
 	
 	Entry		*e, **ep, *e_time;
 	monitor_entry_t	*mp;
-	char		buf[ BACKMONITOR_BUFSIZE ];
+	struct berval	bv, value;
 
 	assert( be != NULL );
 
@@ -67,34 +67,18 @@
 	mp->mp_children = NULL;
 	ep = &mp->mp_children;
 
-	snprintf( buf, sizeof( buf ),
-			"dn: cn=Start,%s\n"
-			"objectClass: %s\n"
-			"structuralObjectClass: %s\n"
-			"cn: Start\n"
-			"%s: %s\n"
-			"creatorsName: %s\n"
-			"modifiersName: %s\n"
-			"createTimestamp: %s\n"
-			"modifyTimestamp: %s\n", 
-			ms->mss_dn.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_ad_monitorTimestamp->ad_cname.bv_val,
-			mi->mi_startTime.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_startTime.bv_val,
-			mi->mi_startTime.bv_val );
-
-	e = str2entry( buf );
+	BER_BVSTR( &bv, "cn=Start" );
+	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
+		mi->mi_oc_monitoredObject, mi, NULL, NULL );
 	if ( e == NULL ) {
 		Debug( LDAP_DEBUG_ANY,
 			"monitor_subsys_time_init: "
-			"unable to create entry \"cn=Start,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
+			"unable to create entry \"%s,%s\"\n",
+			bv.bv_val, ms->mss_ndn.bv_val, 0 );
 		return( -1 );
 	}
+	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
+		&mi->mi_startTime, NULL );
 	
 	mp = monitor_entrypriv_create();
 	if ( mp == NULL ) {
@@ -108,8 +92,8 @@
 	if ( monitor_cache_add( mi, e ) ) {
 		Debug( LDAP_DEBUG_ANY,
 			"monitor_subsys_time_init: "
-			"unable to add entry \"cn=Start,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
+			"unable to add entry \"%s,%s\"\n",
+			bv.bv_val, ms->mss_ndn.bv_val, 0 );
 		return( -1 );
 	}
 	
@@ -119,34 +103,55 @@
 	/*
 	 * Current
 	 */
-	snprintf( buf, sizeof( buf ),
-			"dn: cn=Current,%s\n"
-			"objectClass: %s\n"
-			"structuralObjectClass: %s\n"
-			"cn: Current\n"
-			"%s: %s\n"
-			"creatorsName: %s\n"
-			"modifiersName: %s\n"
-			"createTimestamp: %s\n"
-			"modifyTimestamp: %s\n",
-			ms->mss_dn.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_oc_monitoredObject->soc_cname.bv_val,
-			mi->mi_ad_monitorTimestamp->ad_cname.bv_val,
-			mi->mi_startTime.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_creatorsName.bv_val,
-			mi->mi_startTime.bv_val,
-			mi->mi_startTime.bv_val );
+	BER_BVSTR( &bv, "cn=Current" );
+	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
+		mi->mi_oc_monitoredObject, mi, NULL, NULL );
+	if ( e == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_time_init: "
+			"unable to create entry \"%s,%s\"\n",
+			bv.bv_val, ms->mss_ndn.bv_val, 0 );
+		return( -1 );
+	}
+	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
+		&mi->mi_startTime, NULL );
 
-	e = str2entry( buf );
+	mp = monitor_entrypriv_create();
+	if ( mp == NULL ) {
+		return -1;
+	}
+	e->e_private = ( void * )mp;
+	mp->mp_info = ms;
+	mp->mp_flags = ms->mss_flags \
+		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
+
+	if ( monitor_cache_add( mi, e ) ) {
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_subsys_time_init: "
+			"unable to add entry \"%s,%s\"\n",
+			bv.bv_val, ms->mss_ndn.bv_val, 0 );
+		return( -1 );
+	}
+	
+	*ep = e;
+	ep = &mp->mp_next;
+
+	/*
+	 * Uptime
+	 */
+	BER_BVSTR( &bv, "cn=Uptime" );
+	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
+		mi->mi_oc_monitoredObject, mi, NULL, NULL );
 	if ( e == NULL ) {
 		Debug( LDAP_DEBUG_ANY,
 			"monitor_subsys_time_init: "
-			"unable to create entry \"cn=Current,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
+			"unable to create entry \"%s,%s\"\n",
+			bv.bv_val, ms->mss_ndn.bv_val, 0 );
 		return( -1 );
 	}
+	BER_BVSTR( &value, "0" );
+	attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
+		&value, NULL );
 
 	mp = monitor_entrypriv_create();
 	if ( mp == NULL ) {
@@ -160,8 +165,8 @@
 	if ( monitor_cache_add( mi, e ) ) {
 		Debug( LDAP_DEBUG_ANY,
 			"monitor_subsys_time_init: "
-			"unable to add entry \"cn=Current,%s\"\n",
-			ms->mss_ndn.bv_val, 0, 0 );
+			"unable to add entry \"%s,%s\"\n",
+			bv.bv_val, ms->mss_ndn.bv_val, 0 );
 		return( -1 );
 	}
 	
@@ -180,7 +185,8 @@
 	Entry                   *e )
 {
 	monitor_info_t		*mi = ( monitor_info_t * )op->o_bd->be_private;
-	static struct berval	bv_current = BER_BVC( "cn=current" );
+	static struct berval	bv_current = BER_BVC( "cn=current" ),
+				bv_uptime = BER_BVC( "cn=uptime" );
 	struct berval		rdn;
 
 	assert( mi != NULL );
@@ -233,6 +239,29 @@
 		AC_MEMCPY( a->a_vals[ 0 ].bv_val, tmbuf, len );
 
 		/* FIXME: touch modifyTimestamp? */
+
+	} else if ( dn_match( &rdn, &bv_uptime ) ) {
+		Attribute	*a;
+		double		diff;
+		char		buf[ BACKMONITOR_BUFSIZE ];
+		struct berval	bv;
+
+		a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
+		if ( a == NULL ) {
+			return rs->sr_err = LDAP_OTHER;
+		}
+
+		diff = difftime( slap_get_time(), starttime );
+		bv.bv_len = snprintf( buf, sizeof( buf ), "%lu",
+			(unsigned long) diff );
+		bv.bv_val = buf;
+
+		ber_bvreplace( &a->a_vals[ 0 ], &bv );
+		if ( a->a_nvals != a->a_vals ) {
+			ber_bvreplace( &a->a_nvals[ 0 ], &bv );
+		}
+
+		/* FIXME: touch modifyTimestamp? */
 	}
 
 	return SLAP_CB_CONTINUE;

Modified: openldap/trunk/servers/slapd/back-null/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-null/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-null/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-null
-# $OpenLDAP: pkg/ldap/servers/slapd/back-null/Makefile.in,v 1.7.2.3 2007/01/02 21:44:05 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-null/Makefile.in,v 1.9.2.2 2007/08/31 23:14:04 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-null/null.c
===================================================================
--- openldap/trunk/servers/slapd/back-null/null.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-null/null.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* null.c - the null backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-null/null.c,v 1.12.2.5 2007/01/02 21:44:05 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-null/null.c,v 1.18.2.3 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2002-2007 The OpenLDAP Foundation.
@@ -24,6 +24,7 @@
 #include <ac/string.h>
 
 #include "slap.h"
+#include "config.h"
 
 struct null_info {
 	int	ni_bind_allowed;
@@ -38,7 +39,7 @@
 {
 	struct null_info *ni = (struct null_info *) op->o_bd->be_private;
 
-	if ( ni->ni_bind_allowed ) {
+	if ( ni->ni_bind_allowed || be_isroot_pw( op ) ) {
 		/* front end will send result on success (0) */
 		return LDAP_SUCCESS;
 	}
@@ -68,6 +69,20 @@
 }
 
 
+/* for overlays */
+int null_back_entry_get(
+	Operation *op,
+	struct berval *ndn,
+	ObjectClass *oc,
+	AttributeDescription *at,
+	int rw,
+	Entry **ent )
+{
+	*ent = NULL;
+	return 1;
+}
+
+
 /* Slap tools */
 
 static int
@@ -146,7 +161,7 @@
 }
 
 static int
-null_back_db_init( BackendDB *be )
+null_back_db_init( BackendDB *be, ConfigReply *cr )
 {
 	struct null_info *ni = ch_calloc( 1, sizeof(struct null_info) );
 	ni->ni_bind_allowed = 0;
@@ -156,7 +171,7 @@
 }
 
 static int
-null_back_db_destroy( Backend *be )
+null_back_db_destroy( Backend *be, ConfigReply *cr )
 {
 	free( be->be_private );
 	return 0;
@@ -194,6 +209,8 @@
 	bi->bi_connection_init = 0;
 	bi->bi_connection_destroy = 0;
 
+	bi->bi_entry_get_rw = null_back_entry_get;
+
 	bi->bi_tool_entry_open = null_tool_entry_open;
 	bi->bi_tool_entry_close = null_tool_entry_close;
 	bi->bi_tool_entry_first = null_tool_entry_next;

Modified: openldap/trunk/servers/slapd/back-passwd/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-passwd/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-passwd/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-passwd
-# $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/Makefile.in,v 1.18.2.3 2007/01/02 21:44:05 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/Makefile.in,v 1.20.2.2 2007/08/31 23:14:04 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-passwd/back-passwd.h
===================================================================
--- openldap/trunk/servers/slapd/back-passwd/back-passwd.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-passwd/back-passwd.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/back-passwd.h,v 1.5.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/back-passwd.h,v 1.7.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-passwd/config.c
===================================================================
--- openldap/trunk/servers/slapd/back-passwd/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-passwd/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* config.c - passwd backend configuration file routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/config.c,v 1.12.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/config.c,v 1.14.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-passwd/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-passwd/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-passwd/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* init.c - initialize passwd backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/init.c,v 1.29.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/init.c,v 1.32.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-passwd/proto-passwd.h
===================================================================
--- openldap/trunk/servers/slapd/back-passwd/proto-passwd.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-passwd/proto-passwd.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/proto-passwd.h,v 1.2.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/proto-passwd.h,v 1.5.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-passwd/search.c
===================================================================
--- openldap/trunk/servers/slapd/back-passwd/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-passwd/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* search.c - /etc/passwd backend search function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/search.c,v 1.70.2.7 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-passwd/search.c,v 1.79.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-perl/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-perl
-# $OpenLDAP: pkg/ldap/servers/slapd/back-perl/Makefile.in,v 1.18.2.3 2007/01/02 21:44:06 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-perl/Makefile.in,v 1.20.2.2 2007/08/31 23:14:04 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/SampleLDAP.pm
===================================================================
--- openldap/trunk/servers/slapd/back-perl/SampleLDAP.pm	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/SampleLDAP.pm	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # This is a sample Perl module for the OpenLDAP server slapd.
-# $OpenLDAP: pkg/ldap/servers/slapd/back-perl/SampleLDAP.pm,v 1.8.2.4 2007/06/18 13:31:06 hallvard Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-perl/SampleLDAP.pm,v 1.10.2.2 2007/08/31 23:14:04 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -24,149 +24,145 @@
 # See the slapd-perl(5) manual page for details.
 
 package SampleLDAP;
-
+use strict;
+use warnings;
 use POSIX;
 
-sub new
-{
-	my $class = shift;
+$SampleLDAP::VERSION = '1.01';
 
-	my $this = {};
-	bless $this, $class;
-        print STDERR "Here in new\n";
-	print STDERR "Posix Var " . BUFSIZ . " and " . FILENAME_MAX . "\n";
-	return $this;
+sub new {
+    my $class = shift;
+
+    my $this = {};
+    bless $this, $class;
+    print {*STDERR} "Here in new\n";
+    print {*STDERR} 'Posix Var ' . BUFSIZ . ' and ' . FILENAME_MAX . "\n";
+    return $this;
 }
 
-sub init
-{
-	return 0;
+sub init {
+    return 0;
 }
 
-sub search
-{
-	my $this = shift;
-	my($base, $scope, $deref, $sizeLim, $timeLim, $filterStr, $attrOnly, @attrs ) = @_;
-        print STDERR "====$filterStr====\n";
-	$filterStr =~ s/\(|\)//g;
-	$filterStr =~ s/=/: /;
+sub search {
+    my $this = shift;
+    my ( $base, $scope, $deref, $sizeLim, $timeLim, $filterStr, $attrOnly,
+        @attrs )
+      = @_;
+    print {*STDERR}, "====$filterStr====\n";
+    $filterStr =~ s/\(|\)//gm;
+    $filterStr =~ s/=/: /m;
 
-	my @match_dn = ();
-	foreach my $dn ( keys %$this ) {
-		if ( $this->{ $dn } =~ /$filterStr/im ) {
-			push @match_dn, $dn;
-			last if ( scalar @match_dn == $sizeLim );
+    my @match_dn = ();
+    for my $dn ( keys %{$this} ) {
+        if ( $this->{$dn} =~ /$filterStr/imx ) {
+            push @match_dn, $dn;
+            last if ( scalar @match_dn == $sizeLim );
 
-		}
-	}
+        }
+    }
 
-	my @match_entries = ();
-	
-	foreach my $dn ( @match_dn )  {
-		push @match_entries, $this->{ $dn };
-	}
+    my @match_entries = ();
 
-	return ( 0 , @match_entries );
+    for my $dn (@match_dn) {
+        push @match_entries, $this->{$dn};
+    }
 
+    return ( 0, @match_entries );
+
 }
 
-sub compare
-{
-	my $this = shift;
-	my ( $dn, $avaStr ) = @_;
-	my $rc = 5; # LDAP_COMPARE_FALSE
+sub compare {
+    my $this = shift;
+    my ( $dn, $avaStr ) = @_;
+    my $rc = 5;    # LDAP_COMPARE_FALSE
 
-	$avaStr =~ s/=/: /;
+    $avaStr =~ s/=/: /m;
 
-	if ( $this->{ $dn } =~ /$avaStr/im ) {
-		$rc = 6; # LDAP_COMPARE_TRUE
-	}
+    if ( $this->{$dn} =~ /$avaStr/im ) {
+        $rc = 6;    # LDAP_COMPARE_TRUE
+    }
 
-	return $rc;
+    return $rc;
 }
 
-sub modify
-{
-	my $this = shift;
+sub modify {
+    my $this = shift;
 
-	my ( $dn, @list ) = @_;
+    my ( $dn, @list ) = @_;
 
-	while ( @list > 0 ) {
-		my $action = shift @list;
-		my $key    = shift @list;
-		my $value  = shift @list;
+    while ( @list > 0 ) {
+        my $action = shift @list;
+        my $key    = shift @list;
+        my $value  = shift @list;
 
-		if( $action eq "ADD" ) {
-			$this->{ $dn } .= "$key: $value\n";
+        if ( $action eq 'ADD' ) {
+            $this->{$dn} .= "$key: $value\n";
 
-		}
-		elsif( $action eq "DELETE" ) {
-			$this->{ $dn } =~ s/^$key:\s*$value\n//mi ;
+        }
+        elsif ( $action eq 'DELETE' ) {
+            $this->{$dn} =~ s/^$key:\s*$value\n//im;
 
-		}
-		elsif( $action eq "REPLACE" ) {
-			$this->{ $dn } =~ s/$key: .*$/$key: $value/im ;
-		}
-	}
+        }
+        elsif ( $action eq 'REPLACE' ) {
+            $this->{$dn} =~ s/$key: .*$/$key: $value/im;
+        }
+    }
 
-	return 0;
+    return 0;
 }
 
-sub add
-{
-	my $this = shift;
+sub add {
+    my $this = shift;
 
-	my ( $entryStr ) = @_;
+    my ($entryStr) = @_;
 
-	my ( $dn ) = ( $entryStr =~ /dn:\s(.*)$/m );
+    my ($dn) = ( $entryStr =~ /dn:\s(.*)$/m );
 
-	#
-	# This needs to be here until a normalized dn is
-	# passed to this routine.
-	#
-	$dn = uc( $dn );
-	$dn =~ s/\s*//g;
+    #
+    # This needs to be here until a normalized dn is
+    # passed to this routine.
+    #
+    $dn = uc $dn;
+    $dn =~ s/\s*//gm;
 
+    $this->{$dn} = $entryStr;
 
-	$this->{$dn} = $entryStr;
-
-	return 0;
+    return 0;
 }
 
-sub modrdn
-{
-	my $this = shift;
+sub modrdn {
+    my $this = shift;
 
-	my ( $dn, $newdn, $delFlag ) = @_;
+    my ( $dn, $newdn, $delFlag ) = @_;
 
-	$this->{ $newdn } = $this->{ $dn };
+    $this->{$newdn} = $this->{$dn};
 
-	if( $delFlag ) {
-		delete $this->{ $dn };
-	}
-	return 0;
+    if ($delFlag) {
+        delete $this->{$dn};
+    }
+    return 0;
 
 }
 
-sub delete
-{
-	my $this = shift;
+sub delete {
+    my $this = shift;
 
-	my ( $dn ) = @_;
-	
-        print STDERR "XXXXXX $dn XXXXXXX\n";
-	delete $this->{$dn};
+    my ($dn) = @_;
+
+    print {*STDERR} "XXXXXX $dn XXXXXXX\n";
+    delete $this->{$dn};
+    return 0;
 }
 
-sub config
-{
-	my $this = shift;
+sub config {
+    my $this = shift;
 
-	my ( @args ) = @_;
-        local $, = " - ";
-        print STDERR @args;
-        print STDERR "\n";
-	return 0;
+    my (@args) = @_;
+    local $, = ' - ';
+    print {*STDERR} @args;
+    print {*STDERR} "\n";
+    return 0;
 }
 
 1;

Modified: openldap/trunk/servers/slapd/back-perl/add.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/add.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/add.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/add.c,v 1.18.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/add.c,v 1.20.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/asperl_undefs.h
===================================================================
--- openldap/trunk/servers/slapd/back-perl/asperl_undefs.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/asperl_undefs.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/asperl_undefs.h,v 1.5.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/asperl_undefs.h,v 1.7.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/bind.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/bind.c,v 1.22.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/bind.c,v 1.24.2.3 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -32,6 +32,16 @@
 
 	PerlBackend *perl_back = (PerlBackend *) op->o_bd->be_private;
 
+	/* allow rootdn as a means to auth without the need to actually
+ 	 * contact the proxied DSA */
+	switch ( be_rootdn_bind( op, rs ) ) {
+	case SLAP_CB_CONTINUE:
+		break;
+
+	default:
+		return rs->sr_err;
+	}
+
 #if defined(HAVE_WIN32_ASPERL) || defined(USE_ITHREADS)
 	PERL_SET_CONTEXT( PERL_INTERPRETER );
 #endif

Modified: openldap/trunk/servers/slapd/back-perl/close.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/close.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/close.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/close.c,v 1.14.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/close.c,v 1.17.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -16,7 +16,7 @@
  */
 
 #include "perl_back.h"
-
+#include "../config.h"
 /**********************************************************
  *
  * Close
@@ -39,7 +39,8 @@
 
 int
 perl_back_db_destroy(
-	BackendDB *be
+	BackendDB *be,
+	ConfigReply *cr
 )
 {
 	free( be->be_private );

Modified: openldap/trunk/servers/slapd/back-perl/compare.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/compare.c,v 1.23.2.5 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/compare.c,v 1.26.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/config.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/config.c,v 1.20.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/config.c,v 1.22.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/delete.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/delete.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/delete.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/delete.c,v 1.18.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/delete.c,v 1.20.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/init.c,v 1.40.2.5 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/init.c,v 1.44.2.3 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -16,6 +16,7 @@
  */
 
 #include "perl_back.h"
+#include "../config.h"
 
 static void perl_back_xs_init LDAP_P((PERL_BACK_XS_INIT_PARAMS));
 EXT void boot_DynaLoader LDAP_P((PERL_BACK_BOOT_DYNALOADER_PARAMS));
@@ -85,7 +86,8 @@
 
 int
 perl_back_db_init(
-	BackendDB	*be
+	BackendDB	*be,
+	ConfigReply	*cr
 )
 {
 	be->be_private = (PerlBackend *) ch_malloc( sizeof(PerlBackend) );
@@ -100,7 +102,8 @@
 
 int
 perl_back_db_open(
-	BackendDB	*be
+	BackendDB	*be,
+	ConfigReply	*cr
 )
 {
 	int count;

Modified: openldap/trunk/servers/slapd/back-perl/modify.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/modify.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/modify.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/modify.c,v 1.21.2.5 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/modify.c,v 1.23.2.3 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/modrdn.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/modrdn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/modrdn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/modrdn.c,v 1.20.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/modrdn.c,v 1.22.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/perl_back.h
===================================================================
--- openldap/trunk/servers/slapd/back-perl/perl_back.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/perl_back.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/perl_back.h,v 1.13.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/perl_back.h,v 1.15.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/proto-perl.h
===================================================================
--- openldap/trunk/servers/slapd/back-perl/proto-perl.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/proto-perl.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/proto-perl.h,v 1.2.2.5 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/proto-perl.h,v 1.5.2.3 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-perl/search.c
===================================================================
--- openldap/trunk/servers/slapd/back-perl/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-perl/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/search.c,v 1.25.2.5 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-perl/search.c,v 1.31.2.2 2007/08/31 23:14:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-relay/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-relay/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-relay/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,5 @@
 # Makefile.in for back-relay
+# $OpenLDAP: pkg/ldap/servers/slapd/back-relay/Makefile.in,v 1.5.2.2 2007/08/31 23:14:04 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.
@@ -12,8 +13,8 @@
 ## top-level directory of the distribution or, alternatively, at
 ## <http://www.OpenLDAP.org/license.html>.
 
-SRCS	= init.c config.c op.c
-OBJS	= init.lo config.lo op.lo
+SRCS	= init.c op.c
+OBJS	= init.lo op.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries

Deleted: openldap/trunk/servers/slapd/back-relay/config.c
===================================================================
--- openldap/trunk/servers/slapd/back-relay/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-relay/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,181 +0,0 @@
-/* config.c - relay backend configuration file routine */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2004-2007 The OpenLDAP Foundation.
- * Portions Copyright 2004 Pierangelo Masarati.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was initially developed by Pierangelo Masaratifor inclusion
- * in OpenLDAP Software.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "slap.h"
-#include "back-relay.h"
-
-int
-relay_back_db_config(
-	BackendDB	*be,
-	const char	*fname,
-	int		lineno,
-	int		argc,
-	char		**argv
-)
-{
-	relay_back_info *ri = (struct relay_back_info *)be->be_private;
-
-	if ( ri == NULL ) {
-		fprintf( stderr, "%s: line %d: relay backend info is null!\n",
-		    fname, lineno );
-		return 1;
-	}
-
-	/* real naming context */
-	if ( strcasecmp( argv[0], "relay" ) == 0 ) {
-		struct berval	dn, ndn, pdn;
-		int		rc;
-		BackendDB	*bd;
-
-		if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: "
-				"relay dn already specified.\n",
-				fname, lineno, 0 );
-			return 1;
-		}
-
-		switch ( argc ) {
-		case 3:
-			if ( strcmp( argv[ 2 ], "massage" ) != 0 ) {
-				Debug( LDAP_DEBUG_ANY,
-					"%s: line %d: "
-					"unknown arg[#2]=\"%s\" "
-					"in \"relay <dn> [massage]\" line\n",
-					fname, lineno, argv[ 2 ] );
-				return 1;
-			}
-
-			if ( be->be_nsuffix == NULL ) {
-				Debug( LDAP_DEBUG_ANY,
-					"%s: line %d: "
-					"\"relay\" directive "
-					"must appear after \"suffix\".\n",
-					fname, lineno, 0 );
-				return 1;
-			}
-
-			if ( !BER_BVISNULL( &be->be_nsuffix[ 1 ] ) ) {
-				Debug( LDAP_DEBUG_ANY,
-					"%s: line %d: "
-					"relaying of multiple suffix "
-					"database not supported.\n",
-					fname, lineno, 0 );
-				return 1;
-			}
-			/* fallthru */
-
-		case 2:
-			break;
-
-		case 1:
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: missing relay suffix "
-				"in \"relay <dn> [massage]\" line.\n",
-				fname, lineno, 0 );
-			return 1;
-
-		default:
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: extra cruft "
-				"in \"relay <dn> [massage]\" line.\n",
-				fname, lineno, 0 );
-			return 1;
-		}
-
-		/* The man page says that the "relay" directive
-		 * automatically instantiates slapo-rwm; I don't
-		 * like this very much any more, I'd prefer to
-		 * have automatic instantiation only when "massage"
-		 * is specified, so one has better control on
-		 * where the overlay gets instantiated, but this
-		 * would break compatibility.  One can still control
-		 * where the overlay is instantiated by moving
-		 * around the "relay" directive, although this could
-		 * make slapd.conf a bit confusing. */
-		if ( overlay_config( be, "rwm" ) ) {
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: unable to install "
-				"rwm overlay "
-				"in \"relay <dn> [massage]\" line\n",
-				fname, lineno, 0 );
-			return 1;
-		}
-
-		dn.bv_val = argv[ 1 ];
-		dn.bv_len = strlen( argv[ 1 ] );
-		rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL );
-		if ( rc != LDAP_SUCCESS ) {
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: "
-				"relay dn \"%s\" is invalid "
-				"in \"relay <dn> [massage]\" line\n",
-				fname, lineno, argv[ 1 ] );
-			return 1;
-		}
-
-		bd = select_backend( &ndn, 0, 1 );
-		if ( bd == NULL ) {
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: "
-				"cannot find database "
-				"of relay dn \"%s\" "
-				"in \"relay <dn> [massage]\" line\n",
-				fname, lineno, argv[ 1 ] );
-			rc = 1;
-			goto relay_done;
-
-		} else if ( bd->be_private == be->be_private ) {
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: "
-				"relay dn \"%s\" would call self "
-				"in \"relay <dn> [massage]\" line\n",
-				fname, lineno, pdn.bv_val );
-			rc = 1;
-			goto relay_done;
-		}
-
-		ri->ri_realsuffix = ndn;
-
-		if ( argc == 3 ) {
-			char	*cargv[ 4 ];
-
-			cargv[ 0 ] = "rwm-suffixmassage";
-			cargv[ 1 ] = be->be_suffix[0].bv_val;
-			cargv[ 2 ] = pdn.bv_val;
-			cargv[ 3 ] = NULL;
-
-			rc = be->be_config( be, fname, lineno, 3, cargv );
-		}
-
-relay_done:;
-		ch_free( pdn.bv_val );
-
-		return rc;
-	}
-
-	/* anything else */
-	return SLAP_CONF_UNKNOWN;
-}
-

Modified: openldap/trunk/servers/slapd/back-relay/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-relay/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-relay/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -24,8 +24,116 @@
 #include <ac/string.h>
 
 #include "slap.h"
+#include "config.h"
 #include "back-relay.h"
 
+static ConfigDriver relay_back_cf;
+
+static ConfigTable relaycfg[] = {
+	{ "relay", "relay", 2, 2, 0,
+		ARG_MAGIC|ARG_DN,
+		relay_back_cf, "( OLcfgDbAt:5.1 "
+			"NAME 'olcRelay' "
+			"DESC 'Relay DN' "
+			"SYNTAX OMsDN "
+			"SINGLE-VALUE )",
+		NULL, NULL },
+	{ NULL }
+};
+
+static ConfigOCs relayocs[] = {
+	{ "( OLcfgDbOc:5.1 "
+		"NAME 'olcRelayConfig' "
+		"DESC 'Relay backend configuration' "
+		"SUP olcDatabaseConfig "
+		"MAY ( olcRelay "
+		") )",
+		 	Cft_Database, relaycfg},
+	{ NULL, 0, NULL }
+};
+
+static int
+relay_back_cf( ConfigArgs *c )
+{
+	relay_back_info	*ri = ( relay_back_info * )c->be->be_private;
+	int		rc = 0;
+
+	if ( c->op == SLAP_CONFIG_EMIT ) {
+		if ( ri != NULL && !BER_BVISNULL( &ri->ri_realsuffix ) ) {
+			value_add_one( &c->rvalue_vals, &ri->ri_realsuffix );
+			return 0;
+		}
+		return 1;
+
+	} else if ( c->op == LDAP_MOD_DELETE ) {
+		if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
+			ch_free( ri->ri_realsuffix.bv_val );
+			BER_BVZERO( &ri->ri_realsuffix );
+			ri->ri_bd = NULL;
+			return 0;
+		}
+		return 1;
+
+	} else {
+		BackendDB *bd;
+
+		assert( ri != NULL );
+		assert( BER_BVISNULL( &ri->ri_realsuffix ) );
+
+		if ( c->be->be_nsuffix == NULL ) {
+			snprintf( c->cr_msg, sizeof( c->cr_msg),
+				"\"relay\" directive "
+				"must appear after \"suffix\"" );
+			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
+				"%s: %s.\n", c->log, c->cr_msg );
+			rc = 1;
+			goto relay_done;
+		}
+
+		if ( !BER_BVISNULL( &c->be->be_nsuffix[ 1 ] ) ) {
+			snprintf( c->cr_msg, sizeof( c->cr_msg),
+				"relaying of multiple suffix "
+				"database not supported" );
+			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
+				"%s: %s.\n", c->log, c->cr_msg );
+			rc = 1;
+			goto relay_done;
+		}
+
+		bd = select_backend( &c->value_ndn, 1 );
+		if ( bd == NULL ) {
+			snprintf( c->cr_msg, sizeof( c->cr_msg),
+				"cannot find database "
+				"of relay dn \"%s\" "
+				"in \"olcRelay <dn>\"\n",
+				c->value_dn.bv_val );
+			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
+				"%s: %s.\n", c->log, c->cr_msg );
+			rc = 1;
+			goto relay_done;
+
+		} else if ( bd->be_private == c->be->be_private ) {
+			snprintf( c->cr_msg, sizeof( c->cr_msg),
+				"relay dn \"%s\" would call self "
+				"in \"relay <dn>\" line\n",
+				c->value_dn.bv_val );
+			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
+				"%s: %s.\n", c->log, c->cr_msg );
+			rc = 1;
+			goto relay_done;
+		}
+
+		ri->ri_realsuffix = c->value_ndn;
+		BER_BVZERO( &c->value_ndn );
+
+relay_done:;
+		ch_free( c->value_dn.bv_val );
+		ch_free( c->value_ndn.bv_val );
+	}
+
+	return rc;
+}
+
 int
 relay_back_initialize( BackendInfo *bi )
 {
@@ -36,10 +144,10 @@
 	bi->bi_destroy = 0;
 
 	bi->bi_db_init = relay_back_db_init;
-	bi->bi_db_config = relay_back_db_config;
+	bi->bi_db_config = config_generic_wrapper;
 	bi->bi_db_open = relay_back_db_open;
 #if 0
-	bi->bi_db_close =relay_back_db_close;
+	bi->bi_db_close = relay_back_db_close;
 #endif
 	bi->bi_db_destroy = relay_back_db_destroy;
 
@@ -65,11 +173,13 @@
 	bi->bi_connection_init = relay_back_connection_init;
 	bi->bi_connection_destroy = relay_back_connection_destroy;
 
-	return 0;
+	bi->bi_cf_ocs = relayocs;
+
+	return config_register_schema( relaycfg, relayocs );
 }
 
 int
-relay_back_db_init( Backend *be )
+relay_back_db_init( Backend *be, ConfigReply *cr)
 {
 	relay_back_info		*ri;
 
@@ -84,20 +194,22 @@
 	BER_BVZERO( &ri->ri_realsuffix );
 	ri->ri_massage = 0;
 
+	be->be_cf_ocs = be->bd_info->bi_cf_ocs;
+
 	be->be_private = (void *)ri;
 
 	return 0;
 }
 
 int
-relay_back_db_open( Backend *be )
+relay_back_db_open( Backend *be, ConfigReply *cr )
 {
 	relay_back_info		*ri = (relay_back_info *)be->be_private;
 
 	assert( ri != NULL );
 
 	if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
-		ri->ri_bd = select_backend( &ri->ri_realsuffix, 0, 1 );
+		ri->ri_bd = select_backend( &ri->ri_realsuffix, 1 );
 
 		/* must be there: it was during config! */
 		assert( ri->ri_bd != NULL );
@@ -114,13 +226,13 @@
 }
 
 int
-relay_back_db_close( Backend *be )
+relay_back_db_close( Backend *be, ConfigReply *cr )
 {
 	return 0;
 }
 
 int
-relay_back_db_destroy( Backend *be )
+relay_back_db_destroy( Backend *be, ConfigReply *cr)
 {
 	relay_back_info		*ri = (relay_back_info *)be->be_private;
 

Modified: openldap/trunk/servers/slapd/back-relay/op.c
===================================================================
--- openldap/trunk/servers/slapd/back-relay/op.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-relay/op.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -26,7 +26,7 @@
 #include "back-relay.h"
 
 static int
-relay_back_swap_bd( struct slap_op *op, struct slap_rep *rs )
+relay_back_swap_bd( Operation *op, SlapReply *rs )
 {
 	slap_callback	*cb = op->o_callback;
 	BackendDB	*be = op->o_bd;
@@ -38,7 +38,7 @@
 }
 
 static void
-relay_back_add_cb( slap_callback *cb, struct slap_op *op )
+relay_back_add_cb( slap_callback *cb, Operation *op )
 {
 	cb->sc_next = op->o_callback;
 	cb->sc_response = relay_back_swap_bd;
@@ -55,15 +55,15 @@
  *	any valid error 	send as error result
  */
 static BackendDB *
-relay_back_select_backend( struct slap_op *op, struct slap_rep *rs, int err )
+relay_back_select_backend( Operation *op, SlapReply *rs, int err, int dosend )
 {
 	relay_back_info		*ri = (relay_back_info *)op->o_bd->be_private;
 	BackendDB		*bd = ri->ri_bd;
 
 	if ( bd == NULL && !BER_BVISNULL( &op->o_req_ndn ) ) {
-		bd = select_backend( &op->o_req_ndn, 0, 1 );
+		bd = select_backend( &op->o_req_ndn, 1 );
 		if ( bd == op->o_bd ) {
-			if ( err > LDAP_SUCCESS ) {
+			if ( err > LDAP_SUCCESS && dosend ) {
 				send_ldap_error( op, rs,
 						LDAP_UNWILLING_TO_PERFORM, 
 						"back-relay would call self" );
@@ -74,17 +74,21 @@
 
 	if ( bd == NULL && err > -1 ) {
 		if ( default_referral ) {
-			rs->sr_ref = referral_rewrite( default_referral,
-				NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
-			if ( !rs->sr_ref ) {
-				rs->sr_ref = default_referral;
-			}
-
 			rs->sr_err = LDAP_REFERRAL;
-			send_ldap_result( op, rs );
+			if ( dosend ) {
+				rs->sr_ref = referral_rewrite(
+					default_referral,
+					NULL, &op->o_req_dn,
+					LDAP_SCOPE_DEFAULT );
+				if ( !rs->sr_ref ) {
+					rs->sr_ref = default_referral;
+				}
 
-			if ( rs->sr_ref != default_referral ) {
-				ber_bvarray_free( rs->sr_ref );
+				send_ldap_result( op, rs );
+
+				if ( rs->sr_ref != default_referral ) {
+					ber_bvarray_free( rs->sr_ref );
+				}
 			}
 
 		} else {
@@ -92,7 +96,9 @@
 			 * LDAP_NO_SUCH_OBJECT for other operations.
 			 * noSuchObject cannot be returned by bind */
 			rs->sr_err = err;
-			send_ldap_result( op, rs );
+			if ( dosend ) {
+				send_ldap_result( op, rs );
+			}
 		}
 	}
 
@@ -100,12 +106,22 @@
 }
 
 int
-relay_back_op_bind( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_bind( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, LDAP_INVALID_CREDENTIALS );
+	/* allow rootdn as a means to auth without the need to actually
+ 	 * contact the proxied DSA */
+	switch ( be_rootdn_bind( op, rs ) ) {
+	case SLAP_CB_CONTINUE:
+		break;
+
+	default:
+		return rs->sr_err;
+	}
+
+	bd = relay_back_select_backend( op, rs, LDAP_INVALID_CREDENTIALS, 1 );
 	if ( bd == NULL ) {
 		return rc;
 	}
@@ -117,7 +133,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_bind )( op, rs );
+		rc = bd->be_bind( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -134,15 +150,14 @@
 }
 
 int
-relay_back_op_unbind( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_unbind( Operation *op, SlapReply *rs )
 {
-	relay_back_info		*ri = (relay_back_info *)op->o_bd->be_private;
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, -1 );
+	bd = relay_back_select_backend( op, rs, LDAP_SUCCESS, 0 );
 	if ( bd == NULL ) {
-		return rc;
+		return 1;
 	}
 
 	if ( bd && bd->be_unbind ) {
@@ -152,7 +167,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_unbind )( op, rs );
+		rc = bd->be_unbind( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -165,12 +180,12 @@
 }
 
 int
-relay_back_op_search( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_search( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
+	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT, 1 );
 	if ( bd == NULL ) {
 		return 1;
 	}
@@ -182,7 +197,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_search )( op, rs );
+		rc = bd->be_search( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -200,12 +215,12 @@
 }
 
 int
-relay_back_op_compare( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_compare( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
+	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT, 1 );
 	if ( bd == NULL ) {
 		return 1;
 	}
@@ -217,7 +232,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_compare )( op, rs );
+		rc = bd->be_compare( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -235,12 +250,12 @@
 }
 
 int
-relay_back_op_modify( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_modify( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
+	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT, 1 );
 	if ( bd == NULL ) {
 		return 1;
 	}
@@ -252,7 +267,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_modify )( op, rs );
+		rc = bd->be_modify( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -270,12 +285,12 @@
 }
 
 int
-relay_back_op_modrdn( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_modrdn( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
+	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT, 1 );
 	if ( bd == NULL ) {
 		return 1;
 	}
@@ -287,7 +302,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_modrdn )( op, rs );
+		rc = bd->be_modrdn( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -305,12 +320,12 @@
 }
 
 int
-relay_back_op_add( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_add( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
+	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT, 1 );
 	if ( bd == NULL ) {
 		return 1;
 	}
@@ -322,7 +337,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_add )( op, rs );
+		rc = bd->be_add( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -340,12 +355,12 @@
 }
 
 int
-relay_back_op_delete( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_delete( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
+	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT, 1 );
 	if ( bd == NULL ) {
 		return 1;
 	}
@@ -357,7 +372,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_delete )( op, rs );
+		rc = bd->be_delete( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -370,12 +385,12 @@
 }
 
 int
-relay_back_op_abandon( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_abandon( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, -1 );
+	bd = relay_back_select_backend( op, rs, LDAP_SUCCESS, 0 );
 	if ( bd == NULL ) {
 		return 1;
 	}
@@ -387,7 +402,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_abandon )( op, rs );
+		rc = bd->be_abandon( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -400,12 +415,12 @@
 }
 
 int
-relay_back_op_cancel( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_cancel( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, LDAP_CANNOT_CANCEL );
+	bd = relay_back_select_backend( op, rs, LDAP_CANNOT_CANCEL, 0 );
 	if ( bd == NULL ) {
 		return 1;
 	}
@@ -417,7 +432,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_cancel )( op, rs );
+		rc = bd->be_cancel( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -435,12 +450,12 @@
 }
 
 int
-relay_back_op_extended( struct slap_op *op, struct slap_rep *rs )
+relay_back_op_extended( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );
+	bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT, 0 );
 	if ( bd == NULL ) {
 		return 1;
 	}
@@ -452,7 +467,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_extended )( op, rs );
+		rc = bd->be_extended( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -470,7 +485,7 @@
 }
 
 int
-relay_back_entry_release_rw( struct slap_op *op, Entry *e, int rw )
+relay_back_entry_release_rw( Operation *op, Entry *e, int rw )
 {
 	relay_back_info		*ri = (relay_back_info *)op->o_bd->be_private;
 	BackendDB		*bd;
@@ -478,7 +493,7 @@
 
 	bd = ri->ri_bd;
 	if ( bd == NULL) {
-		bd = select_backend( &op->o_req_ndn, 0, 1 );
+		bd = select_backend( &op->o_req_ndn, 1 );
 		if ( bd == NULL ) {
 			return 1;
 		}
@@ -488,7 +503,7 @@
 		BackendDB	*be = op->o_bd;
 
 		op->o_bd = bd;
-		rc = ( bd->be_release )( op, e, rw );
+		rc = bd->be_release( op, e, rw );
 		op->o_bd = be;
 	}
 
@@ -497,7 +512,7 @@
 }
 
 int
-relay_back_entry_get_rw( struct slap_op *op, struct berval *ndn,
+relay_back_entry_get_rw( Operation *op, struct berval *ndn,
 	ObjectClass *oc, AttributeDescription *at, int rw, Entry **e )
 {
 	relay_back_info		*ri = (relay_back_info *)op->o_bd->be_private;
@@ -506,7 +521,7 @@
 
 	bd = ri->ri_bd;
 	if ( bd == NULL) {
-		bd = select_backend( &op->o_req_ndn, 0, 1 );
+		bd = select_backend( &op->o_req_ndn, 1 );
 		if ( bd == NULL ) {
 			return 1;
 		}
@@ -516,7 +531,7 @@
 		BackendDB	*be = op->o_bd;
 
 		op->o_bd = bd;
-		rc = ( bd->be_fetch )( op, ndn, oc, at, rw, e );
+		rc = bd->be_fetch( op, ndn, oc, at, rw, e );
 		op->o_bd = be;
 	}
 
@@ -532,12 +547,12 @@
  * naming context... mmmh.
  */
 int
-relay_back_chk_referrals( struct slap_op *op, struct slap_rep *rs )
+relay_back_chk_referrals( Operation *op, SlapReply *rs )
 {
 	BackendDB		*bd;
 	int			rc = 0;
 
-	bd = relay_back_select_backend( op, rs, LDAP_SUCCESS );
+	bd = relay_back_select_backend( op, rs, LDAP_SUCCESS, 1 );
 	/* FIXME: this test only works if there are no overlays, so
 	 * it is nearly useless; if made stricter, no nested back-relays
 	 * can be instantiated... too bad. */
@@ -561,7 +576,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_chk_referrals )( op, rs );
+		rc = bd->be_chk_referrals( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -574,18 +589,17 @@
 }
 
 int
-relay_back_operational( struct slap_op *op, struct slap_rep *rs )
+relay_back_operational( Operation *op, SlapReply *rs )
 {
-	relay_back_info		*ri = (relay_back_info *)op->o_bd->be_private;
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = ri->ri_bd;
-	if ( bd == NULL) {
-		bd = select_backend( &op->o_req_ndn, 0, 1 );
-		if ( bd == NULL ) {
-			return 1;
-		}
+	bd = relay_back_select_backend( op, rs, LDAP_SUCCESS, 0 );
+	/* FIXME: this test only works if there are no overlays, so
+	 * it is nearly useless; if made stricter, no nested back-relays
+	 * can be instantiated... too bad. */
+	if ( bd == NULL || bd == op->o_bd ) {
+		return 0;
 	}
 
 	if ( bd->be_operational ) {
@@ -595,7 +609,7 @@
 		relay_back_add_cb( &cb, op );
 
 		op->o_bd = bd;
-		rc = ( bd->be_operational )( op, rs );
+		rc = bd->be_operational( op, rs );
 		op->o_bd = be;
 
 		if ( op->o_callback == &cb ) {
@@ -608,25 +622,25 @@
 }
 
 int
-relay_back_has_subordinates( struct slap_op *op, Entry *e, int *hasSubs )
+relay_back_has_subordinates( Operation *op, Entry *e, int *hasSubs )
 {
-	relay_back_info		*ri = (relay_back_info *)op->o_bd->be_private;
+	SlapReply		rs = { 0 };
 	BackendDB		*bd;
 	int			rc = 1;
 
-	bd = ri->ri_bd;
-	if ( bd == NULL) {
-		bd = select_backend( &op->o_req_ndn, 0, 1 );
-		if ( bd == NULL ) {
-			return 1;
-		}
+	bd = relay_back_select_backend( op, &rs, LDAP_SUCCESS, 0 );
+	/* FIXME: this test only works if there are no overlays, so
+	 * it is nearly useless; if made stricter, no nested back-relays
+	 * can be instantiated... too bad. */
+	if ( bd == NULL || bd == op->o_bd ) {
+		return 0;
 	}
 
 	if ( bd->be_has_subordinates ) {
 		BackendDB	*be = op->o_bd;
 
 		op->o_bd = bd;
-		rc = ( bd->be_has_subordinates )( op, e, hasSubs );
+		rc = bd->be_has_subordinates( op, e, hasSubs );
 		op->o_bd = be;
 	}
 
@@ -635,7 +649,7 @@
 }
 
 int
-relay_back_connection_init( BackendDB *bd, struct slap_conn *c )
+relay_back_connection_init( BackendDB *bd, Connection *c )
 {
 	relay_back_info		*ri = (relay_back_info *)bd->be_private;
 
@@ -645,24 +659,24 @@
 	}
 
 	if ( bd->be_connection_init ) {
-		return ( bd->be_connection_init )( bd, c );
+		return bd->be_connection_init( bd, c );
 	}
 
 	return 0;
 }
 
 int
-relay_back_connection_destroy( BackendDB *bd, struct slap_conn *c )
+relay_back_connection_destroy( BackendDB *bd, Connection *c )
 {
 	relay_back_info		*ri = (relay_back_info *)bd->be_private;
 
 	bd = ri->ri_bd;
-	if ( bd == NULL) {
+	if ( bd == NULL ) {
 		return 0;
 	}
 
 	if ( bd->be_connection_destroy ) {
-		return ( bd->be_connection_destroy )( bd, c );
+		return bd->be_connection_destroy( bd, c );
 	}
 
 	return 0;

Modified: openldap/trunk/servers/slapd/back-relay/proto-back-relay.h
===================================================================
--- openldap/trunk/servers/slapd/back-relay/proto-back-relay.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-relay/proto-back-relay.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -27,7 +27,6 @@
 extern BI_init			relay_back_initialize;
 
 extern BI_db_init		relay_back_db_init;
-extern BI_db_config		relay_back_db_config;
 extern BI_db_open		relay_back_db_open;
 extern BI_db_close		relay_back_db_close;
 extern BI_db_destroy		relay_back_db_destroy;

Modified: openldap/trunk/servers/slapd/back-shell/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-shell/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-shell
-# $OpenLDAP: pkg/ldap/servers/slapd/back-shell/Makefile.in,v 1.20.2.3 2007/01/02 21:44:06 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-shell/Makefile.in,v 1.22.2.2 2007/08/31 23:14:05 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/add.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/add.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/add.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* add.c - shell backend add function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/add.c,v 1.24.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/add.c,v 1.27.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/bind.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* bind.c - shell backend bind function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/bind.c,v 1.25.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/bind.c,v 1.27.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -49,6 +49,16 @@
 	FILE			*rfp, *wfp;
 	int			rc;
 
+	/* allow rootdn as a means to auth without the need to actually
+ 	 * contact the proxied DSA */
+	switch ( be_rootdn_bind( op, rs ) ) {
+	case SLAP_CB_CONTINUE:
+		break;
+
+	default:
+		return rs->sr_err;
+	}
+
 	if ( si->si_bind == NULL ) {
 		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
 		    "bind not implemented" );

Modified: openldap/trunk/servers/slapd/back-shell/compare.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* compare.c - shell backend compare function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/compare.c,v 1.26.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/compare.c,v 1.28.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/config.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* config.c - shell backend configuration file routine */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/config.c,v 1.16.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/config.c,v 1.18.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/delete.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/delete.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/delete.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* delete.c - shell backend delete function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/delete.c,v 1.23.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/delete.c,v 1.26.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/fork.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/fork.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/fork.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* fork.c - fork and exec a process, connecting stdin/out w/pipes */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/fork.c,v 1.15.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/fork.c,v 1.18.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -103,7 +103,12 @@
 	if ( (*rfp = fdopen( c2p[0], "r" )) == NULL || (*wfp = fdopen( p2c[1],
 	    "w" )) == NULL ) {
 		Debug( LDAP_DEBUG_ANY, "fdopen failed\n", 0, 0, 0 );
-		close( c2p[0] );
+		if ( *rfp ) {
+			fclose( *rfp );
+			*rfp = NULL;
+		} else {
+			close( c2p[0] );
+		}
 		close( p2c[1] );
 
 		return( -1 );

Modified: openldap/trunk/servers/slapd/back-shell/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* init.c - initialize shell backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/init.c,v 1.35.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/init.c,v 1.37.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -36,6 +36,8 @@
 
 #include "slap.h"
 
+#include "config.h"
+
 #include "shell.h"
 
 int
@@ -76,7 +78,8 @@
 
 int
 shell_back_db_init(
-    Backend	*be
+	Backend	*be,
+	ConfigReply *cr
 )
 {
 	struct shellinfo	*si;
@@ -90,7 +93,8 @@
 
 int
 shell_back_db_destroy(
-    Backend	*be
+	Backend	*be,
+	ConfigReply *cr
 )
 {
 	free( be->be_private );

Modified: openldap/trunk/servers/slapd/back-shell/modify.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/modify.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/modify.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* modify.c - shell backend modify function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/modify.c,v 1.31.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/modify.c,v 1.33.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -46,7 +46,7 @@
 	Modification *mod;
 	struct shellinfo	*si = (struct shellinfo *) op->o_bd->be_private;
 	AttributeDescription *entry = slap_schema.si_ad_entry;
-	Modifications *ml  = op->oq_modify.rs_modlist;
+	Modifications *ml  = op->orm_modlist;
 	Entry e;
 	FILE			*rfp, *wfp;
 	int			i;

Modified: openldap/trunk/servers/slapd/back-shell/modrdn.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/modrdn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/modrdn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* modrdn.c - shell backend modrdn function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/modrdn.c,v 1.25.2.4 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/modrdn.c,v 1.28.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/proto-shell.h
===================================================================
--- openldap/trunk/servers/slapd/back-shell/proto-shell.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/proto-shell.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/proto-shell.h,v 1.2.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/proto-shell.h,v 1.4.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/result.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/result.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/result.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* result.c - shell backend result reading function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/result.c,v 1.21.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/result.c,v 1.23.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/search.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* search.c - shell backend search function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/search.c,v 1.27.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/search.c,v 1.29.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/searchexample.conf
===================================================================
--- openldap/trunk/servers/slapd/back-shell/searchexample.conf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/searchexample.conf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/servers/slapd/back-shell/searchexample.conf,v 1.8.2.3 2007/01/02 21:44:06 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-shell/searchexample.conf,v 1.10.2.2 2007/08/31 23:14:05 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/searchexample.sh
===================================================================
--- openldap/trunk/servers/slapd/back-shell/searchexample.sh	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/searchexample.sh	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# $OpenLDAP: pkg/ldap/servers/slapd/back-shell/searchexample.sh,v 1.7.2.3 2007/01/02 21:44:06 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-shell/searchexample.sh,v 1.9.2.2 2007/08/31 23:14:05 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-shell/shell.h
===================================================================
--- openldap/trunk/servers/slapd/back-shell/shell.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/shell.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* shell.h - shell backend header file */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/shell.h,v 1.22.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/shell.h,v 1.24.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -46,10 +46,6 @@
 	char	**si_delete;	/* cmd + args to exec for delete  */
 };
 
-struct slap_backend_db;
-struct slap_conn;
-struct slap_op;
-
 extern pid_t forkandexec LDAP_P((
 	char **args,
 	FILE **rfp,
@@ -57,11 +53,11 @@
 
 extern void print_suffixes LDAP_P((
 	FILE *fp,
-	struct slap_backend_db *bd));
+	BackendDB *bd));
 
 extern int read_and_send_results LDAP_P((
-	struct slap_op *op,
-	struct slap_rep *rs,
+	Operation *op,
+	SlapReply *rs,
 	FILE *fp));
 
 LDAP_END_DECL

Modified: openldap/trunk/servers/slapd/back-shell/unbind.c
===================================================================
--- openldap/trunk/servers/slapd/back-shell/unbind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-shell/unbind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* unbind.c - shell backend unbind function */
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/unbind.c,v 1.21.2.3 2007/01/02 21:44:06 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-shell/unbind.c,v 1.23.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-sql/Makefile.in
===================================================================
--- openldap/trunk/servers/slapd/back-sql/Makefile.in	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/Makefile.in	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 # Makefile.in for back-sql
-# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/Makefile.in,v 1.14.2.3 2007/01/02 21:44:07 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/Makefile.in,v 1.16.2.2 2007/08/31 23:14:05 quanah Exp $
 ## This work is part of OpenLDAP Software <http://www.openldap.org/>.
 ##
 ## Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/back-sql/add.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/add.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/add.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/add.c,v 1.20.2.13 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/add.c,v 1.50.2.4 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -924,6 +924,7 @@
 	Entry			p = { 0 }, *e = NULL;
 	Attribute		*at,
 				*at_objectClass = NULL;
+	ObjectClass		*soc = NULL;
 	struct berval		scname = BER_BVNULL;
 	struct berval		pdn;
 	struct berval		realdn = BER_BVNULL;
@@ -957,13 +958,11 @@
 	Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n",
 			op->ora_e->e_name.bv_val, 0, 0 );
 
-	slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
-
 	/* check schema */
 	if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
 		char		textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
 
-		rs->sr_err = entry_schema_check( op, op->ora_e, NULL, 0,
+		rs->sr_err = entry_schema_check( op, op->ora_e, NULL, 0, 1,
 			&rs->sr_text, textbuf, sizeof( textbuf ) );
 		if ( rs->sr_err != LDAP_SUCCESS ) {
 			Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
@@ -974,6 +973,8 @@
 		}
 	}
 
+	slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
 	/* search structuralObjectClass */
 	for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) {
 		if ( at->a_desc == slap_schema.si_ad_structuralObjectClass ) {
@@ -1002,8 +1003,8 @@
 			goto done;
 		}
 
-		rs->sr_err = structural_class( at->a_vals, &scname, NULL,
-				&text, buf, sizeof( buf ) );
+		rs->sr_err = structural_class( at->a_vals, &soc, NULL,
+				&text, buf, sizeof( buf ), op->o_tmpmemctx );
 		if ( rs->sr_err != LDAP_SUCCESS ) {
 			Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
 				"%s (%d)\n",
@@ -1011,6 +1012,7 @@
 			e = NULL;
 			goto done;
 		}
+		scname = soc->soc_cname;
 
 	} else {
 		scname = at->a_vals[0];
@@ -1479,7 +1481,6 @@
 	 * in deleting that row.
 	 */
 
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 	if ( e != NULL ) {
 		int	disclose = 1;
 
@@ -1504,7 +1505,6 @@
 			}
 		}
 	}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 
 	if ( op->o_noop && rs->sr_err == LDAP_SUCCESS ) {
 		rs->sr_err = LDAP_X_NO_OPERATION;
@@ -1520,7 +1520,7 @@
 	}
 
 	if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-		(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
 	}
 
 	if ( !BER_BVISNULL( &p.e_nname ) ) {

Modified: openldap/trunk/servers/slapd/back-sql/back-sql.h
===================================================================
--- openldap/trunk/servers/slapd/back-sql/back-sql.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/back-sql.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/back-sql.h,v 1.30.2.10 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/back-sql.h,v 1.49.2.3 2007/11/27 19:45:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -181,6 +181,7 @@
 	SWORD		ncols;
 	BerVarray	col_names;
 	UDWORD		*col_prec;
+	SQLSMALLINT	*col_type;
 	char		**cols;
 	SQLINTEGER	*value_len;
 } BACKSQL_ROW_NTS;
@@ -266,37 +267,6 @@
 } backsql_api;
 
 /*
- * Entry ID structure
- */
-typedef struct backsql_entryID {
-	/* #define BACKSQL_ARBITRARY_KEY to allow a non-numeric key.
-	 * It is required by some special applications that use
-	 * strings as keys for the main table.
-	 * In this case, #define BACKSQL_MAX_KEY_LEN consistently
-	 * with the key size definition */
-#ifdef BACKSQL_ARBITRARY_KEY
-	struct berval		eid_id;
-	struct berval		eid_keyval;
-#define BACKSQL_MAX_KEY_LEN	64
-#else /* ! BACKSQL_ARBITRARY_KEY */
-	/* The original numeric key is maintained as default. */
-	unsigned long		eid_id;
-	unsigned long		eid_keyval;
-#endif /* ! BACKSQL_ARBITRARY_KEY */
-
-	unsigned long		eid_oc_id;
-	struct berval		eid_dn;
-	struct berval		eid_ndn;
-	struct backsql_entryID	*eid_next;
-} backsql_entryID;
-
-#ifdef BACKSQL_ARBITRARY_KEY
-#define BACKSQL_ENTRYID_INIT { BER_BVNULL, BER_BVNULL, 0, BER_BVNULL, BER_BVNULL, NULL }
-#else /* ! BACKSQL_ARBITRARY_KEY */
-#define BACKSQL_ENTRYID_INIT { 0, 0, 0, BER_BVNULL, BER_BVNULL, NULL }
-#endif /* BACKSQL_ARBITRARY_KEY */
-
-/*
  * "structural" objectClass mapping structure
  */
 typedef struct backsql_oc_map_rec {
@@ -330,6 +300,7 @@
 typedef struct backsql_at_map_rec {
 	/* Description of corresponding LDAP attribute type */
 	AttributeDescription	*bam_ad;
+	AttributeDescription	*bam_true_ad;
 	/* ObjectClass if bam_ad is objectClass */
 	ObjectClass		*bam_oc;
 
@@ -395,14 +366,49 @@
 
 #define BB_NULL		{ BER_BVNULL, 0 }
 
+/*
+ * Entry ID structure
+ */
+typedef struct backsql_entryID {
+	/* #define BACKSQL_ARBITRARY_KEY to allow a non-numeric key.
+	 * It is required by some special applications that use
+	 * strings as keys for the main table.
+	 * In this case, #define BACKSQL_MAX_KEY_LEN consistently
+	 * with the key size definition */
+#ifdef BACKSQL_ARBITRARY_KEY
+	struct berval		eid_id;
+	struct berval		eid_keyval;
+#define BACKSQL_MAX_KEY_LEN	64
+#else /* ! BACKSQL_ARBITRARY_KEY */
+	/* The original numeric key is maintained as default. */
+	unsigned long		eid_id;
+	unsigned long		eid_keyval;
+#endif /* ! BACKSQL_ARBITRARY_KEY */
+
+	unsigned long		eid_oc_id;
+	backsql_oc_map_rec	*eid_oc;
+	struct berval		eid_dn;
+	struct berval		eid_ndn;
+	struct backsql_entryID	*eid_next;
+} backsql_entryID;
+
+#ifdef BACKSQL_ARBITRARY_KEY
+#define BACKSQL_ENTRYID_INIT { BER_BVNULL, BER_BVNULL, 0, NULL, BER_BVNULL, BER_BVNULL, NULL }
+#else /* ! BACKSQL_ARBITRARY_KEY */
+#define BACKSQL_ENTRYID_INIT { 0, 0, 0, NULL, BER_BVNULL, BER_BVNULL, NULL }
+#endif /* BACKSQL_ARBITRARY_KEY */
+
 /* the function must collect the entry associated to nbase */
 #define BACKSQL_ISF_GET_ID	0x1U
 #define BACKSQL_ISF_GET_ENTRY	( 0x2U | BACKSQL_ISF_GET_ID )
-#define BACKSQL_ISF_MATCHED	0x4U
+#define BACKSQL_ISF_GET_OC	( 0x4U | BACKSQL_ISF_GET_ID )
+#define BACKSQL_ISF_MATCHED	0x8U
 #define BACKSQL_IS_GET_ID(f) \
 	( ( (f) & BACKSQL_ISF_GET_ID ) == BACKSQL_ISF_GET_ID )
 #define BACKSQL_IS_GET_ENTRY(f) \
 	( ( (f) & BACKSQL_ISF_GET_ENTRY ) == BACKSQL_ISF_GET_ENTRY )
+#define BACKSQL_IS_GET_OC(f) \
+	( ( (f) & BACKSQL_ISF_GET_OC ) == BACKSQL_ISF_GET_OC )
 #define BACKSQL_IS_MATCHED(f) \
 	( ( (f) & BACKSQL_ISF_MATCHED ) == BACKSQL_ISF_MATCHED )
 typedef struct backsql_srch_info {
@@ -471,14 +477,16 @@
 	 */
 	struct berval	sql_subtree_cond;
 	struct berval	sql_children_cond;
-	char		*sql_oc_query,
-			*sql_at_query;
-	char		*sql_insentry_stmt,
-			*sql_delentry_stmt,
-			*sql_renentry_stmt,
-			*sql_delobjclasses_stmt;
+	struct berval	sql_dn_match_cond;
+	char		*sql_oc_query;
+	char		*sql_at_query;
+	char		*sql_insentry_stmt;
+	char		*sql_delentry_stmt;
+	char		*sql_renentry_stmt;
+	char		*sql_delobjclasses_stmt;
 	char		*sql_id_query;
 	char		*sql_has_children_query;
+	char		*sql_list_children_query;
 
 	MatchingRule	*sql_caseIgnoreMatch;
 	MatchingRule	*sql_telephoneNumberMatch;
@@ -556,9 +564,10 @@
 #define BACKSQL_BASEOBJECT_OC		0
 	
 	Avlnode		*sql_db_conns;
+	SQLHDBC		sql_dbh;
+	ldap_pvt_thread_mutex_t		sql_dbconn_mutex;
 	Avlnode		*sql_oc_by_oc;
 	Avlnode		*sql_oc_by_id;
-	ldap_pvt_thread_mutex_t		sql_dbconn_mutex;
 	ldap_pvt_thread_mutex_t		sql_schema_mutex;
  	SQLHENV		sql_db_env;
 
@@ -582,5 +591,10 @@
 #define BACKSQL_SANITIZE_ERROR( rc ) \
 	( BACKSQL_LEGAL_ERROR( (rc) ) ? (rc) : LDAP_OTHER )
 
+#define BACKSQL_IS_BINARY(ct) \
+	( (ct) == SQL_BINARY \
+	  || (ct) == SQL_VARBINARY \
+	  || (ct) == SQL_LONGVARBINARY)
+
 #endif /* __BACKSQL_H__ */
 

Modified: openldap/trunk/servers/slapd/back-sql/bind.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/bind.c,v 1.28.2.5 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/bind.c,v 1.41.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -40,27 +40,20 @@
  
  	Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 );
 
-	if ( be_isroot_pw( op ) ) {
-     		ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
-		Debug( LDAP_DEBUG_TRACE, "<==backsql_bind() root bind\n", 
-				0, 0, 0 );
-		return LDAP_SUCCESS;
-	}
+	switch ( be_rootdn_bind( op, rs ) ) {
+	case SLAP_CB_CONTINUE:
+		break;
 
-	ber_dupbv( &op->oq_bind.rb_edn, &op->o_req_ndn );
-
-	if ( op->oq_bind.rb_method != LDAP_AUTH_SIMPLE ) {
-		rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
-		rs->sr_text = "authentication method not supported"; 
-		send_ldap_result( op, rs );
+	default:
+		/* in case of success, front end will send result;
+		 * otherwise, be_rootdn_bind() did */
+ 		Debug( LDAP_DEBUG_TRACE, "<==backsql_bind(%d)\n",
+			rs->sr_err, 0, 0 );
 		return rs->sr_err;
 	}
 
-	/*
-	 * method = LDAP_AUTH_SIMPLE
-	 */
 	rs->sr_err = backsql_get_db_conn( op, &dbh );
-	if ( !dbh ) {
+	if ( rs->sr_err != LDAP_SUCCESS ) {
      		Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
 			"could not get connection handle - exiting\n",
 			0, 0, 0 );
@@ -101,7 +94,7 @@
 
 error_return:;
 	if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-		(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
 	}
 
 	if ( !BER_BVISNULL( &e.e_nname ) ) {

Modified: openldap/trunk/servers/slapd/back-sql/compare.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/compare.c,v 1.10.2.5 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/compare.c,v 1.24.2.4 2007/09/29 09:55:22 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -42,7 +42,7 @@
  	Debug( LDAP_DEBUG_TRACE, "==>backsql_compare()\n", 0, 0, 0 );
 
 	rs->sr_err = backsql_get_db_conn( op, &dbh );
-	if ( !dbh ) {
+	if ( rs->sr_err != LDAP_SUCCESS ) {
      		Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
 			"could not get connection handle - exiting\n",
 			0, 0, 0 );
@@ -131,11 +131,10 @@
 			a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc ) )
 	{
 		rs->sr_err = LDAP_COMPARE_FALSE;
-		if ( value_find_ex( op->oq_compare.rs_ava->aa_desc,
+		if ( attr_valfind( a,
 					SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
 					SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-					a->a_nvals,
-					&op->oq_compare.rs_ava->aa_value,
+					&op->oq_compare.rs_ava->aa_value, NULL,
 					op->o_tmpmemctx ) == 0 )
 		{
 			rs->sr_err = LDAP_COMPARE_TRUE;
@@ -150,7 +149,6 @@
 		break;
 
 	default:
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 		if ( !BER_BVISNULL( &e.e_nname ) &&
 				! access_allowed( op, &e,
 					slap_schema.si_ad_entry, NULL,
@@ -159,7 +157,6 @@
 			rs->sr_err = LDAP_NO_SUCH_OBJECT;
 			rs->sr_text = NULL;
 		}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 		break;
 	}
 
@@ -175,7 +172,7 @@
 	}
 
 	if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-		(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
 	}
 
 	if ( !BER_BVISNULL( &e.e_nname ) ) {

Modified: openldap/trunk/servers/slapd/back-sql/config.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/config.c,v 1.17.2.7 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/config.c,v 1.32.2.3 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -148,8 +148,21 @@
 		}
 		ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_children_cond );
 		Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
-			"subtree_cond=%s\n", bi->sql_children_cond.bv_val, 0, 0 );
+			"children_cond=%s\n", bi->sql_children_cond.bv_val, 0, 0 );
 
+	} else if ( !strcasecmp( argv[ 0 ], "dn_match_cond" ) ) {
+		if ( argc < 2 ) {
+			Debug( LDAP_DEBUG_TRACE, 
+				"<==backsql_db_config (%s line %d): "
+				"missing SQL condition "
+				"in \"dn_match_cond\" directive\n",
+				fname, lineno, 0 );
+			return 1;
+		}
+		ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_dn_match_cond );
+		Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+			"children_cond=%s\n", bi->sql_dn_match_cond.bv_val, 0, 0 );
+
 	} else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) {
 		if ( argc < 2 ) {
 			Debug( LDAP_DEBUG_TRACE, 
@@ -661,10 +674,10 @@
 		return LDAP_OTHER;
 	}
 
-	bi->sql_baseObject = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) );
+	bi->sql_baseObject = entry_alloc();
 	if ( bi->sql_baseObject == NULL ) {
 		Debug( LDAP_DEBUG_ANY,
-			"read_baseObject_file: SLAP_CALLOC failed", 0, 0, 0 );
+			"read_baseObject_file: entry_alloc failed", 0, 0, 0 );
 		ldif_close( fp );
 		return LDAP_NO_MEMORY;
 	}

Modified: openldap/trunk/servers/slapd/back-sql/delete.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/delete.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/delete.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/delete.c,v 1.15.2.9 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/delete.c,v 1.35.2.7 2007/11/27 19:45:37 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -58,8 +58,7 @@
 	Operation 		*op,
 	SlapReply		*rs,
 	SQLHDBC			dbh, 
-	backsql_entryID		*e_id,
-	backsql_oc_map_rec	*oc )
+	backsql_entryID		*eid )
 {
 	backsql_delete_attr_t	bda;
 	int			rc;
@@ -67,9 +66,9 @@
 	bda.op = op;
 	bda.rs = rs;
 	bda.dbh = dbh;
-	bda.e_id = e_id;
+	bda.e_id = eid;
 	
-	rc = avl_apply( oc->bom_attrs, backsql_delete_attr_f, &bda,
+	rc = avl_apply( eid->eid_oc->bom_attrs, backsql_delete_attr_f, &bda,
 			BACKSQL_AVL_STOP, AVL_INORDER );
 	if ( rc == BACKSQL_AVL_STOP ) {
 		return rs->sr_err;
@@ -78,187 +77,31 @@
 	return LDAP_SUCCESS;
 }
 
-int
-backsql_delete( Operation *op, SlapReply *rs )
+static int
+backsql_delete_int(
+	Operation	*op,
+	SlapReply	*rs,
+	SQLHDBC		dbh,
+	SQLHSTMT	*sthp,
+	backsql_entryID	*eid,
+	Entry		**ep )
 {
 	backsql_info 		*bi = (backsql_info*)op->o_bd->be_private;
-	SQLHDBC 		dbh = SQL_NULL_HDBC;
 	SQLHSTMT		sth = SQL_NULL_HSTMT;
 	RETCODE			rc;
 	int			prc = LDAP_SUCCESS;
-	backsql_oc_map_rec	*oc = NULL;
-	backsql_srch_info	bsi = { 0 };
-	backsql_entryID		e_id = { 0 };
-	Entry			d = { 0 }, p = { 0 }, *e = NULL;
-	struct berval		pdn = BER_BVNULL;
-	int			manageDSAit = get_manageDSAit( op );
 	/* first parameter no */
 	SQLUSMALLINT		pno = 0;
 
-	Debug( LDAP_DEBUG_TRACE, "==>backsql_delete(): deleting entry \"%s\"\n",
-			op->o_req_ndn.bv_val, 0, 0 );
+	sth = *sthp;
 
-	rs->sr_err = backsql_get_db_conn( op, &dbh );
-	if ( rs->sr_err != LDAP_SUCCESS ) {
-		Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
-			"could not get connection handle - exiting\n", 
-			0, 0, 0 );
-		rs->sr_text = ( rs->sr_err == LDAP_OTHER )
-			? "SQL-backend error" : NULL;
-		e = NULL;
-		goto done;
-	}
-	
-	/*
-	 * Get the entry
-	 */
-	bsi.bsi_e = &d;
-	rs->sr_err = backsql_init_search( &bsi, &op->o_req_ndn,
-			LDAP_SCOPE_BASE, 
-			(time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
-			( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
-	switch ( rs->sr_err ) {
-	case LDAP_SUCCESS:
-		break;
-
-	case LDAP_REFERRAL:
-		if ( manageDSAit && !BER_BVISNULL( &bsi.bsi_e->e_nname ) &&
-				dn_match( &op->o_req_ndn, &bsi.bsi_e->e_nname ) )
-		{
-			rs->sr_err = LDAP_SUCCESS;
-			rs->sr_text = NULL;
-			rs->sr_matched = NULL;
-			if ( rs->sr_ref ) {
-				ber_bvarray_free( rs->sr_ref );
-				rs->sr_ref = NULL;
-			}
-			break;
-		}
-		e = &d;
-		/* fallthru */
-
-	default:
-		Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
-			"could not retrieve deleteDN ID - no such entry\n", 
-			0, 0, 0 );
-		if ( !BER_BVISNULL( &d.e_nname ) ) {
-			/* FIXME: should always be true! */
-			e = &d;
-
-		} else {
-			e = NULL;
-		}
-		goto done;
-	}
-
-	if ( get_assert( op ) &&
-			( test_filter( op, &d, get_assertion( op ) )
-			  != LDAP_COMPARE_TRUE ) )
-	{
-		rs->sr_err = LDAP_ASSERTION_FAILED;
-		e = &d;
-		goto done;
-	}
-
-	if ( !access_allowed( op, &d, slap_schema.si_ad_entry, 
-			NULL, ACL_WDEL, NULL ) )
-	{
-		Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
-			"no write access to entry\n", 
-			0, 0, 0 );
-		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-		e = &d;
-		goto done;
-	}
-
-	rs->sr_err = backsql_has_children( op, dbh, &op->o_req_ndn );
-	switch ( rs->sr_err ) {
-	case LDAP_COMPARE_FALSE:
-		rs->sr_err = LDAP_SUCCESS;
-		break;
-
-	case LDAP_COMPARE_TRUE:
-		if ( get_treeDelete( op ) ) {
-			/* not supported yet */ ;
-		}
-		Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
-			"entry \"%s\" has children\n",
-			op->o_req_dn.bv_val, 0, 0 );
-		rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
-		rs->sr_text = "subordinate objects must be deleted first";
-		/* fallthru */
-
-	default:
-		e = &d;
-		goto done;
-	}
-
-	oc = backsql_id2oc( bi, bsi.bsi_base_id.eid_oc_id );
-	if ( oc == NULL ) {
-		Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
-			"cannot determine objectclass of entry -- aborting\n",
-			0, 0, 0 );
-		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-		rs->sr_text = "operation not permitted within namingContext";
-		e = NULL;
- 		goto done;
-	}
-
-	if ( oc->bom_delete_proc == NULL ) {
-		Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
-			"delete procedure is not defined "
-			"for this objectclass - aborting\n", 0, 0, 0 );
-		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-		rs->sr_text = "operation not permitted within namingContext";
-		e = NULL;
-		goto done;
-	}
-
-	/*
-	 * Get the parent
-	 */
-	e_id = bsi.bsi_base_id;
-	if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
-		dnParent( &op->o_req_ndn, &pdn );
-		bsi.bsi_e = &p;
-		rs->sr_err = backsql_init_search( &bsi, &pdn,
-				LDAP_SCOPE_BASE, 
-				(time_t)(-1), NULL, dbh, op, rs,
-				slap_anlist_no_attrs,
-				BACKSQL_ISF_GET_ENTRY );
-		if ( rs->sr_err != LDAP_SUCCESS ) {
-			Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
-				"could not retrieve deleteDN ID "
-				"- no such entry\n", 
-				0, 0, 0 );
-			e = &p;
-			goto done;
-		}
-
-		(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
-
-		/* check parent for "children" acl */
-		if ( !access_allowed( op, &p, slap_schema.si_ad_children, 
-				NULL, ACL_WDEL, NULL ) )
-		{
-			Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
-				"no write access to parent\n", 
-				0, 0, 0 );
-			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-			e = &p;
-			goto done;
-
-		}
-	}
-
 	/* avl_apply ... */
-	rs->sr_err = backsql_delete_all_attrs( op, rs, dbh, &e_id, oc );
+	rs->sr_err = backsql_delete_all_attrs( op, rs, dbh, eid );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
-		e = &d;
 		goto done;
 	}
 
-	rc = backsql_Prepare( dbh, &sth, oc->bom_delete_proc, 0 );
+	rc = backsql_Prepare( dbh, &sth, eid->eid_oc->bom_delete_proc, 0 );
 	if ( rc != SQL_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE,
 			"   backsql_delete(): "
@@ -268,42 +111,42 @@
 
 		rs->sr_err = LDAP_OTHER;
 		rs->sr_text = "SQL-backend error";
-		e = NULL;
+		*ep = NULL;
 		goto done;
 	}
 
-	if ( BACKSQL_IS_DEL( oc->bom_expect_return ) ) {
+	if ( BACKSQL_IS_DEL( eid->eid_oc->bom_expect_return ) ) {
 		pno = 1;
 		rc = backsql_BindParamInt( sth, 1, SQL_PARAM_OUTPUT, &prc );
 		if ( rc != SQL_SUCCESS ) {
 			Debug( LDAP_DEBUG_TRACE,
 				"   backsql_delete(): "
 				"error binding output parameter for objectClass %s\n",
-				oc->bom_oc->soc_cname.bv_val, 0, 0 );
+				eid->eid_oc->bom_oc->soc_cname.bv_val, 0, 0 );
 			backsql_PrintErrors( bi->sql_db_env, dbh, 
 				sth, rc );
 			SQLFreeStmt( sth, SQL_DROP );
 
 			rs->sr_text = "SQL-backend error";
 			rs->sr_err = LDAP_OTHER;
-			e = NULL;
+			*ep = NULL;
 			goto done;
 		}
 	}
 
-	rc = backsql_BindParamID( sth, pno + 1, SQL_PARAM_INPUT, &e_id.eid_keyval );
+	rc = backsql_BindParamID( sth, pno + 1, SQL_PARAM_INPUT, &eid->eid_keyval );
 	if ( rc != SQL_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE,
 			"   backsql_delete(): "
 			"error binding keyval parameter for objectClass %s\n",
-			oc->bom_oc->soc_cname.bv_val, 0, 0 );
+			eid->eid_oc->bom_oc->soc_cname.bv_val, 0, 0 );
 		backsql_PrintErrors( bi->sql_db_env, dbh, 
 			sth, rc );
 		SQLFreeStmt( sth, SQL_DROP );
 
 		rs->sr_text = "SQL-backend error";
 		rs->sr_err = LDAP_OTHER;
-		e = NULL;
+		*ep = NULL;
 		goto done;
 	}
 
@@ -328,7 +171,6 @@
 			rs->sr_err = LDAP_OTHER;
 		}
 		SQLFreeStmt( sth, SQL_DROP );
-		e = &d;
 		goto done;
 	}
 	SQLFreeStmt( sth, SQL_DROP );
@@ -344,24 +186,24 @@
 
 		rs->sr_err = LDAP_OTHER;
 		rs->sr_text = "SQL-backend error";
-		e = NULL;
+		*ep = NULL;
 		goto done;
 	}
 
-	rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT, &e_id.eid_id );
+	rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT, &eid->eid_id );
 	if ( rc != SQL_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE,
 			"   backsql_delete(): "
 			"error binding auxiliary objectClasses "
 			"entry ID parameter for objectClass %s\n",
-			oc->bom_oc->soc_cname.bv_val, 0, 0 );
+			eid->eid_oc->bom_oc->soc_cname.bv_val, 0, 0 );
 		backsql_PrintErrors( bi->sql_db_env, dbh, 
 			sth, rc );
 		SQLFreeStmt( sth, SQL_DROP );
 
 		rs->sr_text = "SQL-backend error";
 		rs->sr_err = LDAP_OTHER;
-		e = NULL;
+		*ep = NULL;
 		goto done;
 	}
 
@@ -381,7 +223,7 @@
 		SQLFreeStmt( sth, SQL_DROP );
 		rs->sr_err = LDAP_OTHER;
 		rs->sr_text = "SQL-backend error";
-		e = NULL;
+		*ep = NULL;
 		goto done;
 	}
 	SQLFreeStmt( sth, SQL_DROP );
@@ -397,24 +239,24 @@
 
 		rs->sr_err = LDAP_OTHER;
 		rs->sr_text = "SQL-backend error";
-		e = NULL;
+		*ep = NULL;
 		goto done;
 	}
 
-	rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT, &e_id.eid_id );
+	rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT, &eid->eid_id );
 	if ( rc != SQL_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE,
 			"   backsql_delete(): "
 			"error binding entry ID parameter "
 			"for objectClass %s\n",
-			oc->bom_oc->soc_cname.bv_val, 0, 0 );
+			eid->eid_oc->bom_oc->soc_cname.bv_val, 0, 0 );
 		backsql_PrintErrors( bi->sql_db_env, dbh, 
 			sth, rc );
 		SQLFreeStmt( sth, SQL_DROP );
 
 		rs->sr_text = "SQL-backend error";
 		rs->sr_err = LDAP_OTHER;
-		e = NULL;
+		*ep = NULL;
 		goto done;
 	}
 
@@ -427,14 +269,316 @@
 		SQLFreeStmt( sth, SQL_DROP );
 		rs->sr_err = LDAP_OTHER;
 		rs->sr_text = "SQL-backend error";
-		e = NULL;
+		*ep = NULL;
 		goto done;
 	}
 	SQLFreeStmt( sth, SQL_DROP );
 
 	rs->sr_err = LDAP_SUCCESS;
+	*ep = NULL;
 
+done:;
+	*sthp = sth;
+
+	return rs->sr_err;
+}
+
+typedef struct backsql_tree_delete_t {
+	Operation	*btd_op;
+	int		btd_rc;
+	backsql_entryID	*btd_eid;
+} backsql_tree_delete_t;
+
+static int
+backsql_tree_delete_search_cb( Operation *op, SlapReply *rs )
+{
+	if ( rs->sr_type == REP_SEARCH ) {
+		backsql_tree_delete_t	*btd;
+		backsql_entryID		*eid;
+
+		btd = (backsql_tree_delete_t *)op->o_callback->sc_private;
+
+		if ( !access_allowed( btd->btd_op, rs->sr_entry,
+			slap_schema.si_ad_entry, NULL, ACL_WDEL, NULL )
+			|| !access_allowed( btd->btd_op, rs->sr_entry,
+			slap_schema.si_ad_children, NULL, ACL_WDEL, NULL ) )
+		{
+			btd->btd_rc = LDAP_INSUFFICIENT_ACCESS;
+			return rs->sr_err = LDAP_UNAVAILABLE;
+		}
+
+		assert( rs->sr_entry != NULL );
+		assert( rs->sr_entry->e_private != NULL );
+
+		eid = (backsql_entryID *)rs->sr_entry->e_private;
+		assert( eid->eid_oc != NULL );
+		if ( eid->eid_oc == NULL || eid->eid_oc->bom_delete_proc == NULL ) {
+			btd->btd_rc = LDAP_UNWILLING_TO_PERFORM;
+			return rs->sr_err = LDAP_UNAVAILABLE;
+		}
+
+		eid = backsql_entryID_dup( eid, op->o_tmpmemctx );
+		eid->eid_next = btd->btd_eid;
+		btd->btd_eid = eid;
+	}
+
+	return 0;
+}
+
+static int
+backsql_tree_delete(
+	Operation	*op,
+	SlapReply	*rs,
+	SQLHDBC		dbh,
+	SQLHSTMT	*sthp )
+{
+	Operation		op2 = *op;
+	slap_callback		sc = { 0 };
+	SlapReply		rs2 = { 0 };
+	backsql_tree_delete_t	btd = { 0 };
+
+	int			rc;
+
 	/*
+	 * - perform an internal subtree search as the rootdn
+	 * - for each entry
+	 *	- check access
+	 *	- check objectClass and delete method(s)
+	 * - for each entry
+	 *	- delete
+	 * - if successful, commit
+	 */
+
+	op2.o_tag = LDAP_REQ_SEARCH;
+	op2.o_protocol = LDAP_VERSION3;
+
+	btd.btd_op = op;
+	sc.sc_private = &btd;
+	sc.sc_response = backsql_tree_delete_search_cb;
+	op2.o_callback = &sc;
+
+	op2.o_dn = op->o_bd->be_rootdn;
+	op2.o_ndn = op->o_bd->be_rootndn;
+
+	op2.o_managedsait = SLAP_CONTROL_CRITICAL;
+
+	op2.ors_scope = LDAP_SCOPE_SUBTREE;
+	op2.ors_deref = LDAP_DEREF_NEVER;
+	op2.ors_slimit = SLAP_NO_LIMIT;
+	op2.ors_tlimit = SLAP_NO_LIMIT;
+	op2.ors_filter = (Filter *)slap_filter_objectClass_pres;
+	op2.ors_filterstr = *slap_filterstr_objectClass_pres;
+	op2.ors_attrs = slap_anlist_all_attributes;
+	op2.ors_attrsonly = 0;
+
+	rc = op->o_bd->be_search( &op2, &rs2 );
+	if ( rc != LDAP_SUCCESS ) {
+		rc = rs->sr_err = btd.btd_rc;
+		rs->sr_text = "subtree delete not possible";
+		send_ldap_result( op, rs );
+		goto clean;
+	}
+
+	for ( ; btd.btd_eid != NULL;
+		btd.btd_eid = backsql_free_entryID( btd.btd_eid,
+			1, op->o_tmpmemctx ) )
+	{
+		Entry	*e = (void *)0xbad;
+		rc = backsql_delete_int( op, rs, dbh, sthp, btd.btd_eid, &e );
+		if ( rc != LDAP_SUCCESS ) {
+			break;
+		}
+	}
+
+clean:;
+	for ( ; btd.btd_eid != NULL;
+		btd.btd_eid = backsql_free_entryID( btd.btd_eid,
+			1, op->o_tmpmemctx ) )
+		;
+
+	return rc;
+}
+
+int
+backsql_delete( Operation *op, SlapReply *rs )
+{
+	SQLHDBC 		dbh = SQL_NULL_HDBC;
+	SQLHSTMT		sth = SQL_NULL_HSTMT;
+	backsql_oc_map_rec	*oc = NULL;
+	backsql_srch_info	bsi = { 0 };
+	backsql_entryID		e_id = { 0 };
+	Entry			d = { 0 }, p = { 0 }, *e = NULL;
+	struct berval		pdn = BER_BVNULL;
+	int			manageDSAit = get_manageDSAit( op );
+
+	Debug( LDAP_DEBUG_TRACE, "==>backsql_delete(): deleting entry \"%s\"\n",
+			op->o_req_ndn.bv_val, 0, 0 );
+
+	rs->sr_err = backsql_get_db_conn( op, &dbh );
+	if ( rs->sr_err != LDAP_SUCCESS ) {
+		Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
+			"could not get connection handle - exiting\n", 
+			0, 0, 0 );
+		rs->sr_text = ( rs->sr_err == LDAP_OTHER )
+			? "SQL-backend error" : NULL;
+		e = NULL;
+		goto done;
+	}
+
+	/*
+	 * Get the entry
+	 */
+	bsi.bsi_e = &d;
+	rs->sr_err = backsql_init_search( &bsi, &op->o_req_ndn,
+			LDAP_SCOPE_BASE, 
+			(time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
+			( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY | BACKSQL_ISF_GET_OC ) );
+	switch ( rs->sr_err ) {
+	case LDAP_SUCCESS:
+		break;
+
+	case LDAP_REFERRAL:
+		if ( manageDSAit && !BER_BVISNULL( &bsi.bsi_e->e_nname ) &&
+				dn_match( &op->o_req_ndn, &bsi.bsi_e->e_nname ) )
+		{
+			rs->sr_err = LDAP_SUCCESS;
+			rs->sr_text = NULL;
+			rs->sr_matched = NULL;
+			if ( rs->sr_ref ) {
+				ber_bvarray_free( rs->sr_ref );
+				rs->sr_ref = NULL;
+			}
+			break;
+		}
+		e = &d;
+		/* fallthru */
+
+	default:
+		Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
+			"could not retrieve deleteDN ID - no such entry\n", 
+			0, 0, 0 );
+		if ( !BER_BVISNULL( &d.e_nname ) ) {
+			/* FIXME: should always be true! */
+			e = &d;
+
+		} else {
+			e = NULL;
+		}
+		goto done;
+	}
+
+	if ( get_assert( op ) &&
+			( test_filter( op, &d, get_assertion( op ) )
+			  != LDAP_COMPARE_TRUE ) )
+	{
+		rs->sr_err = LDAP_ASSERTION_FAILED;
+		e = &d;
+		goto done;
+	}
+
+	if ( !access_allowed( op, &d, slap_schema.si_ad_entry, 
+			NULL, ACL_WDEL, NULL ) )
+	{
+		Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
+			"no write access to entry\n", 
+			0, 0, 0 );
+		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+		e = &d;
+		goto done;
+	}
+
+	rs->sr_err = backsql_has_children( op, dbh, &op->o_req_ndn );
+	switch ( rs->sr_err ) {
+	case LDAP_COMPARE_FALSE:
+		rs->sr_err = LDAP_SUCCESS;
+		break;
+
+	case LDAP_COMPARE_TRUE:
+#ifdef SLAP_CONTROL_X_TREE_DELETE
+		if ( get_treeDelete( op ) ) {
+			rs->sr_err = LDAP_SUCCESS;
+			break;
+		}
+#endif /* SLAP_CONTROL_X_TREE_DELETE */
+
+		Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
+			"entry \"%s\" has children\n",
+			op->o_req_dn.bv_val, 0, 0 );
+		rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
+		rs->sr_text = "subordinate objects must be deleted first";
+		/* fallthru */
+
+	default:
+		e = &d;
+		goto done;
+	}
+
+	assert( bsi.bsi_base_id.eid_oc != NULL );
+	oc = bsi.bsi_base_id.eid_oc;
+	if ( oc->bom_delete_proc == NULL ) {
+		Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
+			"delete procedure is not defined "
+			"for this objectclass - aborting\n", 0, 0, 0 );
+		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+		rs->sr_text = "operation not permitted within namingContext";
+		e = NULL;
+		goto done;
+	}
+
+	/*
+	 * Get the parent
+	 */
+	e_id = bsi.bsi_base_id;
+	memset( &bsi.bsi_base_id, 0, sizeof( bsi.bsi_base_id ) );
+	if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
+		dnParent( &op->o_req_ndn, &pdn );
+		bsi.bsi_e = &p;
+		rs->sr_err = backsql_init_search( &bsi, &pdn,
+				LDAP_SCOPE_BASE, 
+				(time_t)(-1), NULL, dbh, op, rs,
+				slap_anlist_no_attrs,
+				BACKSQL_ISF_GET_ENTRY );
+		if ( rs->sr_err != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
+				"could not retrieve deleteDN ID "
+				"- no such entry\n", 
+				0, 0, 0 );
+			e = &p;
+			goto done;
+		}
+
+		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
+
+		/* check parent for "children" acl */
+		if ( !access_allowed( op, &p, slap_schema.si_ad_children, 
+				NULL, ACL_WDEL, NULL ) )
+		{
+			Debug( LDAP_DEBUG_TRACE, "   backsql_delete(): "
+				"no write access to parent\n", 
+				0, 0, 0 );
+			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+			e = &p;
+			goto done;
+
+		}
+	}
+
+	e = &d;
+#ifdef SLAP_CONTROL_X_TREE_DELETE
+	if ( get_treeDelete( op ) ) {
+		backsql_tree_delete( op, rs, dbh, &sth );
+		if ( rs->sr_err == LDAP_OTHER || rs->sr_err == LDAP_SUCCESS )
+		{
+			e = NULL;
+		}
+
+	} else
+#endif /* SLAP_CONTROL_X_TREE_DELETE */
+	{
+		backsql_delete_int( op, rs, dbh, &sth, &e_id, &e );
+	}
+
+	/*
 	 * Commit only if all operations succeed
 	 */
 	if ( sth != SQL_NULL_HSTMT ) {
@@ -449,7 +593,6 @@
 	}
 
 done:;
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 	if ( e != NULL ) {
 		if ( !access_allowed( op, e, slap_schema.si_ad_entry, NULL,
 					ACL_DISCLOSE, NULL ) )
@@ -463,7 +606,6 @@
 			}
 		}
 	}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 
 	if ( op->o_noop && rs->sr_err == LDAP_SUCCESS ) {
 		rs->sr_err = LDAP_X_NO_OPERATION;
@@ -474,7 +616,7 @@
 	Debug( LDAP_DEBUG_TRACE, "<==backsql_delete()\n", 0, 0, 0 );
 
 	if ( !BER_BVISNULL( &e_id.eid_ndn ) ) {
-		(void)backsql_free_entryID( op, &e_id, 0 );
+		(void)backsql_free_entryID( &e_id, 0, op->o_tmpmemctx );
 	}
 
 	if ( !BER_BVISNULL( &d.e_nname ) ) {

Modified: openldap/trunk/servers/slapd/back-sql/entry-id.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/entry-id.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/entry-id.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/entry-id.c,v 1.46.2.13 2007/08/11 07:39:30 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/entry-id.c,v 1.67.2.5 2007/09/29 09:55:22 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -36,8 +36,37 @@
 #endif /* BACKSQL_ARBITRARY_KEY */
 
 backsql_entryID *
-backsql_free_entryID( Operation *op, backsql_entryID *id, int freeit )
+backsql_entryID_dup( backsql_entryID *src, void *ctx )
 {
+	backsql_entryID	*dst;
+
+	if ( src == NULL ) return NULL;
+
+	dst = slap_sl_calloc( 1, sizeof( backsql_entryID ), ctx );
+	ber_dupbv_x( &dst->eid_ndn, &src->eid_ndn, ctx );
+	if ( src->eid_dn.bv_val == src->eid_ndn.bv_val ) {
+		dst->eid_dn = dst->eid_ndn;
+	} else {
+		ber_dupbv_x( &dst->eid_dn, &src->eid_dn, ctx );
+	}
+
+#ifdef BACKSQL_ARBITRARY_KEY
+	ber_dupbv_x( &dst->eid_id, &src->eid_id, ctx );
+	ber_dupbv_x( &dst->eid_keyval, &src->eid_keyval, ctx );
+#else /* ! BACKSQL_ARBITRARY_KEY */
+	dst->eid_id = src->eid_id;
+	dst->eid_keyval = src->eid_keyval;
+#endif /* ! BACKSQL_ARBITRARY_KEY */
+
+	dst->eid_oc = src->eid_oc;
+	dst->eid_oc_id = src->eid_oc_id;
+
+	return dst;
+}
+
+backsql_entryID *
+backsql_free_entryID( backsql_entryID *id, int freeit, void *ctx )
+{
 	backsql_entryID 	*next;
 
 	assert( id != NULL );
@@ -48,28 +77,28 @@
 		if ( !BER_BVISNULL( &id->eid_dn )
 				&& id->eid_dn.bv_val != id->eid_ndn.bv_val )
 		{
-			op->o_tmpfree( id->eid_dn.bv_val, op->o_tmpmemctx );
+			slap_sl_free( id->eid_dn.bv_val, ctx );
 			BER_BVZERO( &id->eid_dn );
 		}
 
-		op->o_tmpfree( id->eid_ndn.bv_val, op->o_tmpmemctx );
+		slap_sl_free( id->eid_ndn.bv_val, ctx );
 		BER_BVZERO( &id->eid_ndn );
 	}
 
 #ifdef BACKSQL_ARBITRARY_KEY
 	if ( !BER_BVISNULL( &id->eid_id ) ) {
-		op->o_tmpfree( id->eid_id.bv_val, op->o_tmpmemctx );
+		slap_sl_free( id->eid_id.bv_val, ctx );
 		BER_BVZERO( &id->eid_id );
 	}
 
 	if ( !BER_BVISNULL( &id->eid_keyval ) ) {
-		op->o_tmpfree( id->eid_keyval.bv_val, op->o_tmpmemctx );
+		slap_sl_free( id->eid_keyval.bv_val, ctx );
 		BER_BVZERO( &id->eid_keyval );
 	}
 #endif /* BACKSQL_ARBITRARY_KEY */
 
 	if ( freeit ) {
-		op->o_tmpfree( id, op->o_tmpmemctx );
+		slap_sl_free( id, ctx );
 	}
 
 	return next;
@@ -291,7 +320,7 @@
 					ldap_err2string( res ) );
 
 				/* cleanup... */
-				(void)backsql_free_entryID( op, id, 0 );
+				(void)backsql_free_entryID( id, 0, op->o_tmpmemctx );
 			}
 
 			if ( dn.bv_val != row.cols[ 3 ] ) {
@@ -516,8 +545,8 @@
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 
 #ifdef BACKSQL_PRETTY_VALIDATE
-	validate = at->bam_ad->ad_type->sat_syntax->ssyn_validate;
-	pretty =  at->bam_ad->ad_type->sat_syntax->ssyn_pretty;
+	validate = at->bam_true_ad->ad_type->sat_syntax->ssyn_validate;
+	pretty =  at->bam_true_ad->ad_type->sat_syntax->ssyn_pretty;
 
 	if ( validate == NULL && pretty == NULL ) {
 		return 1;
@@ -525,8 +554,8 @@
 #endif /* BACKSQL_PRETTY_VALIDATE */
 
 #ifdef BACKSQL_COUNTQUERY
-	if ( at->bam_ad->ad_type->sat_equality ) {
-		normfunc = at->bam_ad->ad_type->sat_equality->smr_normalize;
+	if ( at->bam_true_ad->ad_type->sat_equality ) {
+		normfunc = at->bam_true_ad->ad_type->sat_equality->smr_normalize;
 	}
 
 	/* Count how many rows will be returned. This avoids memory 
@@ -583,13 +612,12 @@
 		return 1;
 	}
 
-	attr = attr_find( bsi->bsi_e->e_attrs, at->bam_ad );
+	attr = attr_find( bsi->bsi_e->e_attrs, at->bam_true_ad );
 	if ( attr != NULL ) {
 		BerVarray	tmp;
 
 		if ( attr->a_vals != NULL ) {
-			for ( ; !BER_BVISNULL( &attr->a_vals[ oldcount ] ); oldcount++ )
-				/* just count */ ;
+			oldcount = attr->a_numvals;
 		}
 
 		tmp = ch_realloc( attr->a_vals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
@@ -610,22 +638,20 @@
 		} else {
 			attr->a_nvals = attr->a_vals;
 		}
+		attr->a_numvals += count;
 
 	} else {
 		append = 1;
 
 		/* Make space for the array of values */
-		attr = (Attribute *) ch_malloc( sizeof( Attribute ) );
-		attr->a_desc = at->bam_ad;
-		attr->a_flags = 0;
-		attr->a_next = NULL;
+		attr = attr_alloc( at->bam_true_ad );
+		attr->a_numvals = count;
 		attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) );
 		if ( attr->a_vals == NULL ) {
 			Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 );
 			ch_free( attr );
 			return 1;
 		}
-		memset( attr->a_vals, 0, ( count + 1 ) * sizeof( struct berval ) );
 		if ( normfunc ) {
 			attr->a_nvals = ch_calloc( count + 1, sizeof( struct berval ) );
 			if ( attr->a_nvals == NULL ) {
@@ -633,8 +659,6 @@
 				ch_free( attr );
 				return 1;
 
-			} else {
-				memset( attr->a_nvals, 0, ( count + 1 ) * sizeof( struct berval ) );
 			}
 
 		} else {
@@ -738,22 +762,38 @@
 				}
 #endif /* BACKSQL_TRACE */
 
-				/*
-				 * FIXME: what if a binary 
-				 * is fetched?
+				/* ITS#3386, ITS#3113 - 20070308
+				 * If a binary is fetched?
+				 * must use the actual size read
+				 * from the database.
 				 */
-				ber_str2bv( row.cols[ i ], 0, 0, &bv );
+				if ( BACKSQL_IS_BINARY( row.col_type[ i ] ) ) {
+#ifdef BACKSQL_TRACE
+					Debug( LDAP_DEBUG_ANY,
+						"==>backsql_get_attr_vals(\"%s\"): "
+						"column name %s: data is binary; "
+						"using database size %ld\n",
+						bsi->bsi_e->e_name.bv_val,
+						ad->ad_cname.bv_val,
+						row.value_len[ i ] );
+#endif /* BACKSQL_TRACE */
+					bv.bv_val = row.cols[ i ];
+					bv.bv_len = row.value_len[ i ];
 
+				} else {
+					ber_str2bv( row.cols[ i ], 0, 0, &bv );
+				}
+
 #ifdef BACKSQL_PRETTY_VALIDATE
 				if ( pretty ) {
 					struct berval	pbv;
 
-					retval = pretty( at->bam_ad->ad_type->sat_syntax,
+					retval = pretty( at->bam_true_ad->ad_type->sat_syntax,
 						&bv, &pbv, bsi->bsi_op->o_tmpmemctx );
 					bv = pbv;
 
 				} else {
-					retval = validate( at->bam_ad->ad_type->sat_syntax,
+					retval = validate( at->bam_true_ad->ad_type->sat_syntax,
 						&bv );
 				}
 
@@ -779,7 +819,7 @@
 
 #ifndef BACKSQL_COUNTQUERY
 				(void)backsql_entry_addattr( bsi->bsi_e, 
-						at->bam_ad, &bv,
+						at->bam_true_ad, &bv,
 						bsi->bsi_op->o_tmpmemctx );
 
 #else /* BACKSQL_COUNTQUERY */
@@ -787,8 +827,8 @@
 					struct berval	nbv;
 
 					retval = (*normfunc)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
-						at->bam_ad->ad_type->sat_syntax,
-						at->bam_ad->ad_type->sat_equality,
+						at->bam_true_ad->ad_type->sat_syntax,
+						at->bam_true_ad->ad_type->sat_equality,
 						&bv, &nbv,
 						bsi->bsi_op->o_tmpmemctx );
 
@@ -912,8 +952,11 @@
 	bsi->bsi_e->e_attrs = NULL;
 	bsi->bsi_e->e_private = NULL;
 
-	bsi->bsi_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private,
+	if ( eid->eid_oc == NULL ) {
+		eid->eid_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private,
 			eid->eid_oc_id );
+	}
+	bsi->bsi_oc = eid->eid_oc;
 	bsi->bsi_c_eid = eid;
 
 #ifndef BACKSQL_ARBITRARY_KEY	
@@ -1009,8 +1052,7 @@
 			const char	*text = NULL;
 			char		textbuf[ 1024 ];
 			size_t		textlen = sizeof( textbuf );
-			struct berval	soc_name,
-					bv[ 2 ],
+			struct berval	bv[ 2 ],
 					*nvals;
 			int		rc = LDAP_SUCCESS;
 
@@ -1025,8 +1067,8 @@
 				nvals = bv;
 			}
 
-			rc = structural_class( nvals, &soc_name, &soc, 
-					&text, textbuf, textlen );
+			rc = structural_class( nvals, &soc, NULL, 
+					&text, textbuf, textlen, op->o_tmpmemctx );
 			if ( rc != LDAP_SUCCESS ) {
       				Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
 					"structural_class() failed %d (%s)\n",

Modified: openldap/trunk/servers/slapd/back-sql/init.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/init.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/init.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/init.c,v 1.47.2.14 2007/08/22 21:37:58 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/init.c,v 1.73.2.3 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -27,6 +27,7 @@
 #include "ac/string.h"
 
 #include "slap.h"
+#include "config.h"
 #include "proto-sql.h"
 
 int
@@ -37,9 +38,10 @@
 		LDAP_CONTROL_ASSERT,
 		LDAP_CONTROL_MANAGEDSAIT,
 		LDAP_CONTROL_NOOP,
-#if 0 /* SLAP_CONTROL_X_TREE_DELETE */
+#ifdef SLAP_CONTROL_X_TREE_DELETE
 		SLAP_CONTROL_X_TREE_DELETE,
 #endif /* SLAP_CONTROL_X_TREE_DELETE */
+		LDAP_CONTROL_PAGEDRESULTS,
 		NULL
 	};
 
@@ -75,7 +77,6 @@
 	bi->bi_entry_release_rw = backsql_entry_release;
  
 	bi->bi_connection_init = 0;
-	bi->bi_connection_destroy = backsql_connection_destroy;
 
 	Debug( LDAP_DEBUG_TRACE,"<==sql_back_initialize()\n", 0, 0, 0 );
 	return 0;
@@ -92,7 +93,8 @@
 
 int
 backsql_db_init(
-	BackendDB 	*bd )
+	BackendDB 	*bd,
+	ConfigReply	*cr )
 {
 	backsql_info	*bi;
 	int		rc = 0;
@@ -116,19 +118,16 @@
 
 int
 backsql_db_destroy(
-	BackendDB 	*bd )
+	BackendDB 	*bd,
+	ConfigReply	*cr )
 {
 	backsql_info	*bi = (backsql_info*)bd->be_private;
  
 	Debug( LDAP_DEBUG_TRACE, "==>backsql_db_destroy()\n", 0, 0, 0 );
 
-	ldap_pvt_thread_mutex_lock( &bi->sql_dbconn_mutex );
 	backsql_free_db_env( bi );
-	ldap_pvt_thread_mutex_unlock( &bi->sql_dbconn_mutex );
 	ldap_pvt_thread_mutex_destroy( &bi->sql_dbconn_mutex );
-	ldap_pvt_thread_mutex_lock( &bi->sql_schema_mutex );
 	backsql_destroy_schema_map( bi );
-	ldap_pvt_thread_mutex_unlock( &bi->sql_schema_mutex );
 	ldap_pvt_thread_mutex_destroy( &bi->sql_schema_mutex );
 
 	if ( bi->sql_dbname ) {
@@ -157,6 +156,9 @@
 	if ( !BER_BVISNULL( &bi->sql_children_cond ) ) {
 		ch_free( bi->sql_children_cond.bv_val );
 	}
+	if ( !BER_BVISNULL( &bi->sql_dn_match_cond ) ) {
+		ch_free( bi->sql_dn_match_cond.bv_val );
+	}
 	if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) {
 		ch_free( bi->sql_subtree_cond.bv_val );
 	}
@@ -216,15 +218,18 @@
 
 int
 backsql_db_open(
-	BackendDB 	*bd )
+	BackendDB 	*bd,
+	ConfigReply	*cr )
 {
 	backsql_info 	*bi = (backsql_info*)bd->be_private;
-	SQLHDBC 	dbh = SQL_NULL_HDBC;
 	struct berbuf	bb = BB_NULL;
 
-	OperationBuffer	opbuf;
-	Operation*	op = (Operation *) &opbuf;
-	
+	Connection	conn = { 0 };
+	OperationBuffer opbuf;
+	Operation*	op;
+	SQLHDBC		dbh = SQL_NULL_HDBC;
+	void		*thrctx = ldap_pvt_thread_pool_context();
+
 	Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
 		"testing RDBMS connection\n", 0, 0, 0 );
 	if ( bi->sql_dbname == NULL ) {
@@ -315,18 +320,20 @@
 		};
 		struct berbuf	bb = BB_NULL;
 
+		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+			"subtree search SQL condition not specified "
+			"(use \"subtree_cond\" directive in slapd.conf); "
+			"preparing default\n", 
+			0, 0, 0);
+
 		if ( backsql_prepare_pattern( bi->sql_concat_func, values, 
 				&concat ) ) {
 			Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
-				"unable to prepare CONCAT pattern", 0, 0, 0 );
+				"unable to prepare CONCAT pattern for subtree search",
+				0, 0, 0 );
 			return 1;
 		}
 			
-		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
-			"subtree search SQL condition not specified "
-			"(use \"subtree_cond\" directive in slapd.conf)\n", 
-			0, 0, 0);
-
 		if ( bi->sql_upper_func.bv_val ) {
 
 			/*
@@ -358,42 +365,112 @@
 		bi->sql_subtree_cond = bb.bb_val;
 			
 		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
-			"setting \"%s\" as default\n",
+			"setting \"%s\" as default \"subtree_cond\"\n",
 			bi->sql_subtree_cond.bv_val, 0, 0 );
 	}
 
 	if ( bi->sql_children_cond.bv_val == NULL ) {
+		/*
+		 * Prepare concat function for children search condition
+		 */
+		struct berval	concat;
+		struct berval	values[] = {
+			BER_BVC( "'%,'" ),
+			BER_BVC( "?" ),
+			BER_BVNULL
+		};
 		struct berbuf	bb = BB_NULL;
 
+		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+			"children search SQL condition not specified "
+			"(use \"children_cond\" directive in slapd.conf); "
+			"preparing default\n", 
+			0, 0, 0);
+
+		if ( backsql_prepare_pattern( bi->sql_concat_func, values, 
+				&concat ) ) {
+			Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+				"unable to prepare CONCAT pattern for children search", 0, 0, 0 );
+			return 1;
+		}
+			
 		if ( bi->sql_upper_func.bv_val ) {
 
 			/*
 			 * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?))
 			 */
 
-			backsql_strfcat_x( &bb, NULL, "blbl",
+			backsql_strfcat_x( &bb, NULL, "blbbb",
 					&bi->sql_upper_func,
+					(ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ),
+						"(ldap_entries.dn) LIKE ",
+					&bi->sql_upper_func_open,
+					&concat,
+					&bi->sql_upper_func_close );
+
+		} else {
+
+			/*
+			 * ldap_entries.dn LIKE CONCAT('%,',?)
+			 */
+
+			backsql_strfcat_x( &bb, NULL, "lb",
+					(ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ),
+						"ldap_entries.dn LIKE ",
+					&concat );
+		}
+
+		ch_free( concat.bv_val );
+
+		bi->sql_children_cond = bb.bb_val;
+			
+		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+			"setting \"%s\" as default \"children_cond\"\n",
+			bi->sql_children_cond.bv_val, 0, 0 );
+	}
+
+	if ( bi->sql_dn_match_cond.bv_val == NULL ) {
+		/*
+		 * Prepare concat function for dn match search condition
+		 */
+		struct berbuf	bb = BB_NULL;
+
+		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+			"DN match search SQL condition not specified "
+			"(use \"dn_match_cond\" directive in slapd.conf); "
+			"preparing default\n", 
+			0, 0, 0);
+
+		if ( bi->sql_upper_func.bv_val ) {
+
+			/*
+			 * UPPER(ldap_entries.dn)=?
+			 */
+
+			backsql_strfcat_x( &bb, NULL, "blbcb",
+					&bi->sql_upper_func,
 					(ber_len_t)STRLENOF( "(ldap_entries.dn)=" ),
 						"(ldap_entries.dn)=",
-					&bi->sql_upper_func,
-					(ber_len_t)STRLENOF( "(?)" ), "(?)" );
+					&bi->sql_upper_func_open,
+					'?',
+					&bi->sql_upper_func_close );
 
 		} else {
 
 			/*
-			 * ldap_entries.dn LIKE CONCAT('%,',?)
+			 * ldap_entries.dn=?
 			 */
 
 			backsql_strfcat_x( &bb, NULL, "l",
 					(ber_len_t)STRLENOF( "ldap_entries.dn=?" ),
-						"ldap_entries.dn=?");
+						"ldap_entries.dn=?" );
 		}
 
-		bi->sql_children_cond = bb.bb_val;
+		bi->sql_dn_match_cond = bb.bb_val;
 			
 		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
-			"setting \"%s\" as default\n",
-			bi->sql_children_cond.bv_val, 0, 0 );
+			"setting \"%s\" as default \"dn_match_cond\"\n",
+			bi->sql_dn_match_cond.bv_val, 0, 0 );
 	}
 
 	if ( bi->sql_oc_query == NULL ) {
@@ -469,8 +546,8 @@
 	}
 
 	/* This should just be to force schema loading */
-	op->o_hdr = (Opheader *)&op[ 1 ];
-	op->o_connid = (unsigned long)(-1);
+	connection_fake_init( &conn, &opbuf, thrctx );
+	op = &opbuf.ob_op;
 	op->o_bd = bd;
 	if ( backsql_get_db_conn( op, &dbh ) != LDAP_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
@@ -482,7 +559,7 @@
 			"schema mapping failed, exiting\n", 0, 0, 0 );
 		return 1;
 	}
-	if ( backsql_free_db_conn( op ) != SQL_SUCCESS ) {
+	if ( backsql_free_db_conn( op, dbh ) != SQL_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
 			"connection free failed\n", 0, 0, 0 );
 	}
@@ -526,7 +603,7 @@
 	}
 
 	/*
-	 * Prepare children ID selection query
+	 * Prepare children count query
 	 */
 	BER_BVZERO( &bb.bb_val );
 	bb.bb_len = 0;
@@ -535,7 +612,7 @@
 			"FROM ldap_entries,ldap_entries ",
 			&bi->sql_aliasing, "subordinates "
 			"WHERE subordinates.parent=ldap_entries.id AND ",
-			&bi->sql_children_cond );
+			&bi->sql_dn_match_cond );
 	bi->sql_has_children_query = bb.bb_val.bv_val;
  
 	/*
@@ -567,7 +644,8 @@
 
 int
 backsql_db_close(
-	BackendDB	*bd )
+	BackendDB	*bd,
+	ConfigReply	*cr )
 {
 	backsql_info 	*bi = (backsql_info*)bd->be_private;
 
@@ -580,23 +658,6 @@
 	return 0;
 }
 
-int
-backsql_connection_destroy( Backend *bd, Connection *c )
-{
-	OperationBuffer opbuf;
-	Operation*	op = (Operation *) &opbuf;
-
-	op->o_hdr = (Opheader *)&op[ 1 ];
-	op->o_connid = c->c_connid;
-	op->o_bd = bd;
-
-	Debug( LDAP_DEBUG_TRACE, "==>backsql_connection_destroy()\n", 0, 0, 0 );
-	backsql_free_db_conn( op );
-	Debug( LDAP_DEBUG_TRACE, "<==backsql_connection_destroy()\n", 0, 0, 0 );
-
-	return 0;
-}
-
 #if SLAPD_SQL == SLAPD_MOD_DYNAMIC
 
 /* conditionally define the init_module() function */

Modified: openldap/trunk/servers/slapd/back-sql/modify.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/modify.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/modify.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/modify.c,v 1.31.2.11 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/modify.c,v 1.53.2.4 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -67,7 +67,7 @@
 			LDAP_SCOPE_BASE, 
 			(time_t)(-1), NULL, dbh, op, rs,
 			slap_anlist_all_attributes,
-			( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
+			( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY | BACKSQL_ISF_GET_OC ) );
 	switch ( rs->sr_err ) {
 	case LDAP_SUCCESS:
 		break;
@@ -124,17 +124,17 @@
 
 	slap_mods_opattrs( op, &op->orm_modlist, 1 );
 
-	oc = backsql_id2oc( bi, bsi.bsi_base_id.eid_oc_id );
-	assert( oc != NULL );
+	assert( bsi.bsi_base_id.eid_oc != NULL );
+	oc = bsi.bsi_base_id.eid_oc;
 
-	if ( !acl_check_modlist( op, &m, op->oq_modify.rs_modlist ) ) {
+	if ( !acl_check_modlist( op, &m, op->orm_modlist ) ) {
 		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
 		e = &m;
 		goto done;
 	}
 
 	rs->sr_err = backsql_modify_internal( op, rs, dbh, oc,
-			&bsi.bsi_base_id, op->oq_modify.rs_modlist );
+			&bsi.bsi_base_id, op->orm_modlist );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		e = &m;
 		goto do_transact;
@@ -152,10 +152,10 @@
 			goto do_transact;
 		}
 
-		rs->sr_err = entry_schema_check( op, &m, NULL, 0,
+		rs->sr_err = entry_schema_check( op, &m, NULL, 0, 0,
 			&rs->sr_text, textbuf, sizeof( textbuf ) );
 		if ( rs->sr_err != LDAP_SUCCESS ) {
-			Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+			Debug( LDAP_DEBUG_TRACE, "   backsql_modify(\"%s\"): "
 				"entry failed schema check -- aborting\n",
 				m.e_name.bv_val, 0, 0 );
 			e = NULL;
@@ -175,7 +175,6 @@
 	SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
 
 done:;
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 	if ( e != NULL ) {
 		if ( !access_allowed( op, e, slap_schema.si_ad_entry, NULL,
 					ACL_DISCLOSE, NULL ) )
@@ -189,7 +188,6 @@
 			}
 		}
 	}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 
 	if ( op->o_noop && rs->sr_err == LDAP_SUCCESS ) {
 		rs->sr_err = LDAP_X_NO_OPERATION;
@@ -199,7 +197,7 @@
 	slap_graduate_commit_csn( op );
 
 	if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-		(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
 	}
 
 	if ( !BER_BVISNULL( &m.e_nname ) ) {

Modified: openldap/trunk/servers/slapd/back-sql/modrdn.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/modrdn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/modrdn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/modrdn.c,v 1.14.2.10 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/modrdn.c,v 1.39.2.4 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -44,16 +44,12 @@
 				*new_pdn = NULL, *new_npdn = NULL,
 				new_dn = BER_BVNULL, new_ndn = BER_BVNULL,
 				realnew_dn = BER_BVNULL;
-	LDAPRDN			new_rdn = NULL;
-	LDAPRDN			old_rdn = NULL;
 	Entry			r = { 0 },
 				p = { 0 },
 				n = { 0 },
 				*e = NULL;
 	int			manageDSAit = get_manageDSAit( op );
-	Modifications		*mod = NULL;
 	struct berval		*newSuperior = op->oq_modrdn.rs_newSup;
-	char			*next;
  
 	Debug( LDAP_DEBUG_TRACE, "==>backsql_modrdn() renaming entry \"%s\", "
 			"newrdn=\"%s\", newSuperior=\"%s\"\n",
@@ -76,7 +72,7 @@
 			LDAP_SCOPE_BASE, 
 			(time_t)(-1), NULL, dbh, op, rs,
 			slap_anlist_all_attributes,
-			( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
+			( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY | BACKSQL_ISF_GET_OC ) );
 	switch ( rs->sr_err ) {
 	case LDAP_SUCCESS:
 		break;
@@ -168,6 +164,7 @@
 	 */
 	bsi.bsi_e = &p;
 	e_id = bsi.bsi_base_id;
+	memset( &bsi.bsi_base_id, 0, sizeof( bsi.bsi_base_id ) );
 	rs->sr_err = backsql_init_search( &bsi, &pndn,
 			LDAP_SCOPE_BASE, 
 			(time_t)(-1), NULL, dbh, op, rs,
@@ -201,7 +198,7 @@
 	}
 
 	if ( newSuperior ) {
-		(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
 		
 		/*
 		 * namingContext "" is not supported
@@ -263,6 +260,8 @@
 		new_npdn = &pndn;
 	}
 
+	memset( &bsi.bsi_base_id, 0, sizeof( bsi.bsi_base_id ) );
+
 	if ( newSuperior && dn_match( &pndn, new_npdn ) ) {
 		Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(): "
 			"newSuperior is equal to old parent - ignored\n",
@@ -395,49 +394,13 @@
 	}
 	SQLFreeStmt( sth, SQL_DROP );
 
-	/*
-	 * Get attribute type and attribute value of our new rdn,
-	 * we will need to add that to our new entry
-	 */
-	if ( ldap_bv2rdn( &op->oq_modrdn.rs_newrdn, &new_rdn, &next, 
-				LDAP_DN_FORMAT_LDAP ) )
-	{
-		Debug( LDAP_DEBUG_TRACE,
-			"   backsql_modrdn: can't figure out "
-			"type(s)/values(s) of new_rdn\n", 
-			0, 0, 0 );
-		rs->sr_err = LDAP_INVALID_DN_SYNTAX;
-		e = &r;
-		goto done;
-	}
+	assert( op->orr_modlist != NULL );
 
-	Debug( LDAP_DEBUG_TRACE, "backsql_modrdn: "
-		"new_rdn_type=\"%s\", new_rdn_val=\"%s\"\n",
-		new_rdn[ 0 ]->la_attr.bv_val,
-		new_rdn[ 0 ]->la_value.bv_val, 0 );
+	slap_mods_opattrs( op, &op->orr_modlist, 1 );
 
-	if ( op->oq_modrdn.rs_deleteoldrdn ) {
-		if ( ldap_bv2rdn( &op->o_req_dn, &old_rdn, &next,
-					LDAP_DN_FORMAT_LDAP ) )
-		{
-			Debug( LDAP_DEBUG_TRACE,
-				"   backsql_modrdn: can't figure out "
-				"the old_rdn type(s)/value(s)\n", 
-				0, 0, 0 );
-			rs->sr_err = LDAP_OTHER;
-			e = NULL;
-			goto done;
-		}
-	}
-
-	rs->sr_err = slap_modrdn2mods( op, rs, &r, old_rdn, new_rdn, &mod );
-	if ( rs->sr_err != LDAP_SUCCESS ) {
-		e = &r;
-		goto done;
-	}
-
-	oc = backsql_id2oc( bi, e_id.eid_oc_id );
-	rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id, mod );
+	assert( e_id.eid_oc != NULL );
+	oc = e_id.eid_oc;
+	rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id, op->orr_modlist );
 	slap_graduate_commit_csn( op );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		e = &r;
@@ -448,7 +411,7 @@
 		char		textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
 
 		backsql_entry_clean( op, &r );
-		(void)backsql_free_entryID( op, &e_id, 0 );
+		(void)backsql_free_entryID( &e_id, 0, op->o_tmpmemctx );
 
 		bsi.bsi_e = &r;
 		rs->sr_err = backsql_init_search( &bsi, &new_ndn,
@@ -492,10 +455,10 @@
 
 		e_id = bsi.bsi_base_id;
 
-		rs->sr_err = entry_schema_check( op, &r, NULL, 0,
+		rs->sr_err = entry_schema_check( op, &r, NULL, 0, 0,
 			&rs->sr_text, textbuf, sizeof( textbuf ) );
 		if ( rs->sr_err != LDAP_SUCCESS ) {
-			Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
+			Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(\"%s\"): "
 				"entry failed schema check -- aborting\n",
 				r.e_name.bv_val, 0, 0 );
 			e = NULL;
@@ -504,7 +467,6 @@
 	}
 
 done:;
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 	if ( e != NULL ) {
 		if ( !access_allowed( op, e, slap_schema.si_ad_entry, NULL,
 					ACL_DISCLOSE, NULL ) )
@@ -518,7 +480,6 @@
 			}
 		}
 	}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 
 	/*
 	 * Commit only if all operations succeed
@@ -552,27 +513,12 @@
 		slap_sl_free( new_ndn.bv_val, op->o_tmpmemctx );
 	}
 	
-	/* LDAP v2 supporting correct attribute handling. */
-	if ( new_rdn != NULL ) {
-		ldap_rdnfree( new_rdn );
-	}
-	if ( old_rdn != NULL ) {
-		ldap_rdnfree( old_rdn );
-	}
-	if ( mod != NULL ) {
-		Modifications *tmp;
-		for (; mod; mod = tmp ) {
-			tmp = mod->sml_next;
-			free( mod );
-		}
-	}
-
 	if ( !BER_BVISNULL( &e_id.eid_ndn ) ) {
-		(void)backsql_free_entryID( op, &e_id, 0 );
+		(void)backsql_free_entryID( &e_id, 0, op->o_tmpmemctx );
 	}
 
 	if ( !BER_BVISNULL( &n_id.eid_ndn ) ) {
-		(void)backsql_free_entryID( op, &n_id, 0 );
+		(void)backsql_free_entryID( &n_id, 0, op->o_tmpmemctx );
 	}
 
 	if ( !BER_BVISNULL( &r.e_nname ) ) {

Modified: openldap/trunk/servers/slapd/back-sql/operational.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/operational.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/operational.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/operational.c,v 1.9.2.6 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/operational.c,v 1.21.2.4 2007/09/29 09:55:22 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -53,9 +53,9 @@
 		return NULL;
 	}
 
-	a = ch_malloc( sizeof( Attribute ) );
-	a->a_desc = desc;
+	a = attr_alloc( desc );
 
+	a->a_numvals = 1;
 	a->a_vals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
 	a->a_vals[ 0 ] = val;
 	BER_BVZERO( &a->a_vals[ 1 ] );
@@ -63,9 +63,6 @@
 	a->a_nvals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
 	a->a_nvals[ 0 ] = nval;
 	BER_BVZERO( &a->a_nvals[ 1 ] );
-	
-	a->a_next = NULL;
-	a->a_flags = 0;
 
 	return a;
 }
@@ -77,8 +74,8 @@
 	struct berval	entryCSN;
 	Attribute	*a;
 
-	a = ch_malloc( sizeof( Attribute ) );
-	a->a_desc = slap_schema.si_ad_entryCSN;
+	a = attr_alloc( slap_schema.si_ad_entryCSN );
+	a->a_numvals = 1;
 	a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
 	BER_BVZERO( &a->a_vals[ 1 ] );
 
@@ -100,9 +97,6 @@
 
 	a->a_nvals = a->a_vals;
 
-	a->a_next = NULL;
-	a->a_flags = 0;
-
 	return a;
 }
 
@@ -197,7 +191,7 @@
 
 		*ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id );
 
-		(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
 
 		if ( bsi.bsi_attrs != NULL ) {
 			op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );

Modified: openldap/trunk/servers/slapd/back-sql/proto-sql.h
===================================================================
--- openldap/trunk/servers/slapd/back-sql/proto-sql.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/proto-sql.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -111,25 +111,33 @@
 #endif /* BACKSQL_ARBITRARY_KEY */
 
 /* stores in *id the ID in table ldap_entries corresponding to DN, if any */
-int backsql_dn2id( Operation *op, SlapReply *rs, SQLHDBC dbh,
+extern int
+backsql_dn2id( Operation *op, SlapReply *rs, SQLHDBC dbh,
 		struct berval *ndn, backsql_entryID *id,
 		int matched, int muck );
 
 /* stores in *nchildren the count of children for an entry */
-int backsql_count_children( Operation *op, SQLHDBC dbh,
+extern int
+backsql_count_children( Operation *op, SQLHDBC dbh,
 		struct berval *dn, unsigned long *nchildren );
 
 /* returns LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE if the entry corresponding
  * to DN has/has not children */
-int backsql_has_children( Operation *op, SQLHDBC dbh, struct berval *dn );
+extern int
+backsql_has_children( Operation *op, SQLHDBC dbh, struct berval *dn );
 
-/* frees *id and returns next in list */
-backsql_entryID *backsql_free_entryID( Operation *op, backsql_entryID *id,
-		int freeit );
+/* free *id and return next in list */
+extern backsql_entryID *
+backsql_free_entryID( backsql_entryID *id, int freeit, void *ctx );
 
-/* turns an ID into an entry */
-int backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *id );
+/* turn an ID into an entry */
+extern int
+backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *id );
 
+/* duplicate an entryID */
+extern backsql_entryID *
+backsql_entryID_dup( backsql_entryID *eid, void *ctx );
+
 /*
  * operational.c
  */
@@ -219,9 +227,9 @@
 
 int backsql_free_db_env( backsql_info *si );
 
-int backsql_get_db_conn( Operation *op, SQLHDBC *dbh );
+int backsql_get_db_conn( Operation *op, SQLHDBC	*dbh );
 
-int backsql_free_db_conn( Operation *op );
+int backsql_free_db_conn( Operation *op, SQLHDBC dbh );
 
 /*
  * util.c

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/ibmdb2/slapd.conf
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/ibmdb2/slapd.conf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/ibmdb2/slapd.conf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/ibmdb2/slapd.conf,v 1.2.4.1 2005/01/20 18:04:03 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/ibmdb2/slapd.conf,v 1.3 2005/01/05 15:23:00 ando Exp $
 #
 # See slapd.conf(5) for details on configuration options.
 # This file should NOT be world readable.

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf,v 1.5.2.1 2005/01/20 18:04:03 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf,v 1.6 2005/01/05 15:23:00 ando Exp $
 #
 # See slapd.conf(5) for details on configuration options.
 # This file should NOT be world readable.

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_create.sql
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_create.sql	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_create.sql	2007-12-15 10:25:31 UTC (rev 892)
@@ -32,8 +32,13 @@
 	pers_id int NOT NULL 
 );
 
+drop table if exists certs;
+CREATE TABLE certs (
+	id int NOT NULL ,
+	cert LONGBLOB NOT NULL,
+	pers_id int NOT NULL 
+);
 
-
 ALTER TABLE authors_docs  ADD 
 	CONSTRAINT PK_authors_docs PRIMARY KEY  
 	(
@@ -66,6 +71,12 @@
 		id
 	); 
 
+ALTER TABLE certs  ADD 
+	CONSTRAINT PK_certs PRIMARY KEY  
+	(
+		id
+	); 
+
 drop table if exists referrals;
 CREATE TABLE referrals (
 	id int NOT NULL,

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_data.sql
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_data.sql	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_data.sql	2007-12-15 10:25:31 UTC (rev 892)
@@ -16,3 +16,6 @@
 insert into authors_docs (pers_id,doc_id) values (2,1);
 
 insert into referrals (id,name,url) values (1,'Referral','ldap://localhost:9012/');
+
+insert into certs (id,cert,pers_id) values (1,UNHEX('3082036b308202d4a003020102020102300d06092a864886f70d01010405003077310b3009060355040613025553311330110603550408130a43616c69666f726e6961311f301d060355040a13164f70656e4c444150204578616d706c652c204c74642e311330110603550403130a4578616d706c65204341311d301b06092a864886f70d010901160e6361406578616d706c652e636f6d301e170d3033313031373136333331395a170d3034313031363136333331395a307e310b3009060355040613025553311330110603550408130a43616c69666f726e6961311f301d060355040a13164f70656e4c444150204578616d706c652c204c74642e311830160603550403130f557273756c612048616d7073746572311f301d06092a864886f70d01090116107568616d406578616d706c652e636f6d30819f300d06092a864886f70d010101050003818d0030818902818100eec60a7910b57d2e687158ca55eea738d36f10413dfecf31435e1aeeb9713b8e2da7dd2dde6bc6cec03b4987eaa7b037b9eb50e11c71e58088cc282883122cd8329c6f24f6045e6be9d21b9190c8292998267a5f7905292de936262747ab4b76a88a63872c41629a69d32e894d44c896a8d06fab0a1bc7de343c6c1458478f290203010001a381ff3081fc30090603551d1304023000302c06096086480186f842010d041f161d4f70656e53534c2047656e657261746564204365727469666963617465301d0603551d0e04160414a323de136c19ae0c479450e882dfb10ad147f45e3081a10603551d2304819930819680144b6f211a3624d290f943b053472d7de1c0e69823a17ba4793077310b3009060355040613025553311330110603550408130a43616c69666f726e6961311f301d060355040a13164f70656e4c444150204578616d706c652c204c74642e311330110603550403130a4578616d706c65204341311d301b06092a864886f70d010901160e6361406578616d706c652e636f6d820100300d06092a864886f70d010104050003818100881470045bdce95660d6e6af59e6a844aec4b9f5eaea88d4eb7a5a47080afa64750f81a3e47d00fd39c69a17a1c66d29d36f06edc537107f8c592239c2d4da55fb3f1d488e7b2387ad2a551cbd1ceb070ae9e020a9467275cb28798abb4cbfff98ddb3f1e7689b067072392511bb08125b5bec2bc207b7b6b275c47248f29acd'),3);
+

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql	2007-12-15 10:25:31 UTC (rev 892)
@@ -80,6 +80,10 @@
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
 values (14,4,'ref','referrals.url','referrals',NULL,NULL,NULL,3,0);
 
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
+values (15,1,'userCertificate','certs.cert','persons,certs',
+        'certs.pers_id=persons.id',NULL,NULL,3,0);
+
 -- entries mapping: each entry must appear in this table, with a unique DN rooted at the database naming context
 --	id		a unique number > 0 identifying the entry
 --	dn		the DN of the entry, in "pretty" form
@@ -114,5 +118,8 @@
 values (1,'dcObject');
 
 insert into ldap_entry_objclasses (entry_id,oc_name)
+values (4,'pkiUser');
+
+insert into ldap_entry_objclasses (entry_id,oc_name)
 values (7,'extensibleObject');
 

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf,v 1.4.6.1 2005/01/20 18:04:03 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf,v 1.5 2005/01/05 15:23:00 ando Exp $
 #
 # See slapd.conf(5) for details on configuration options.
 # This file should NOT be world readable.

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/slapd.conf
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/slapd.conf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/slapd.conf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/pgsql/slapd.conf,v 1.4.2.1 2005/01/20 18:04:03 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/pgsql/slapd.conf,v 1.5 2005/01/05 15:23:01 ando Exp $
 #
 # See slapd.conf(5) for details on configuration options.
 # This file should NOT be world readable.

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_create.sql
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_create.sql	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_create.sql	2007-12-15 10:25:31 UTC (rev 892)
@@ -37,6 +37,14 @@
 	pers_id int not null
 );
 
+drop table certs;
+drop sequence certs_id_seq;
+CREATE TABLE certs (
+	id int not null primary key,
+	cert bytea not null,
+	pers_id int not null 
+);
+ 
 drop table referrals;
 drop sequence referrals_id_seq;
 create table referrals (

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_data.sql
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_data.sql	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_data.sql	2007-12-15 10:25:31 UTC (rev 892)
@@ -16,3 +16,6 @@
 insert into authors_docs (pers_id,doc_id) values (2,1);
 
 insert into referrals (id,name,url) values (1,'Referral','ldap://localhost:9012/');
+
+insert into certs (id,cert,pers_id) values (1,decode('MIIDazCCAtSgAwIBAgIBAjANBgkqhkiG9w0BAQQFADB3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhcNMDMxMDE3MTYzMzE5WhcNMDQxMDE2MTYzMzE5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjEYMBYGA1UEAxMPVXJzdWxhIEhhbXBzdGVyMR8wHQYJKoZIhvcNAQkBFhB1aGFtQGV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDuxgp5ELV9LmhxWMpV7qc4028QQT3+zzFDXhruuXE7ji2n3S3ea8bOwDtJh+qnsDe561DhHHHlgIjMKCiDEizYMpxvJPYEXmvp0huRkMgpKZgmel95BSkt6TYmJ0erS3aoimOHLEFimmnTLolNRMiWqNBvqwobx940PGwUWEePKQIDAQABo4H/MIH8MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSjI94TbBmuDEeUUOiC37EK0Uf0XjCBoQYDVR0jBIGZMIGWgBRLbyEaNiTSkPlDsFNHLX3hwOaYI6F7pHkwdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExHzAdBgNVBAoTFk9wZW5MREFQIEV4YW1wbGUsIEx0ZC4xEzARBgNVBAMTCkV4YW1wbGUgQ0ExHTAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBAIgUcARb3OlWYNbmr1nmqESuxLn16uqI1Ot6WkcICvpkdQ+Bo+R9AP05xpoXocZtKdNvBu3FNxB/jFkiOcLU2lX7Px1Ijnsjh60qVRy9HOsHCungIKlGcnXLKHmKu0y//5jds/HnaJsGcHI5JRG7CBJbW+wrwge3trJ1xHJI8prN','base64'),3);
+

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql	2007-12-15 10:25:31 UTC (rev 892)
@@ -55,6 +55,8 @@
 
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (14,4,'ref','referrals.url','referrals',NULL,'UPDATE referrals SET url=? WHERE id=?','SELECT 1 FROM referrals WHERE url=? and id=? and 1=0',3,0);
 
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (15,1,'userCertificate','certs.cert','persons,certs','certs.pers_id=persons.id',NULL,NULL,3,0);
+
 -- entries mapping: each entry must appear in this table, with a unique DN rooted at the database naming context
 --	id		a unique number > 0 identifying the entry
 --	dn		the DN of the entry, in "pretty" form
@@ -80,6 +82,8 @@
 --	oc_name		the name of the objectClass; it MUST match the name of an objectClass that is loaded in slapd's schema
 insert into ldap_entry_objclasses (entry_id,oc_name) values (1,'dcObject');
 
+insert into ldap_entry_objclasses (entry_id,oc_name) values (4,'pkiUser');
+
 insert into ldap_entry_objclasses (entry_id,oc_name) values (7,'extensibleObject');
 
 -- procedures

Modified: openldap/trunk/servers/slapd/back-sql/rdbms_depend/timesten/slapd.conf
===================================================================
--- openldap/trunk/servers/slapd/back-sql/rdbms_depend/timesten/slapd.conf	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/rdbms_depend/timesten/slapd.conf	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/timesten/slapd.conf,v 1.1.6.1 2005/01/20 18:04:03 kurt Exp $
+# $OpenLDAP: pkg/ldap/servers/slapd/back-sql/rdbms_depend/timesten/slapd.conf,v 1.2 2005/01/05 15:23:01 ando Exp $
 #
 # See slapd.conf(5) for details on configuration options.
 # This file should NOT be world readable.

Modified: openldap/trunk/servers/slapd/back-sql/schema-map.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/schema-map.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/schema-map.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/schema-map.c,v 1.44.2.11 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/schema-map.c,v 1.59.2.4 2007/11/15 22:13:38 ando Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -74,7 +74,15 @@
 	const backsql_at_map_rec	*m1 = v_m1,
 					*m2 = v_m2;
 
+	if ( slap_ad_is_binary( m1->bam_ad ) || slap_ad_is_binary( m2->bam_ad ) ) {
 #ifdef BACKSQL_USE_PTR_CMP
+		return SLAP_PTRCMP( m1->bam_ad->ad_type, m2->bam_ad->ad_type );
+#else /* ! BACKSQL_USE_PTR_CMP */
+		return ber_bvcmp( &m1->bam_ad->ad_type->sat_cname, &m2->bam_ad->ad_type->sat_cname );
+#endif /* ! BACKSQL_USE_PTR_CMP */
+	}
+
+#ifdef BACKSQL_USE_PTR_CMP
 	return SLAP_PTRCMP( m1->bam_ad, m2->bam_ad );
 #else /* ! BACKSQL_USE_PTR_CMP */
 	return ber_bvcmp( &m1->bam_ad->ad_cname, &m2->bam_ad->ad_cname );
@@ -87,12 +95,26 @@
 	backsql_at_map_rec		*m1 = v_m1,
 					*m2 = v_m2;
 
-	assert( m1->bam_ad == m2->bam_ad );
+	if ( slap_ad_is_binary( m1->bam_ad ) || slap_ad_is_binary( m2->bam_ad ) ) {
+#ifdef BACKSQL_USE_PTR_CMP
+		assert( m1->bam_ad->ad_type == m2->bam_ad->ad_type );
+#else /* ! BACKSQL_USE_PTR_CMP */
+		assert( ber_bvcmp( &m1->bam_ad->ad_type->sat_cname, &m2->bam_ad->ad_type->sat_cname ) == 0 );
+#endif /* ! BACKSQL_USE_PTR_CMP */
 
+	} else {
+#ifdef BACKSQL_USE_PTR_CMP
+		assert( m1->bam_ad == m2->bam_ad );
+#else /* ! BACKSQL_USE_PTR_CMP */
+		assert( ber_bvcmp( &m1->bam_ad->ad_cname, &m2->bam_ad->ad_cname ) == 0 );
+#endif /* ! BACKSQL_USE_PTR_CMP */
+	}
+
 	/* duplicate definitions of attributeTypes are appended;
 	 * this allows to define multiple rules for the same 
 	 * attributeType.  Use with care! */
 	for ( ; m1->bam_next ; m1 = m1->bam_next );
+
 	m1->bam_next = m2;
 	m2->bam_next = NULL;
 
@@ -178,6 +200,7 @@
 	at_map = (backsql_at_map_rec *)ch_calloc(1, 
 			sizeof( backsql_at_map_rec ) );
 	at_map->bam_ad = slap_schema.si_ad_objectClass;
+	at_map->bam_true_ad = slap_schema.si_ad_objectClass;
 	ber_str2bv( "ldap_entry_objclasses.oc_name", 0, 1,
 			&at_map->bam_sel_expr );
 	ber_str2bv( "ldap_entry_objclasses,ldap_entries", 0, 1, 
@@ -350,9 +373,29 @@
 		at_map = (backsql_at_map_rec *)ch_calloc( 1,
 				sizeof( backsql_at_map_rec ) );
 		at_map->bam_ad = ad;
+		at_map->bam_true_ad = ad;
+		if ( slap_syntax_is_binary( ad->ad_type->sat_syntax )
+			&& !slap_ad_is_binary( ad ) )
+		{
+			char		buf[ BUFSIZ ];
+			struct berval	bv;
+			const char	*text = NULL;
 
+			bv.bv_val = buf;
+			bv.bv_len = snprintf( buf, sizeof( buf ), "%s;binary",
+				ad->ad_cname.bv_val );
+			at_map->bam_true_ad = NULL;
+			bas->bas_rc = slap_bv2ad( &bv, &at_map->bam_true_ad, &text );
+			if ( bas->bas_rc != LDAP_SUCCESS ) {
+				Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
+					"unable to fetch attribute \"%s\": %s (%d)\n",
+					buf, text, rc );
+				return BACKSQL_AVL_STOP;
+			}
+		}
+
 		ber_str2bv( at_row.cols[ 1 ], 0, 1, &at_map->bam_sel_expr );
-		if ( at_row.value_len[ 8 ] < 0 ) {
+		if ( at_row.value_len[ 8 ] <= 0 ) {
 			BER_BVZERO( &at_map->bam_sel_expr_u );
 
 		} else {
@@ -363,7 +406,7 @@
 		ber_str2bv( at_row.cols[ 2 ], 0, 0, &bv );
 		backsql_merge_from_clause( bas->bas_bi, &bb, &bv );
 		at_map->bam_from_tbls = bb.bb_val;
-		if ( at_row.value_len[ 3 ] < 0 ) {
+		if ( at_row.value_len[ 3 ] <= 0 ) {
 			BER_BVZERO( &at_map->bam_join_where );
 
 		} else {
@@ -499,16 +542,16 @@
 		
 		ber_str2bv( oc_row.cols[ 2 ], 0, 1, &oc_map->bom_keytbl );
 		ber_str2bv( oc_row.cols[ 3 ], 0, 1, &oc_map->bom_keycol );
-		oc_map->bom_create_proc = ( oc_row.value_len[ 4 ] < 0 ) ? NULL 
+		oc_map->bom_create_proc = ( oc_row.value_len[ 4 ] <= 0 ) ? NULL 
 			: ch_strdup( oc_row.cols[ 4 ] );
 
 		colnum = 5;
 		if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) {
 			colnum = 6;
-			oc_map->bom_create_keyval = ( oc_row.value_len[ 5 ] < 0 ) 
+			oc_map->bom_create_keyval = ( oc_row.value_len[ 5 ] <= 0 ) 
 				? NULL : ch_strdup( oc_row.cols[ 5 ] );
 		}
-		oc_map->bom_delete_proc = ( oc_row.value_len[ colnum ] < 0 ) ? NULL 
+		oc_map->bom_delete_proc = ( oc_row.value_len[ colnum ] <= 0 ) ? NULL 
 			: ch_strdup( oc_row.cols[ colnum ] );
 		if ( lutil_atoix( &oc_map->bom_expect_return, oc_row.cols[ colnum + 1 ], 0 ) != 0 ) {
 			Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
@@ -717,7 +760,7 @@
 backsql_at_map_rec *
 backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
 {
-	backsql_at_map_rec	tmp, *res;
+	backsql_at_map_rec	tmp = { 0 }, *res;
  
 #ifdef BACKSQL_TRACE
 	Debug( LDAP_DEBUG_TRACE, "==>backsql_ad2at(): "

Modified: openldap/trunk/servers/slapd/back-sql/search.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/search.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/search.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/search.c,v 1.81.2.13 2007/03/05 18:39:51 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/search.c,v 1.117.2.6 2007/11/08 19:16:50 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -42,6 +42,23 @@
 static int backsql_process_filter_attr( backsql_srch_info *bsi, Filter *f, 
 		backsql_at_map_rec *at );
 
+/* For LDAP_CONTROL_PAGEDRESULTS, a 32 bit cookie is available to keep track of
+   the state of paged results. The ldap_entries.id and oc_map_id values of the
+   last entry returned are used as the cookie, so 6 bits are used for the OC id
+   and the other 26 for ldap_entries ID number. If your max(oc_map_id) is more
+   than 63, you will need to steal more bits from ldap_entries ID number and
+   put them into the OC ID part of the cookie. */
+#define SQL_TO_PAGECOOKIE(id, oc) (((id) << 6 ) | ((oc) & 0x3F))
+#define PAGECOOKIE_TO_SQL_ID(pc) ((pc) >> 6)
+#define PAGECOOKIE_TO_SQL_OC(pc) ((pc) & 0x3F)
+
+static int parse_paged_cookie( Operation *op, SlapReply *rs );
+
+static void send_paged_response( 
+	Operation *op,
+	SlapReply *rs,
+	ID  *lastid );
+
 static int
 backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
 {
@@ -62,6 +79,11 @@
 		return 1;
 	}
 
+	/* strip ';binary' */
+	if ( slap_ad_is_binary( ad ) ) {
+		ad = ad->ad_type->sat_ad;
+	}
+
 	for ( ; !BER_BVISNULL( &bsi->bsi_attrs[ n_attrs ].an_name ); n_attrs++ ) {
 		an = &bsi->bsi_attrs[ n_attrs ];
 		
@@ -317,6 +339,17 @@
 				rs->sr_err = rc;
 			}
 		}
+
+		if ( gotit && BACKSQL_IS_GET_OC( flags ) ) {
+			bsi->bsi_base_id.eid_oc = backsql_id2oc( bi,
+				bsi->bsi_base_id.eid_oc_id );
+			if ( bsi->bsi_base_id.eid_oc == NULL ) {
+				/* error? */
+				backsql_free_entryID( &bsi->bsi_base_id, 1,
+					op->o_tmpmemctx );
+				rc = rs->sr_err = LDAP_OTHER;
+			}
+		}
 	}
 
 	bsi->bsi_status = rc;
@@ -1490,6 +1523,7 @@
 					(ber_len_t)STRLENOF( "9=9"), "9=9");
 
 		} else if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) {
+			/* This should always be true... */
 			backsql_strfcat_x( &bsi->bsi_join_where,
 					bsi->bsi_op->o_tmpmemctx,
 					"b",
@@ -1517,6 +1551,30 @@
 		assert( 0 );
 	}
 
+	/* If paged results are in effect, ignore low ldap_entries.id numbers */
+	if ( get_pagedresults(bsi->bsi_op) > SLAP_CONTROL_IGNORED ) {
+		unsigned long lowid = 0;
+
+		/* Pick up the previous ldap_entries.id if the previous page ended in this objectClass */
+		if ( bsi->bsi_oc->bom_id == PAGECOOKIE_TO_SQL_OC( ((PagedResultsState *)bsi->bsi_op->o_pagedresults_state)->ps_cookie ) )
+		{
+			lowid = PAGECOOKIE_TO_SQL_ID( ((PagedResultsState *)bsi->bsi_op->o_pagedresults_state)->ps_cookie );
+		}
+
+		if ( lowid ) {
+			char lowidstring[48];
+			int  lowidlen;
+
+			lowidlen = snprintf( lowidstring, sizeof( lowidstring ),
+				" AND ldap_entries.id>%lu", lowid );
+			backsql_strfcat_x( &bsi->bsi_join_where,
+					bsi->bsi_op->o_tmpmemctx,
+					"l",
+					(ber_len_t)lowidlen,
+					lowidstring );
+		}
+	}
+
 	rc = backsql_process_filter( bsi, bsi->bsi_filter );
 	if ( rc > 0 ) {
 		struct berbuf	bb = BB_NULL;
@@ -1596,6 +1654,14 @@
 		return BACKSQL_AVL_STOP;
 	}
 
+	/* If paged results have already completed this objectClass, skip it */
+	if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
+		if ( oc->bom_id < PAGECOOKIE_TO_SQL_OC( ((PagedResultsState *)op->o_pagedresults_state)->ps_cookie ) )
+		{
+			return BACKSQL_AVL_CONTINUE;
+		}
+	}
+
 	if ( bsi->bsi_n_candidates == -1 ) {
 		Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
 			"unchecked limit has been overcome\n", 0, 0, 0 );
@@ -1860,6 +1926,7 @@
 			goto cleanup;
 		}
 #endif /* ! BACKSQL_ARBITRARY_KEY */
+		c_id->eid_oc = bsi->bsi_oc;
 		c_id->eid_oc_id = bsi->bsi_oc->bom_id;
 
 		c_id->eid_dn = pdn;
@@ -1921,6 +1988,7 @@
 	backsql_srch_info	bsi = { 0 };
 	backsql_entryID		*eid = NULL;
 	struct berval		nbase = BER_BVNULL;
+	unsigned long 		lastid = 0;
 
 	Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): "
 		"base=\"%s\", filter=\"%s\", scope=%d,", 
@@ -1992,7 +2060,6 @@
 		/* fall thru */
 
 	default:
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 		if ( !BER_BVISNULL( &base_entry.e_nname )
 				&& !access_allowed( op, &base_entry,
 					slap_schema.si_ad_entry, NULL,
@@ -2006,7 +2073,6 @@
 			rs->sr_matched = NULL;
 			rs->sr_text = NULL;
 		}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 
 		send_ldap_result( op, rs );
 
@@ -2021,7 +2087,6 @@
 
 		goto done;
 	}
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 	/* NOTE: __NEW__ "search" access is required
 	 * on searchBase object */
 	{
@@ -2052,7 +2117,6 @@
 			goto done;
 		}
 	}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 
 	bsi.bsi_e = NULL;
 
@@ -2061,6 +2125,15 @@
 		( op->ors_limit->lms_s_unchecked == -1 ? -2 :
 		( op->ors_limit->lms_s_unchecked ) ) );
 
+	/* If paged results are in effect, check the paging cookie */
+	if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) {
+		rs->sr_err = parse_paged_cookie( op, rs );
+		if ( rs->sr_err != LDAP_SUCCESS ) {
+			send_ldap_result( op, rs );
+			goto done;
+		}
+	}
+
 	switch ( bsi.bsi_scope ) {
 	case LDAP_SCOPE_BASE:
 	case BACKSQL_SCOPE_BASE_LIKE:
@@ -2088,9 +2161,9 @@
 		/*
 		 * for each objectclass we try to construct query which gets IDs
 		 * of entries matching LDAP query filter and scope (or at least 
-		 * candidates), and get the IDs
+		 * candidates), and get the IDs. Do this in ID order for paging.
 		 */
-		avl_apply( bi->sql_oc_by_oc, backsql_oc_get_candidates,
+		avl_apply( bi->sql_oc_by_id, backsql_oc_get_candidates,
 				&bsi, BACKSQL_AVL_STOP, AVL_INORDER );
 
 		/* check for abandon */
@@ -2116,9 +2189,9 @@
 	 * and then send to client; don't free entry_id if baseObject...
 	 */
 	for ( eid = bsi.bsi_id_list;
-			eid != NULL; 
-			eid = backsql_free_entryID( op,
-				eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )
+		eid != NULL; 
+		eid = backsql_free_entryID( 
+			eid, eid == &bsi.bsi_base_id ? 0 : 1, op->o_tmpmemctx ) )
 	{
 		int		rc;
 		Attribute	*a_hasSubordinate = NULL,
@@ -2267,6 +2340,9 @@
 			rs->sr_ref = NULL;
 			rs->sr_matched = NULL;
 			rs->sr_entry = NULL;
+			if ( rs->sr_err == LDAP_REFERRAL ) {
+				rs->sr_err = LDAP_SUCCESS;
+			}
 
 			goto next_entry;
 		}
@@ -2333,12 +2409,24 @@
 
 		if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE )
 		{
+			/* If paged results are in effect, see if the page limit was exceeded */
+			if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
+				if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size )
+				{
+					e = NULL;
+					send_paged_response( op, rs, &lastid );
+					goto done;
+				}
+				lastid = SQL_TO_PAGECOOKIE( eid->eid_id, eid->eid_oc_id );
+			}
 			rs->sr_attrs = op->ors_attrs;
 			rs->sr_operational_attrs = NULL;
 			rs->sr_entry = e;
+			e->e_private = (void *)eid;
 			rs->sr_flags = ( e == &user_entry ) ? REP_ENTRY_MODIFIABLE : 0;
 			/* FIXME: need the whole entry (ITS#3480) */
 			rs->sr_err = send_search_entry( op, rs );
+			e->e_private = NULL;
 			rs->sr_entry = NULL;
 			rs->sr_attrs = NULL;
 			rs->sr_operational_attrs = NULL;
@@ -2378,13 +2466,17 @@
 
 send_results:;
 	if ( rs->sr_err != SLAPD_ABANDON ) {
-		send_ldap_result( op, rs );
+		if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
+			send_paged_response( op, rs, NULL );
+		} else {
+			send_ldap_result( op, rs );
+		}
 	}
 
 	/* cleanup in case of abandon */
 	for ( ; eid != NULL; 
-			eid = backsql_free_entryID( op,
-				eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )
+		eid = backsql_free_entryID(
+			eid, eid == &bsi.bsi_base_id ? 0 : 1, op->o_tmpmemctx ) )
 		;
 
 	backsql_entry_clean( op, &base_entry );
@@ -2401,25 +2493,28 @@
 	if ( op->o_sync ) {
 		Operation	op2 = *op;
 		SlapReply	rs2 = { 0 };
-		Entry		e = { 0 };
+		Entry		*e = entry_alloc();
 		slap_callback	cb = { 0 };
 
 		op2.o_tag = LDAP_REQ_ADD;
-		op2.o_bd = select_backend( &op->o_bd->be_nsuffix[0], 0, 0 );
-		op2.ora_e = &e;
+		op2.o_bd = select_backend( &op->o_bd->be_nsuffix[0], 0 );
+		op2.ora_e = e;
 		op2.o_callback = &cb;
 
-		e.e_name = op->o_bd->be_suffix[0];
-		e.e_nname = op->o_bd->be_nsuffix[0];
+		ber_dupbv( &e->e_name, op->o_bd->be_suffix );
+		ber_dupbv( &e->e_nname, op->o_bd->be_nsuffix );
 
 		cb.sc_response = slap_null_cb;
 
 		op2.o_bd->be_add( &op2, &rs2 );
+
+		if ( op2.ora_e == e )
+			entry_free( e );
 	}
 #endif /* BACKSQL_SYNCPROV */
 
 done:;
-	(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+	(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
 
 	if ( bsi.bsi_attrs != NULL ) {
 		op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
@@ -2462,8 +2557,8 @@
 	*ent = NULL;
 
 	rc = backsql_get_db_conn( op, &dbh );
-	if ( !dbh ) {
-		return LDAP_OTHER;
+	if ( rc != LDAP_SUCCESS ) {
+		return rc;
 	}
 
 	if ( at ) {
@@ -2472,7 +2567,7 @@
 		BER_BVZERO( &anlist[ 1 ].an_name );
 	}
 
-	bsi.bsi_e = ch_malloc( sizeof( Entry ) );
+	bsi.bsi_e = entry_alloc();
 	rc = backsql_init_search( &bsi,
 			ndn,
 			LDAP_SCOPE_BASE, 
@@ -2481,7 +2576,7 @@
 			BACKSQL_ISF_GET_ENTRY );
 
 	if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
-		(void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
 	}
 
 	if ( rc == LDAP_SUCCESS ) {
@@ -2563,7 +2658,112 @@
 {
 	backsql_entry_clean( op, e );
 
-	ch_free( e );
+	entry_free( e );
 
 	return 0;
 }
+
+
+/* This function is copied verbatim from back-bdb/search.c */
+static int
+parse_paged_cookie( Operation *op, SlapReply *rs )
+{
+	int		rc = LDAP_SUCCESS;
+	PagedResultsState *ps = op->o_pagedresults_state;
+
+	/* this function must be invoked only if the pagedResults
+	 * control has been detected, parsed and partially checked
+	 * by the frontend */
+	assert( get_pagedresults( op ) > SLAP_CONTROL_IGNORED );
+
+	/* cookie decoding/checks deferred to backend... */
+	if ( ps->ps_cookieval.bv_len ) {
+		PagedResultsCookie reqcookie;
+		if( ps->ps_cookieval.bv_len != sizeof( reqcookie ) ) {
+			/* bad cookie */
+			rs->sr_text = "paged results cookie is invalid";
+			rc = LDAP_PROTOCOL_ERROR;
+			goto done;
+		}
+
+		AC_MEMCPY( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie ));
+
+		if ( reqcookie > ps->ps_cookie ) {
+			/* bad cookie */
+			rs->sr_text = "paged results cookie is invalid";
+			rc = LDAP_PROTOCOL_ERROR;
+			goto done;
+
+		} else if ( reqcookie < ps->ps_cookie ) {
+			rs->sr_text = "paged results cookie is invalid or old";
+			rc = LDAP_UNWILLING_TO_PERFORM;
+			goto done;
+		}
+
+	} else {
+		/* Initial request.  Initialize state. */
+		ps->ps_cookie = 0;
+		ps->ps_count = 0;
+	}
+
+done:;
+
+	return rc;
+}
+
+/* This function is copied nearly verbatim from back-bdb/search.c */
+static void
+send_paged_response( 
+	Operation	*op,
+	SlapReply	*rs,
+	unsigned long	*lastid )
+{
+	LDAPControl	ctrl, *ctrls[2];
+	BerElementBuffer berbuf;
+	BerElement	*ber = (BerElement *)&berbuf;
+	PagedResultsCookie respcookie;
+	struct berval cookie;
+
+	Debug(LDAP_DEBUG_ARGS,
+		"send_paged_response: lastid=0x%08lx nentries=%d\n", 
+		lastid ? *lastid : 0, rs->sr_nentries, NULL );
+
+	BER_BVZERO( &ctrl.ldctl_value );
+	ctrls[0] = &ctrl;
+	ctrls[1] = NULL;
+
+	ber_init2( ber, NULL, LBER_USE_DER );
+
+	if ( lastid ) {
+		respcookie = ( PagedResultsCookie )(*lastid);
+		cookie.bv_len = sizeof( respcookie );
+		cookie.bv_val = (char *)&respcookie;
+
+	} else {
+		respcookie = ( PagedResultsCookie )0;
+		BER_BVSTR( &cookie, "" );
+	}
+
+	op->o_conn->c_pagedresults_state.ps_cookie = respcookie;
+	op->o_conn->c_pagedresults_state.ps_count =
+		((PagedResultsState *)op->o_pagedresults_state)->ps_count +
+		rs->sr_nentries;
+
+	/* return size of 0 -- no estimate */
+	ber_printf( ber, "{iO}", 0, &cookie ); 
+
+	if ( ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 ) == -1 ) {
+		goto done;
+	}
+
+	ctrls[0]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
+	ctrls[0]->ldctl_iscritical = 0;
+
+	rs->sr_ctrls = ctrls;
+	rs->sr_err = LDAP_SUCCESS;
+	send_ldap_result( op, rs );
+	rs->sr_ctrls = NULL;
+
+done:
+	(void) ber_free_buf( ber );
+}

Modified: openldap/trunk/servers/slapd/back-sql/sql-wrap.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/sql-wrap.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/sql-wrap.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/sql-wrap.c,v 1.28.2.9 2007/08/22 21:37:58 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/sql-wrap.c,v 1.43.2.3 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.
@@ -32,11 +32,6 @@
 
 #define MAX_ATTR_LEN 16384
 
-typedef struct backsql_db_conn {
-	unsigned long	ldap_cid;
-	SQLHDBC		dbh;
-} backsql_db_conn;
-
 void
 backsql_PrintErrors( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth, int rc )
 {
@@ -132,10 +127,6 @@
 backsql_BindRowAsStrings_x( SQLHSTMT sth, BACKSQL_ROW_NTS *row, void *ctx )
 {
 	RETCODE		rc;
-	SQLCHAR		colname[ 64 ];
-	SQLSMALLINT	name_len, col_type, col_scale, col_null;
-	UDWORD		col_prec;
-	int		i;
 
 	if ( row == NULL ) {
 		return SQL_ERROR;
@@ -155,6 +146,11 @@
 		backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC, sth, rc );
 
 	} else {
+		SQLCHAR		colname[ 64 ];
+		SQLSMALLINT	name_len, col_type, col_scale, col_null;
+		UDWORD		col_prec;
+		int		i;
+
 #ifdef BACKSQL_TRACE
 		Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
 			"ncols=%d\n", (int)row->ncols, 0, 0 );
@@ -162,58 +158,115 @@
 
 		row->col_names = (BerVarray)ber_memcalloc_x( row->ncols + 1, 
 				sizeof( struct berval ), ctx );
-		if ( !row->col_names ) goto nomem3;
+		if ( row->col_names == NULL ) {
+			goto nomem;
+		}
+
+		row->col_prec = (UDWORD *)ber_memcalloc_x( row->ncols,
+				sizeof( UDWORD ), ctx );
+		if ( row->col_prec == NULL ) {
+			goto nomem;
+		}
+
+		row->col_type = (SQLSMALLINT *)ber_memcalloc_x( row->ncols,
+				sizeof( SQLSMALLINT ), ctx );
+		if ( row->col_type == NULL ) {
+			goto nomem;
+		}
+
 		row->cols = (char **)ber_memcalloc_x( row->ncols + 1, 
 				sizeof( char * ), ctx );
-		if ( !row->cols ) goto nomem2;
-		row->col_prec = (UDWORD *)ber_memcalloc_x( row->ncols,
-				sizeof( UDWORD ), ctx );
-		if ( !row->col_prec ) goto nomem1;
+		if ( row->cols == NULL ) {
+			goto nomem;
+		}
+
 		row->value_len = (SQLINTEGER *)ber_memcalloc_x( row->ncols,
 				sizeof( SQLINTEGER ), ctx );
-		if ( !row->value_len ) {
+		if ( row->value_len == NULL ) {
+			goto nomem;
+		}
+
+		if ( 0 ) {
+nomem:
+			ber_memfree_x( row->col_names, ctx );
+			row->col_names = NULL;
 			ber_memfree_x( row->col_prec, ctx );
 			row->col_prec = NULL;
-nomem1:		ber_memfree_x( row->cols, ctx );
+			ber_memfree_x( row->col_type, ctx );
+			row->col_type = NULL;
+			ber_memfree_x( row->cols, ctx );
 			row->cols = NULL;
-nomem2:		ber_memfree_x( row->col_names, ctx );
-			row->col_names = NULL;
-nomem3:		Debug( LDAP_DEBUG_ANY, "backsql_BindRowAsStrings: "
+			ber_memfree_x( row->value_len, ctx );
+			row->value_len = NULL;
+
+			Debug( LDAP_DEBUG_ANY, "backsql_BindRowAsStrings: "
 				"out of memory\n", 0, 0, 0 );
+
 			return LDAP_NO_MEMORY;
 		}
-		for ( i = 1; i <= row->ncols; i++ ) {
-			rc = SQLDescribeCol( sth, (SQLSMALLINT)i, &colname[ 0 ],
+
+		for ( i = 0; i < row->ncols; i++ ) {
+			SQLSMALLINT	TargetType;
+
+			rc = SQLDescribeCol( sth, (SQLSMALLINT)(i + 1), &colname[ 0 ],
 					(SQLUINTEGER)( sizeof( colname ) - 1 ),
 					&name_len, &col_type,
 					&col_prec, &col_scale, &col_null );
 			/* FIXME: test rc? */
 
 			ber_str2bv_x( (char *)colname, 0, 1,
-					&row->col_names[ i - 1 ], ctx );
+					&row->col_names[ i ], ctx );
 #ifdef BACKSQL_TRACE
 			Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
 				"col_name=%s, col_prec[%d]=%d\n",
-				colname, (int)i, (int)col_prec );
+				colname, (int)(i + 1), (int)col_prec );
 #endif /* BACKSQL_TRACE */
 			if ( col_type != SQL_CHAR && col_type != SQL_VARCHAR )
 			{
 				col_prec = MAX_ATTR_LEN;
 			}
 
-			row->cols[ i - 1 ] = (char *)ber_memcalloc_x( col_prec + 1,
+			row->cols[ i ] = (char *)ber_memcalloc_x( col_prec + 1,
 					sizeof( char ), ctx );
-			row->col_prec[ i - 1 ] = col_prec;
-			rc = SQLBindCol( sth, (SQLUSMALLINT)i,
-					 SQL_C_CHAR,
-					 (SQLPOINTER)row->cols[ i - 1 ],
-					 col_prec + 1,
-					 &row->value_len[ i - 1 ] );
+			row->col_prec[ i ] = col_prec;
+			row->col_type[ i ] = col_type;
+
+			/*
+			 * ITS#3386, ITS#3113 - 20070308
+			 * Note: there are many differences between various DPMS and ODBC
+			 * Systems; some support SQL_C_BLOB, SQL_C_BLOB_LOCATOR.  YMMV:
+			 * This has only been tested on Linux/MySQL/UnixODBC
+			 * For BINARY-type Fields (BLOB, etc), read the data as BINARY
+			 */
+			if ( BACKSQL_IS_BINARY( col_type ) ) {
+#ifdef BACKSQL_TRACE
+				Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
+					"col_name=%s, col_type[%d]=%d: reading binary data\n",
+					colname, (int)(i + 1), (int)col_type);
+#endif /* BACKSQL_TRACE */
+				TargetType = SQL_C_BINARY;
+
+			} else {
+				/* Otherwise read it as Character data */
+#ifdef BACKSQL_TRACE
+				Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
+					"col_name=%s, col_type[%d]=%d: reading character data\n",
+					colname, (int)(i + 1), (int)col_type);
+#endif /* BACKSQL_TRACE */
+				TargetType = SQL_C_CHAR;
+			}
+
+			rc = SQLBindCol( sth, (SQLUSMALLINT)(i + 1),
+				 TargetType,
+				 (SQLPOINTER)row->cols[ i ],
+				 col_prec + 1,
+				 &row->value_len[ i ] );
+
 			/* FIXME: test rc? */
 		}
 
-		BER_BVZERO( &row->col_names[ i - 1 ] );
-		row->cols[ i - 1 ] = NULL;
+		BER_BVZERO( &row->col_names[ i ] );
+		row->cols[ i ] = NULL;
 	}
 
 #ifdef BACKSQL_TRACE
@@ -237,8 +290,9 @@
 	}
 
 	ber_bvarray_free_x( row->col_names, ctx );
+	ber_memfree_x( row->col_prec, ctx );
+	ber_memfree_x( row->col_type, ctx );
 	ber_memvfree_x( (void **)row->cols, ctx );
-	ber_memfree_x( row->col_prec, ctx );
 	ber_memfree_x( row->value_len, ctx );
 
 	return SQL_SUCCESS;
@@ -251,30 +305,16 @@
 	return backsql_FreeRow_x( row, NULL );
 }
 
-static int
-backsql_cmp_connid( const void *v_c1, const void *v_c2 )
+static void
+backsql_close_db_handle( SQLHDBC dbh )
 {
-	const backsql_db_conn *c1 = v_c1, *c2 = v_c2;
-	if ( c1->ldap_cid > c2->ldap_cid ) {
-		return 1;
+	if ( dbh == SQL_NULL_HDBC ) {
+		return;
 	}
-	
-	if ( c1->ldap_cid < c2->ldap_cid ) {
-		return -1;
-	}
-	
-	return 0;
-}
 
-static void
-backsql_close_db_conn( void *v_conn )
-{
-	backsql_db_conn	*conn = 	(backsql_db_conn *)v_conn;
-	unsigned long	cid = conn->ldap_cid;
+	Debug( LDAP_DEBUG_TRACE, "==>backsql_close_db_handle(%p)\n",
+		(void *)dbh, 0, 0 );
 
-	Debug( LDAP_DEBUG_TRACE, "==>backsql_close_db_conn(%lu)\n",
-		cid, 0, 0 );
-
 	/*
 	 * Default transact is SQL_ROLLBACK; commit is required only
 	 * by write operations, and it is explicitly performed after
@@ -282,21 +322,18 @@
 	 */
 
 	/* TimesTen */
-	SQLTransact( SQL_NULL_HENV, conn->dbh, SQL_ROLLBACK );
-	SQLDisconnect( conn->dbh );
-	SQLFreeConnect( conn->dbh );
-	ch_free( conn );
+	SQLTransact( SQL_NULL_HENV, dbh, SQL_ROLLBACK );
+	SQLDisconnect( dbh );
+	SQLFreeConnect( dbh );
 
-	Debug( LDAP_DEBUG_TRACE, "<==backsql_close_db_conn(%lu)\n",
-		cid, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE, "<==backsql_close_db_handle(%p)\n",
+		(void *)dbh, 0, 0 );
 }
 
 int
 backsql_conn_destroy(
 	backsql_info	*bi )
 {
-	avl_free( bi->sql_db_conns, backsql_close_db_conn );
-
 	return 0;
 }
 
@@ -341,42 +378,44 @@
 }
 
 static int
-backsql_open_db_conn( backsql_info *bi, unsigned long ldap_cid, backsql_db_conn **pdbc )
+backsql_open_db_handle(
+	backsql_info	*bi,
+	SQLHDBC		*dbhp )
 {
 	/* TimesTen */
 	char			DBMSName[ 32 ];
-	SQLHDBC			dbh = SQL_NULL_HDBC;
-	backsql_db_conn		*dbc;
 	int			rc;
 
-	assert( pdbc != NULL );
-	*pdbc = NULL;
+	assert( dbhp != NULL );
+	*dbhp = SQL_NULL_HDBC;
  
-	Debug( LDAP_DEBUG_TRACE, "==>backsql_open_db_conn(%lu)\n",
-		ldap_cid, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE, "==>backsql_open_db_handle()\n",
+		0, 0, 0 );
 
-	rc = SQLAllocConnect( bi->sql_db_env, &dbh );
+	rc = SQLAllocConnect( bi->sql_db_env, dbhp );
 	if ( !BACKSQL_SUCCESS( rc ) ) {
-		Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
-			"SQLAllocConnect() failed:\n", ldap_cid, 0, 0 );
+		Debug( LDAP_DEBUG_TRACE, "backsql_open_db_handle(): "
+			"SQLAllocConnect() failed:\n",
+			0, 0, 0 );
 		backsql_PrintErrors( bi->sql_db_env, SQL_NULL_HDBC,
-				SQL_NULL_HENV, rc );
+			SQL_NULL_HENV, rc );
 		return LDAP_UNAVAILABLE;
 	}
 
-	rc = SQLConnect( dbh,
-			(SQLCHAR*)bi->sql_dbname, SQL_NTS,
-			(SQLCHAR*)bi->sql_dbuser, SQL_NTS,
-			(SQLCHAR*)bi->sql_dbpasswd, SQL_NTS );
+	rc = SQLConnect( *dbhp,
+		(SQLCHAR*)bi->sql_dbname, SQL_NTS,
+		(SQLCHAR*)bi->sql_dbuser, SQL_NTS,
+		(SQLCHAR*)bi->sql_dbpasswd, SQL_NTS );
 	if ( rc != SQL_SUCCESS ) {
-		Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
+		Debug( LDAP_DEBUG_TRACE, "backsql_open_db_handle(): "
 			"SQLConnect() to database \"%s\" %s.\n",
-			ldap_cid, bi->sql_dbname,
+			bi->sql_dbname,
 			rc == SQL_SUCCESS_WITH_INFO ?
-			"succeeded with info" : "failed" );
-		backsql_PrintErrors( bi->sql_db_env, dbh, SQL_NULL_HENV, rc );
+				"succeeded with info" : "failed",
+			0 );
+		backsql_PrintErrors( bi->sql_db_env, *dbhp, SQL_NULL_HENV, rc );
 		if ( rc != SQL_SUCCESS_WITH_INFO ) {
-			SQLFreeConnect( dbh );
+			SQLFreeConnect( *dbhp );
 			return LDAP_UNAVAILABLE;
 		}
 	}
@@ -385,7 +424,7 @@
 	 * TimesTen : Turn off autocommit.  We must explicitly
 	 * commit any transactions. 
 	 */
-	SQLSetConnectOption( dbh, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF );
+	SQLSetConnectOption( *dbhp, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF );
 
 	/* 
 	 * See if this connection is to TimesTen.  If it is,
@@ -394,114 +433,100 @@
 	/* Assume until proven otherwise */
 	bi->sql_flags &= ~BSQLF_USE_REVERSE_DN;
 	DBMSName[ 0 ] = '\0';
-	rc = SQLGetInfo( dbh, SQL_DBMS_NAME, (PTR)&DBMSName,
+	rc = SQLGetInfo( *dbhp, SQL_DBMS_NAME, (PTR)&DBMSName,
 			sizeof( DBMSName ), NULL );
 	if ( rc == SQL_SUCCESS ) {
 		if ( strcmp( DBMSName, "TimesTen" ) == 0 ||
-				strcmp( DBMSName, "Front-Tier" ) == 0 ) {
-			Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
-				"TimesTen database!\n", ldap_cid, 0, 0 );
+			strcmp( DBMSName, "Front-Tier" ) == 0 )
+		{
+			Debug( LDAP_DEBUG_TRACE, "backsql_open_db_handle(): "
+				"TimesTen database!\n",
+				0, 0, 0 );
 			bi->sql_flags |= BSQLF_USE_REVERSE_DN;
 		}
 
 	} else {
-		Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
-			"SQLGetInfo() failed.\n", ldap_cid, 0, 0 );
-		backsql_PrintErrors( bi->sql_db_env, dbh, SQL_NULL_HENV, rc );
+		Debug( LDAP_DEBUG_TRACE, "backsql_open_db_handle(): "
+			"SQLGetInfo() failed.\n",
+			0, 0, 0 );
+		backsql_PrintErrors( bi->sql_db_env, *dbhp, SQL_NULL_HENV, rc );
+		SQLDisconnect( *dbhp );
+		SQLFreeConnect( *dbhp );
+		return LDAP_UNAVAILABLE;
 	}
 	/* end TimesTen */
 
-	dbc = (backsql_db_conn *)ch_calloc( 1, sizeof( backsql_db_conn ) );
-	dbc->ldap_cid = ldap_cid;
-	dbc->dbh = dbh;
+	Debug( LDAP_DEBUG_TRACE, "<==backsql_open_db_handle()\n",
+		0, 0, 0 );
 
-	*pdbc = dbc;
-
-	Debug( LDAP_DEBUG_TRACE, "<==backsql_open_db_conn(%lu)\n", ldap_cid, 0, 0 );
-
-	return rc;
+	return LDAP_SUCCESS;
 }
 
 int
-backsql_free_db_conn( Operation *op )
+backsql_free_db_conn( Operation *op, SQLHDBC dbh )
 {
-	backsql_info		*bi = (backsql_info *)op->o_bd->be_private;
-	backsql_db_conn		tmp = { 0 },
-				*conn;
-
 	Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_conn()\n", 0, 0, 0 );
-	tmp.ldap_cid = op->o_connid;
-	ldap_pvt_thread_mutex_lock( &bi->sql_dbconn_mutex );
-	conn = avl_delete( &bi->sql_db_conns, &tmp, backsql_cmp_connid );
-	ldap_pvt_thread_mutex_unlock( &bi->sql_dbconn_mutex );
 
-	/*
-	 * we have one thread per connection, as I understand -- so we can
-	 * get this out of critical section
-	 */
-	if ( conn != NULL ) {
-		Debug( LDAP_DEBUG_TRACE, "backsql_free_db_conn(): "
-			"closing db connection %lu (%p)\n",
-			op->o_connid, (void *)conn, 0 );
-		backsql_close_db_conn( (void *)conn );
-	}
+	(void)backsql_close_db_handle( dbh );
 
 	Debug( LDAP_DEBUG_TRACE, "<==backsql_free_db_conn()\n", 0, 0, 0 );
 
-	return conn ? SQL_SUCCESS : SQL_ERROR;
+	return LDAP_SUCCESS;
 }
 
+static void	*backsql_db_conn_dummy;
+
+static void
+backsql_db_conn_keyfree(
+	void		*key,
+	void		*data )
+{
+	backsql_close_db_handle( (SQLHDBC)data );
+}
+
 int
-backsql_get_db_conn( Operation *op, SQLHDBC *dbh )
+backsql_get_db_conn( Operation *op, SQLHDBC *dbhp )
 {
-	backsql_info		*bi = (backsql_info *)op->o_bd->be_private;
-	backsql_db_conn		*dbc,
-				tmp = { 0 };
-	int			rc = LDAP_SUCCESS;
+	backsql_info	*bi = (backsql_info *)op->o_bd->be_private;
+	int		rc = LDAP_SUCCESS;
+	SQLHDBC		dbh = SQL_NULL_HDBC;
 
 	Debug( LDAP_DEBUG_TRACE, "==>backsql_get_db_conn()\n", 0, 0, 0 );
 
-	assert( dbh != NULL );
-	*dbh = SQL_NULL_HDBC;
+	assert( dbhp != NULL );
+	*dbhp = SQL_NULL_HDBC;
 
-	tmp.ldap_cid = op->o_connid;
+	if ( op->o_threadctx ) {
+		void		*data = NULL;
 
-	/*
-	 * we have one thread per connection, as I understand -- 
-	 * so we do not need locking here
-	 */
-	ldap_pvt_thread_mutex_lock( &bi->sql_dbconn_mutex );
-	dbc = avl_find( bi->sql_db_conns, &tmp, backsql_cmp_connid );
-	ldap_pvt_thread_mutex_unlock( &bi->sql_dbconn_mutex );
-	if ( !dbc ) {
-		rc = backsql_open_db_conn( bi, op->o_connid, &dbc );
-		if ( rc != LDAP_SUCCESS) {
-			Debug( LDAP_DEBUG_TRACE, "backsql_get_db_conn(): "
-				"could not get connection handle "
-				"-- returning NULL\n", 0, 0, 0 );
+		ldap_pvt_thread_pool_getkey( op->o_threadctx,
+				&backsql_db_conn_dummy, &data, NULL );
+		dbh = (SQLHDBC)data;
+
+	} else {
+		dbh = bi->sql_dbh;
+	}
+
+	if ( dbh == SQL_NULL_HDBC ) {
+		rc = backsql_open_db_handle( bi, &dbh );
+		if ( rc != LDAP_SUCCESS ) {
 			return rc;
+		}
 
+		if ( op->o_threadctx ) {
+			void		*data = NULL;
+
+			data = (void *)dbh;
+			ldap_pvt_thread_pool_setkey( op->o_threadctx,
+					&backsql_db_conn_dummy, data,
+					backsql_db_conn_keyfree );
+
 		} else {
-			int	ret;
-
-			Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
-				"connected, adding to tree.\n",
-				op->o_connid, 0, 0 );
-			ldap_pvt_thread_mutex_lock( &bi->sql_dbconn_mutex );
-			ret = avl_insert( &bi->sql_db_conns, dbc, backsql_cmp_connid, avl_dup_error );
-			ldap_pvt_thread_mutex_unlock( &bi->sql_dbconn_mutex );
-			if ( ret != 0 ) {
-				Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
-					"duplicate connection ID.\n",
-					op->o_connid, 0, 0 );
-				backsql_close_db_conn( (void *)dbc );
-				dbc = NULL;
-				return LDAP_OTHER;
-			}
+			bi->sql_dbh = dbh;
 		}
 	}
 
-	*dbh = dbc->dbh;
+	*dbhp = dbh;
 
 	Debug( LDAP_DEBUG_TRACE, "<==backsql_get_db_conn()\n", 0, 0, 0 );
 

Modified: openldap/trunk/servers/slapd/back-sql/util.c
===================================================================
--- openldap/trunk/servers/slapd/back-sql/util.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/back-sql/util.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/util.c,v 1.31.2.10 2007/01/02 21:44:07 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/back-sql/util.c,v 1.45.2.2 2007/08/31 23:14:05 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/backend.c
===================================================================
--- openldap/trunk/servers/slapd/backend.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/backend.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* backend.c - routines for dealing with back-end databases */
-/* $OpenLDAP: pkg/ldap/servers/slapd/backend.c,v 1.288.2.26 2007/07/22 15:04:25 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/backend.c,v 1.362.2.7 2007/09/29 09:55:21 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -34,6 +34,7 @@
 #include <sys/stat.h>
 
 #include "slap.h"
+#include "config.h"
 #include "lutil.h"
 #include "lber_pvt.h"
 
@@ -189,7 +190,7 @@
 }
 
 /* startup a specific backend database */
-int backend_startup_one(Backend *be)
+int backend_startup_one(Backend *be, ConfigReply *cr)
 {
 	int		rc = 0;
 
@@ -208,8 +209,19 @@
 	/* set database controls */
 	(void)backend_set_controls( be );
 
+#if 0
+	if ( !BER_BVISEMPTY( &be->be_rootndn )
+		&& select_backend( &be->be_rootndn, 0 ) == be
+		&& BER_BVISNULL( &be->be_rootpw ) )
+	{
+		/* warning: if rootdn entry is created,
+		 * it can take rootdn privileges;
+		 * set empty rootpw to prevent */
+	}
+#endif
+
 	if ( be->bd_info->bi_db_open ) {
-		rc = be->bd_info->bi_db_open( be );
+		rc = be->bd_info->bi_db_open( be, cr );
 		if ( rc == 0 ) {
 			(void)backend_set_controls( be );
 
@@ -228,6 +240,7 @@
 	int i;
 	int rc = 0;
 	BackendInfo *bi;
+	ConfigReply cr={0, ""};
 
 	if( ! ( nBackendDB > 0 ) ) {
 		/* no databases */
@@ -250,12 +263,13 @@
 		}
 		/* append global access controls */
 		acl_append( &be->be_acl, frontendDB->be_acl, -1 );
-		return backend_startup_one( be );
+
+		return backend_startup_one( be, &cr );
 	}
 
 	/* open frontend, if required */
 	if ( frontendDB->bd_info->bi_db_open ) {
-		rc = frontendDB->bd_info->bi_db_open( frontendDB );
+		rc = frontendDB->bd_info->bi_db_open( frontendDB, NULL );
 		if ( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
 				"backend_startup: bi_db_open(frontend) failed! (%d)\n",
@@ -299,7 +313,7 @@
 		/* append global access controls */
 		acl_append( &be->be_acl, frontendDB->be_acl, -1 );
 
-		rc = backend_startup_one( be );
+		rc = backend_startup_one( be, &cr );
 
 		if ( rc ) return rc;
 	}
@@ -335,7 +349,7 @@
 		}
 
 		if ( be->bd_info->bi_db_close ) {
-			be->bd_info->bi_db_close( be );
+			be->bd_info->bi_db_close( be, NULL );
 		}
 
 		if( be->bd_info->bi_close ) {
@@ -348,7 +362,7 @@
 	/* close each backend database */
 	LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
 		if ( be->bd_info->bi_db_close ) {
-			be->bd_info->bi_db_close( be );
+			be->bd_info->bi_db_close( be, NULL );
 		}
 
 		if(rc != 0) {
@@ -372,7 +386,7 @@
 
 	/* close frontend, if required */
 	if ( frontendDB->bd_info->bi_db_close ) {
-		rc = frontendDB->bd_info->bi_db_close ( frontendDB );
+		rc = frontendDB->bd_info->bi_db_close ( frontendDB, NULL );
 		if ( rc != 0 ) {
 			Debug( LDAP_DEBUG_ANY,
 				"backend_startup: bi_db_close(frontend) failed! (%d)\n",
@@ -383,16 +397,18 @@
 	return 0;
 }
 
-void backend_destroy_one( BackendDB *bd, int dynamic )
+/*
+ * This function is supposed to be the exact counterpart
+ * of backend_startup_one(), although this one calls bi_db_destroy()
+ * while backend_startup_one() calls bi_db_open().
+ *
+ * Make sure backend_stopdown_one() destroys resources allocated
+ * by backend_startup_one(); only call backend_destroy_one() when
+ * all stuff in a BackendDB needs to be destroyed
+ */
+void
+backend_stopdown_one( BackendDB *bd )
 {
-	if ( dynamic ) {
-		LDAP_STAILQ_REMOVE(&backendDB, bd, slap_backend_db, be_next );
-	}
-
-	if ( bd->be_syncinfo ) {
-		syncinfo_free( bd->be_syncinfo );
-	}
-
 	if ( bd->be_pending_csn_list ) {
 		struct slap_csn_entry *csne;
 		csne = LDAP_TAILQ_FIRST( bd->be_pending_csn_list );
@@ -408,8 +424,22 @@
 	}
 
 	if ( bd->bd_info->bi_db_destroy ) {
-		bd->bd_info->bi_db_destroy( bd );
+		bd->bd_info->bi_db_destroy( bd, NULL );
 	}
+}
+
+void backend_destroy_one( BackendDB *bd, int dynamic )
+{
+	if ( dynamic ) {
+		LDAP_STAILQ_REMOVE(&backendDB, bd, BackendDB, be_next );
+	}
+
+	if ( bd->be_syncinfo ) {
+		syncinfo_free( bd->be_syncinfo, 1 );
+	}
+
+	backend_stopdown_one( bd );
+
 	ber_bvarray_free( bd->be_suffix );
 	ber_bvarray_free( bd->be_nsuffix );
 	if ( !BER_BVISNULL( &bd->be_rootdn ) ) {
@@ -423,10 +453,6 @@
 	}
 	acl_destroy( bd->be_acl, frontendDB->be_acl );
 	limits_destroy( bd->be_limits );
-	if ( bd->be_replogfile ) {
-		ch_free( bd->be_replogfile );
-	}
-	destroy_replica_info( bd );
 	if ( !BER_BVISNULL( &bd->be_update_ndn ) ) {
 		ch_free( bd->be_update_ndn.bv_val );
 	}
@@ -463,7 +489,7 @@
 	bd = frontendDB;
 	if ( bd ) {
 		if ( bd->bd_info->bi_db_destroy ) {
-			bd->bd_info->bi_db_destroy( bd );
+			bd->bd_info->bi_db_destroy( bd, NULL );
 		}
 		ber_bvarray_free( bd->be_suffix );
 		ber_bvarray_free( bd->be_nsuffix );
@@ -477,11 +503,6 @@
 			free( bd->be_rootpw.bv_val );
 		}
 		acl_destroy( bd->be_acl, frontendDB->be_acl );
-
-		if ( bd->be_replogfile != NULL ) {
-			free( bd->be_replogfile );
-		}
-		assert( bd->be_replica == NULL );
 	}
 
 	return 0;
@@ -501,13 +522,49 @@
 	return NULL;
 }
 
+void
+backend_db_insert(
+	BackendDB *be,
+	int idx
+)
+{
+	/* If idx < 0, just add to end of list */
+	if ( idx < 0 ) {
+		LDAP_STAILQ_INSERT_TAIL(&backendDB, be, be_next);
+	} else if ( idx == 0 ) {
+		LDAP_STAILQ_INSERT_HEAD(&backendDB, be, be_next);
+	} else {
+		int i;
+		BackendDB *b2;
 
+		b2 = LDAP_STAILQ_FIRST(&backendDB);
+		idx--;
+		for (i=0; i<idx; i++) {
+			b2 = LDAP_STAILQ_NEXT(b2, be_next);
+		}
+		LDAP_STAILQ_INSERT_AFTER(&backendDB, b2, be, be_next);
+	}
+}
+
+void
+backend_db_move(
+	BackendDB *be,
+	int idx
+)
+{
+	LDAP_STAILQ_REMOVE(&backendDB, be, BackendDB, be_next);
+	backend_db_insert(be, idx);
+}
+
 BackendDB *
 backend_db_init(
     const char	*type,
-	BackendDB *be )
+	BackendDB *b0,
+	int idx,
+	ConfigReply *cr)
 {
 	BackendInfo *bi = backend_info(type);
+	BackendDB *be = b0;
 	int	rc = 0;
 
 	if( bi == NULL ) {
@@ -520,8 +577,11 @@
 	 */
 	if ( !be ) {
 		be = ch_calloc( 1, sizeof(Backend) );
+		/* Just append */
+		if ( idx >= nbackends )
+			idx = -1;
 		nbackends++;
-		LDAP_STAILQ_INSERT_TAIL(&backendDB, be, be_next);
+		backend_db_insert( be, idx );
 	}
 
 	be->bd_info = bi;
@@ -540,16 +600,21 @@
 	be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; 
 
 	if ( bi->bi_db_init ) {
-		rc = bi->bi_db_init( be );
+		rc = bi->bi_db_init( be, cr );
 	}
 
 	if ( rc != 0 ) {
 		fprintf( stderr, "database init failed (%s)\n", type );
-		nbackends--;
-		return NULL;
+		/* If we created and linked this be, remove it and free it */
+		if ( !b0 ) {
+			LDAP_STAILQ_REMOVE(&backendDB, be, BackendDB, be_next);
+			ch_free( be );
+			be = NULL;
+			nbackends--;
+		}
+	} else {
+		bi->bi_nDB++;
 	}
-
-	bi->bi_nDB++;
 	return( be );
 }
 
@@ -560,12 +625,12 @@
 
 	LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
 		if ( be->bd_info->bi_db_close ) {
-			be->bd_info->bi_db_close( be );
+			be->bd_info->bi_db_close( be, NULL );
 		}
 	}
 
 	if ( frontendDB->bd_info->bi_db_close ) {
-		(*frontendDB->bd_info->bi_db_close)( frontendDB );
+		frontendDB->bd_info->bi_db_close( frontendDB, NULL );
 	}
 
 }
@@ -573,7 +638,6 @@
 Backend *
 select_backend(
 	struct berval * dn,
-	int manageDSAit, /* unused since ITS#4986 */
 	int noSubs )
 {
 	int		j;
@@ -581,7 +645,7 @@
 	Backend		*be;
 
 	LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
-		if ( be->be_nsuffix == NULL ) {
+		if ( be->be_nsuffix == NULL || SLAP_DBHIDDEN( be )) {
 			continue;
 		}
 
@@ -641,6 +705,26 @@
 }
 
 int
+be_issubordinate(
+    Backend *be,
+    struct berval *bvsubordinate )
+{
+	int	i;
+
+	if ( be->be_nsuffix == NULL ) {
+		return 0;
+	}
+
+	for ( i = 0; !BER_BVISNULL( &be->be_nsuffix[i] ); i++ ) {
+		if ( dnIsSuffix( bvsubordinate, &be->be_nsuffix[i] ) ) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+int
 be_isroot_dn( Backend *be, struct berval *ndn )
 {
 	if ( BER_BVISEMPTY( ndn ) || BER_BVISEMPTY( &be->be_rootndn ) ) {
@@ -660,7 +744,10 @@
 int
 be_shadow_update( Operation *op )
 {
-	return ( SLAP_SYNC_SHADOW( op->o_bd ) ||
+	/* This assumes that all internal ops (connid == -1) on a syncrepl
+	 * database are syncrepl operations.
+	 */
+	return (( SLAP_SYNC_SHADOW( op->o_bd ) && op->o_connid == -1 ) ||
 		( SLAP_SHADOW( op->o_bd ) && be_isupdate_dn( op->o_bd, &op->o_ndn ) ) );
 }
 
@@ -689,14 +776,46 @@
 int
 be_isroot_pw( Operation *op )
 {
-	int result;
+	return be_rootdn_bind( op, NULL ) == LDAP_SUCCESS;
+}
 
-	if ( ! be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
-		return 0;
+/*
+ * checks if binding as rootdn
+ *
+ * return value:
+ *	SLAP_CB_CONTINUE		if not the rootdn
+ *	LDAP_SUCCESS			if rootdn & rootpw
+ *	LDAP_INVALID_CREDENTIALS	if rootdn & !rootpw
+ *
+ * if rs != NULL
+ *	if LDAP_SUCCESS, op->orb_edn is set
+ *	if LDAP_INVALID_CREDENTIALS, response is sent to client
+ */
+int
+be_rootdn_bind( Operation *op, SlapReply *rs )
+{
+	int		rc;
+
+	assert( op->o_tag == LDAP_REQ_BIND );
+	assert( op->orb_method == LDAP_AUTH_SIMPLE );
+
+	if ( !be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
+		return SLAP_CB_CONTINUE;
 	}
 
+	if ( BER_BVISNULL( &op->o_bd->be_rootpw ) ) {
+		/* give the database a chance */
+		return SLAP_CB_CONTINUE;
+	}
+
 	if ( BER_BVISEMPTY( &op->o_bd->be_rootpw ) ) {
-		return 0;
+		/* rootdn bind explicitly disallowed */
+		rc = LDAP_INVALID_CREDENTIALS;
+		if ( rs ) {
+			goto send_result;
+		}
+
+		return rc;
 	}
 
 #ifdef SLAPD_SPASSWD
@@ -704,13 +823,31 @@
 		op->o_conn->c_sasl_authctx, NULL );
 #endif
 
-	result = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL );
+	rc = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL );
 
 #ifdef SLAPD_SPASSWD
 	ldap_pvt_thread_pool_setkey( op->o_threadctx, slap_sasl_bind, NULL, NULL );
 #endif
 
-	return result == 0;
+	rc = ( rc == 0 ? LDAP_SUCCESS : LDAP_INVALID_CREDENTIALS );
+	if ( rs ) {
+send_result:;
+		rs->sr_err = rc;
+
+		Debug( LDAP_DEBUG_TRACE, "%s: rootdn=\"%s\" bind%s\n", 
+			op->o_log_prefix, op->o_bd->be_rootdn.bv_val,
+			rc == LDAP_SUCCESS ? " succeeded" : " failed" );
+
+		if ( rc == LDAP_SUCCESS ) {
+			/* Set to the pretty rootdn */
+     			ber_dupbv( &op->orb_edn, &op->o_bd->be_rootdn );
+
+		} else {
+			send_ldap_result( op, rs );
+		}
+	}
+
+	return rc;
 }
 
 int
@@ -791,27 +928,26 @@
 				/* unrecognized control */ 
 				if ( (*ctrls)->ldctl_iscritical ) {
 					/* should not be reachable */ 
-					Debug( LDAP_DEBUG_ANY,
-						"backend_check_controls: unrecognized control: %s\n",
+					Debug( LDAP_DEBUG_ANY, "backend_check_controls: "
+						"unrecognized critical control: %s\n",
 						(*ctrls)->ldctl_oid, 0, 0 );
 					assert( 0 );
+				} else {
+					Debug( LDAP_DEBUG_TRACE, "backend_check_controls: "
+						"unrecognized non-critical control: %s\n",
+						(*ctrls)->ldctl_oid, 0, 0 );
 				}
 				break;
 
 			case LDAP_COMPARE_FALSE:
 				if ( !op->o_bd->be_ctrls[cid] && (*ctrls)->ldctl_iscritical ) {
-					/* Per RFC 2251 (and LDAPBIS discussions), if the control
-					 * is recognized and appropriate for the operation (which
-					 * we've already verified), then the server should make
-					 * use of the control when performing the operation.
-					 * 
-					 * Here we find that operation extended by the control
-					 * is unavailable in a particular context, and the control
-					 * is marked Critical, hence the return of
-					 * unwillingToPerform.
+					/* RFC 4511 allows unavailableCriticalExtension to be
+					 * returned when the server is unwilling to perform
+					 * an operation extended by a recognized critical
+					 * control.
 					 */
 					rs->sr_text = "critical control unavailable in context";
-					rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+					rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
 					goto done;
 				}
 				break;
@@ -833,10 +969,9 @@
 		}
 	}
 
-	/* temporarily removed */
-#if 0
+#if 0 /* temporarily removed */
 	/* check should be generalized */
-	if( get_manageDIT(op) && !be_isroot(op)) {
+	if( get_relax(op) && !be_isroot(op)) {
 		rs->sr_text = "requires manager authorization";
 		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
 	}
@@ -1211,7 +1346,7 @@
 	GroupAssertion *g;
 	Backend *be = op->o_bd;
 
-	op->o_bd = select_backend( gr_ndn, 0, 0 );
+	op->o_bd = select_backend( gr_ndn, 0 );
 
 	for ( g = op->o_groups; g; g = g->ga_next ) {
 		if ( g->ga_be != op->o_bd || g->ga_oc != group_oc ||
@@ -1232,124 +1367,159 @@
 	if ( target && dn_match( &target->e_nname, gr_ndn ) ) {
 		e = target;
 		rc = 0;
+
 	} else {
 		op->o_private = NULL;
 		rc = be_entry_get_rw( op, gr_ndn, group_oc, group_at, 0, &e );
 		e_priv = op->o_private;
 		op->o_private = o_priv;
 	}
+
 	if ( e ) {
 		a = attr_find( e->e_attrs, group_at );
 		if ( a ) {
-			/* If the attribute is a subtype of labeledURI, treat this as
-			 * a dynamic group ala groupOfURLs
+			/* If the attribute is a subtype of labeledURI,
+			 * treat this as a dynamic group ala groupOfURLs
 			 */
-			if (is_at_subtype( group_at->ad_type,
+			if ( is_at_subtype( group_at->ad_type,
 				slap_schema.si_ad_labeledURI->ad_type ) )
 			{
 				int i;
 				LDAPURLDesc *ludp;
 				struct berval bv, nbase;
 				Filter *filter;
-				Entry *user;
+				Entry *user = NULL;
 				void *user_priv = NULL;
 				Backend *b2 = op->o_bd;
 
 				if ( target && dn_match( &target->e_nname, op_ndn ) ) {
 					user = target;
-				} else {
-					op->o_bd = select_backend( op_ndn, 0, 0 );
-					op->o_private = NULL;
-					rc = be_entry_get_rw(op, op_ndn, NULL, NULL, 0, &user );
-					user_priv = op->o_private;
-					op->o_private = o_priv;
 				}
 				
-				if ( rc == 0 ) {
-					rc = LDAP_COMPARE_FALSE;
-					for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) {
-						if ( ldap_url_parse( a->a_vals[i].bv_val, &ludp ) !=
-							LDAP_URL_SUCCESS )
-						{
-							continue;
+				rc = LDAP_COMPARE_FALSE;
+				for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ ) {
+					if ( ldap_url_parse( a->a_vals[i].bv_val, &ludp ) !=
+						LDAP_URL_SUCCESS )
+					{
+						continue;
+					}
+
+					BER_BVZERO( &nbase );
+
+					/* host, attrs and extensions parts must be empty */
+					if ( ( ludp->lud_host && *ludp->lud_host )
+						|| ludp->lud_attrs
+						|| ludp->lud_exts )
+					{
+						goto loopit;
+					}
+
+					ber_str2bv( ludp->lud_dn, 0, 0, &bv );
+					if ( dnNormalize( 0, NULL, NULL, &bv, &nbase,
+						op->o_tmpmemctx ) != LDAP_SUCCESS )
+					{
+						goto loopit;
+					}
+
+					switch ( ludp->lud_scope ) {
+					case LDAP_SCOPE_BASE:
+						if ( !dn_match( &nbase, op_ndn ) ) {
+							goto loopit;
 						}
-						BER_BVZERO( &nbase );
-						/* host part must be empty */
-						/* attrs and extensions parts must be empty */
-						if ( ( ludp->lud_host && *ludp->lud_host ) ||
-							ludp->lud_attrs || ludp->lud_exts )
-						{
+						break;
+					case LDAP_SCOPE_ONELEVEL:
+						dnParent( op_ndn, &bv );
+						if ( !dn_match( &nbase, &bv ) ) {
 							goto loopit;
 						}
-						ber_str2bv( ludp->lud_dn, 0, 0, &bv );
-						if ( dnNormalize( 0, NULL, NULL, &bv, &nbase,
-							op->o_tmpmemctx ) != LDAP_SUCCESS )
+						break;
+					case LDAP_SCOPE_SUBTREE:
+						if ( !dnIsSuffix( op_ndn, &nbase ) ) {
+							goto loopit;
+						}
+						break;
+					case LDAP_SCOPE_SUBORDINATE:
+						if ( dn_match( &nbase, op_ndn ) ||
+							!dnIsSuffix( op_ndn, &nbase ) )
 						{
 							goto loopit;
 						}
-						switch ( ludp->lud_scope ) {
-						case LDAP_SCOPE_BASE:
-							if ( !dn_match( &nbase, op_ndn ) ) {
+					}
+
+					/* NOTE: this could be NULL
+					 * if no filter is provided,
+					 * or if filter parsing fails.
+					 * In the latter case,
+					 * we should give up. */
+					if ( ludp->lud_filter != NULL && ludp->lud_filter != '\0') {
+						filter = str2filter_x( op, ludp->lud_filter );
+						if ( filter == NULL ) {
+							/* give up... */
+							rc = LDAP_OTHER;
+							goto loopit;
+						}
+
+						/* only get user if required
+						 * and not available yet */
+						if ( user == NULL ) {	
+							int rc2;
+
+							op->o_bd = select_backend( op_ndn, 0 );
+							op->o_private = NULL;
+							rc2 = be_entry_get_rw( op, op_ndn, NULL, NULL, 0, &user );
+							user_priv = op->o_private;
+							op->o_private = o_priv;
+							if ( rc2 != 0 ) {
+								/* give up... */
+								rc = LDAP_OTHER;
 								goto loopit;
 							}
-							break;
-						case LDAP_SCOPE_ONELEVEL:
-							dnParent( op_ndn, &bv );
-							if ( !dn_match( &nbase, &bv ) ) {
-								goto loopit;
-							}
-							break;
-						case LDAP_SCOPE_SUBTREE:
-							if ( !dnIsSuffix( op_ndn, &nbase ) ) {
-								goto loopit;
-							}
-							break;
-						case LDAP_SCOPE_SUBORDINATE:
-							if ( dn_match( &nbase, op_ndn ) ||
-								!dnIsSuffix( op_ndn, &nbase ) )
-							{
-								goto loopit;
-							}
 						}
-						filter = str2filter_x( op, ludp->lud_filter );
-						if ( filter ) {
-							if ( test_filter( NULL, user, filter ) ==
-								LDAP_COMPARE_TRUE )
-							{
-								rc = 0;
-							}
-							filter_free_x( op, filter );
+
+						if ( test_filter( NULL, user, filter ) ==
+							LDAP_COMPARE_TRUE )
+						{
+							rc = 0;
 						}
+						filter_free_x( op, filter );
+					}
 loopit:
-						ldap_free_urldesc( ludp );
-						if ( !BER_BVISNULL( &nbase ) ) {
-							op->o_tmpfree( nbase.bv_val, op->o_tmpmemctx );
-						}
-						if ( rc == 0 ) break;
+					ldap_free_urldesc( ludp );
+					if ( !BER_BVISNULL( &nbase ) ) {
+						op->o_tmpfree( nbase.bv_val, op->o_tmpmemctx );
 					}
-					if ( user != target ) {
-						op->o_private = user_priv;
-						be_entry_release_r( op, user );
-						op->o_private = o_priv;
+					if ( rc != LDAP_COMPARE_FALSE ) {
+						break;
 					}
 				}
+
+				if ( user != NULL && user != target ) {
+					op->o_private = user_priv;
+					be_entry_release_r( op, user );
+					op->o_private = o_priv;
+				}
 				op->o_bd = b2;
+
 			} else {
-				rc = value_find_ex( group_at,
-				SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
-				SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-				a->a_nvals, op_ndn, op->o_tmpmemctx );
-				if ( rc == LDAP_NO_SUCH_ATTRIBUTE )
+				rc = attr_valfind( a,
+					SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
+					SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
+					op_ndn, NULL, op->o_tmpmemctx );
+				if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) {
 					rc = LDAP_COMPARE_FALSE;
+				}
 			}
+
 		} else {
 			rc = LDAP_NO_SUCH_ATTRIBUTE;
 		}
+
 		if ( e != target ) {
 			op->o_private = e_priv;
 			be_entry_release_r( op, e );
 			op->o_private = o_priv;
 		}
+
 	} else {
 		rc = LDAP_NO_SUCH_OBJECT;
 	}
@@ -1366,6 +1536,7 @@
 		g->ga_next = op->o_groups;
 		op->o_groups = g;
 	}
+
 done:
 	op->o_bd = be;
 	return rc;
@@ -1389,13 +1560,8 @@
 
 	be_orig = op->o_bd;
 	op->o_bd = frontendDB;
-#ifdef SLAP_OVERLAY_ACCESS
 	rc = frontendDB->be_group( op, target, gr_ndn,
 		op_ndn, group_oc, group_at );
-#else /* ! SLAP_OVERLAY_ACCESS */
-	rc = fe_acl_group( op, target, gr_ndn,
-		op_ndn, group_oc, group_at );
-#endif /* ! SLAP_OVERLAY_ACCESS */
 	op->o_bd = be_orig;
 
 	return rc;
@@ -1417,7 +1583,7 @@
 	AccessControlState	acl_state = ACL_STATE_INIT;
 	Backend			*be = op->o_bd;
 
-	op->o_bd = select_backend( edn, 0, 0 );
+	op->o_bd = select_backend( edn, 0 );
 
 	if ( target && dn_match( &target->e_nname, edn ) ) {
 		e = target;
@@ -1430,6 +1596,19 @@
 	} 
 
 	if ( e ) {
+		if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children ) {
+			assert( vals == NULL );
+
+			rc = LDAP_SUCCESS;
+			if ( op->o_conn && access > ACL_NONE &&
+				access_allowed( op, e, entry_at, NULL,
+						access, &acl_state ) == 0 )
+			{
+				rc = LDAP_INSUFFICIENT_ACCESS;
+			}
+			goto freeit;
+		}
+
 		a = attr_find( e->e_attrs, entry_at );
 		if ( a == NULL ) {
 			SlapReply	rs = { 0 };
@@ -1469,9 +1648,7 @@
 				goto freeit;
 			}
 
-			for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ )
-				;
-			
+			i = a->a_numvals;
 			v = op->o_tmpalloc( sizeof(struct berval) * ( i + 1 ),
 				op->o_tmpmemctx );
 			for ( i = 0, j = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ )
@@ -1529,13 +1706,8 @@
 
 	be_orig = op->o_bd;
 	op->o_bd = frontendDB;
-#ifdef SLAP_OVERLAY_ACCESS
 	rc = frontendDB->be_attribute( op, target, edn,
 		entry_at, vals, access );
-#else /* !SLAP_OVERLAY_ACCESS */
-	rc = fe_acl_attribute( op, target, edn,
-		entry_at, vals, access );
-#endif /* !SLAP_OVERLAY_ACCESS */
 	op->o_bd = be_orig;
 
 	return rc;
@@ -1562,7 +1734,7 @@
 	assert( edn != NULL );
 	assert( access > ACL_NONE );
 
-	op->o_bd = select_backend( edn, 0, 0 );
+	op->o_bd = select_backend( edn, 0 );
 
 	if ( target && dn_match( &target->e_nname, edn ) ) {
 		e = target;
@@ -1655,7 +1827,6 @@
 {
 	Attribute		**ap;
 	int			rc = 0;
-	BackendDB		*be_orig;
 
 	for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
 		/* just count them */ ;
@@ -1681,14 +1852,14 @@
 		ap = &(*ap)->a_next;
 	}
 
-	if ( op->o_bd != NULL )
-	{
+	if ( op->o_bd != NULL ) {
+		BackendDB		*be_orig = op->o_bd;
+
 		/* Let the overlays have a chance at this */
-		be_orig = op->o_bd;
-		op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
-		if ( !be_match( op->o_bd, frontendDB ) &&
+		op->o_bd = select_backend( &op->o_req_ndn, 0 );
+		if ( op->o_bd != NULL && !be_match( op->o_bd, frontendDB ) &&
 			( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) &&
-			op->o_bd != NULL && op->o_bd->be_operational != NULL )
+			op->o_bd->be_operational != NULL )
 		{
 			rc = op->o_bd->be_operational( op, rs );
 		}

Modified: openldap/trunk/servers/slapd/backglue.c
===================================================================
--- openldap/trunk/servers/slapd/backglue.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/backglue.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* backglue.c - backend glue */
-/* $OpenLDAP: pkg/ldap/servers/slapd/backglue.c,v 1.91.2.19 2007/08/23 14:31:02 ando Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/backglue.c,v 1.112.2.8 2007/11/15 00:34:01 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2001-2007 The OpenLDAP Foundation.
@@ -35,6 +35,7 @@
 
 #define SLAPD_TOOLS
 #include "slap.h"
+#include "config.h"
 
 typedef struct gluenode {
 	BackendDB *gn_be;
@@ -160,6 +161,31 @@
 			if (!j) {
 				newctrls = ch_malloc((i+1)*sizeof(LDAPControl *));
 			} else {
+				/* Forget old pagedResults response if we're sending
+				 * a new one now
+				 */
+				if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) {
+					int newpage = 0;
+					for ( k=0; k<i; k++ ) {
+						if ( !strcmp(rs->sr_ctrls[k]->ldctl_oid,
+							LDAP_CONTROL_PAGEDRESULTS )) {
+							newpage = 1;
+							break;
+						}
+					}
+					if ( newpage ) {
+						for ( k=0; k<j; k++ ) {
+							if ( !strcmp(gs->ctrls[k]->ldctl_oid,
+								LDAP_CONTROL_PAGEDRESULTS )) {
+									gs->ctrls[k]->ldctl_oid = NULL;
+									ldap_control_free( gs->ctrls[k] );
+									gs->ctrls[k] = gs->ctrls[--j];
+									gs->ctrls[j] = NULL;
+									break;
+							}
+						}
+					}
+				}
 				newctrls = ch_realloc(gs->ctrls,
 					(j+i+1)*sizeof(LDAPControl *));
 			}
@@ -219,7 +245,6 @@
 static int
 glue_response ( Operation *op, SlapReply *rs )
 {
-	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;
 	BackendDB *be = op->o_bd;
 	be = glue_back_select (op->o_bd, &op->o_req_ndn);
 
@@ -377,6 +402,16 @@
 				continue;
 			if (!dnIsSuffix(&btmp->be_nsuffix[0], &b1->be_nsuffix[0]))
 				continue;
+			if (get_no_subordinate_glue(op) && btmp != b1)
+				continue;
+			/* If we remembered which backend we were on before,
+			 * skip down to it now
+			 */
+			if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED &&
+				op->o_conn->c_pagedresults_state.ps_be &&
+				op->o_conn->c_pagedresults_state.ps_be != btmp )
+				continue;
+
 			if (tlimit0 != SLAP_NO_LIMIT) {
 				op->o_time = slap_get_time();
 				op->ors_tlimit = stoptime - op->o_time;
@@ -446,7 +481,41 @@
 			case LDAP_X_CANNOT_CHAIN:
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 				goto end_of_loop;
-			
+
+			case LDAP_SUCCESS:
+				if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) {
+					PagedResultsState *ps = op->o_pagedresults_state;
+
+					/* Assume this backend can be forgotten now */
+					op->o_conn->c_pagedresults_state.ps_be = NULL;
+
+					/* If we have a full page, exit the loop. We may
+					 * need to remember this backend so we can continue
+					 * from here on a subsequent request.
+					 */
+					if ( rs->sr_nentries >= ps->ps_size ) {
+						/* Don't bother to remember the first backend.
+						 * Only remember the last one if there's more state left.
+						 */
+						if ( op->o_bd != b0 &&
+							( op->o_conn->c_pagedresults_state.ps_cookie ||
+							op->o_bd != gi->gi_n[0].gn_be ))
+							op->o_conn->c_pagedresults_state.ps_be = op->o_bd;
+						goto end_of_loop;
+					}
+
+					/* This backend has run out of entries, but more responses
+					 * can fit in the page. Fake a reset of the state so the
+					 * next backend will start up properly. Only back-[bh]db
+					 * and back-sql look at this state info.
+					 */
+					if ( ps->ps_cookieval.bv_len == sizeof( PagedResultsCookie )) {
+						ps->ps_cookie = 0;
+						memset( ps->ps_cookieval.bv_val, 0,
+							sizeof( PagedResultsCookie ));
+					}
+				}
+				
 			default:
 				break;
 			}
@@ -581,7 +650,7 @@
 					gi->gi_n[i].gn_be->bd_info );
 			/* Let backend.c take care of the rest of startup */
 			if ( !rc )
-				rc = backend_startup_one( gi->gi_n[i].gn_be );
+				rc = backend_startup_one( gi->gi_n[i].gn_be, NULL );
 			if ( rc ) break;
 		}
 		if ( !rc && !bsame && on->on_info->oi_orig->bi_open )
@@ -619,9 +688,8 @@
 	int	rw,
 	Entry	**e )
 {
+	int rc;
 	BackendDB *b0 = op->o_bd;
-	int rc;
-
 	op->o_bd = glue_back_select( b0, dn );
 
 	if ( op->o_bd->be_fetch ) {
@@ -782,13 +850,14 @@
 static int
 glue_tool_entry_reindex (
 	BackendDB *b0,
-	ID id
+	ID id,
+	AttributeDescription **adv
 )
 {
 	if (!glueBack || !glueBack->be_entry_reindex)
 		return -1;
 
-	return glueBack->be_entry_reindex (glueBack, id);
+	return glueBack->be_entry_reindex (glueBack, id, adv);
 }
 
 static int
@@ -814,7 +883,8 @@
 
 static int
 glue_db_init(
-	BackendDB *be
+	BackendDB *be,
+	ConfigReply *cr
 )
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
@@ -859,7 +929,6 @@
 
 	/*FIXME : need to add support */
 	oi->oi_bi.bi_tool_dn2id_get = 0;
-	oi->oi_bi.bi_tool_id2entry_get = 0;
 	oi->oi_bi.bi_tool_entry_modify = 0;
 
 	SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLUE_INSTANCE;
@@ -869,7 +938,8 @@
 
 static int
 glue_db_destroy (
-	BackendDB *be
+	BackendDB *be,
+	ConfigReply *cr
 )
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
@@ -881,7 +951,8 @@
 
 static int
 glue_db_close( 
-	BackendDB *be
+	BackendDB *be,
+	ConfigReply *cr
 )
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
@@ -971,7 +1042,7 @@
 
 			/* If it's not already configured, set up the overlay */
 			if ( !SLAP_GLUE_INSTANCE( be )) {
-				rc = overlay_config( be, glue.on_bi.bi_type );
+				rc = overlay_config( be, glue.on_bi.bi_type, -1, NULL );
 				if ( rc )
 					break;
 			}

Modified: openldap/trunk/servers/slapd/backover.c
===================================================================
--- openldap/trunk/servers/slapd/backover.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/backover.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* backover.c - backend overlay routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/backover.c,v 1.31.2.23 2007/09/02 11:51:09 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/backover.c,v 1.71.2.5 2007/08/31 23:13:58 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -51,14 +51,14 @@
 	func = &oi->oi_orig->bi_db_open;
 	if ( func[which] ) {
 		be->bd_info = oi->oi_orig;
-		rc = func[which]( be );
+		rc = func[which]( be, NULL );
 	}
 
 	for (; on && rc == 0; on=on->on_next) {
 		be->bd_info = &on->on_bi;
 		func = &on->on_bi.bi_db_open;
 		if (func[which]) {
-			rc = func[which]( be );
+			rc = func[which]( be, NULL );
 		}
 	}
 	be->bd_info = bi_orig;
@@ -168,7 +168,8 @@
 
 static int
 over_db_open(
-	BackendDB *be
+	BackendDB *be,
+	ConfigReply *cr
 )
 {
 	return over_db_func( be, db_open );
@@ -176,7 +177,8 @@
 
 static int
 over_db_close(
-	BackendDB *be
+	BackendDB *be,
+	ConfigReply *cr
 )
 {
 	slap_overinfo *oi = be->bd_info->bi_private;
@@ -187,13 +189,13 @@
 	for (; on && rc == 0; on=on->on_next) {
 		be->bd_info = &on->on_bi;
 		if ( be->bd_info->bi_db_close ) {
-			rc = be->bd_info->bi_db_close( be );
+			rc = be->bd_info->bi_db_close( be, NULL );
 		}
 	}
 
 	if ( oi->oi_orig->bi_db_close ) {
 		be->bd_info = oi->oi_orig;
-		rc = be->bd_info->bi_db_close( be );
+		rc = be->bd_info->bi_db_close( be, NULL );
 	}
 
 	be->bd_info = bi_orig;
@@ -202,7 +204,8 @@
 
 static int
 over_db_destroy(
-	BackendDB *be
+	BackendDB *be,
+	ConfigReply *cr
 )
 {
 	slap_overinfo *oi = be->bd_info->bi_private;
@@ -217,6 +220,7 @@
 			free( on );
 		}
 	}
+
 	free( oi );
 	return rc;
 }
@@ -247,6 +251,81 @@
 	return rc;
 }
 
+static int
+over_access_allowed(
+	Operation		*op,
+	Entry			*e,
+	AttributeDescription	*desc,
+	struct berval		*val,
+	slap_access_t		access,
+	AccessControlState	*state,
+	slap_mask_t		*maskp )
+{
+	slap_overinfo *oi;
+	slap_overinst *on;
+	BackendInfo *bi;
+	BackendDB *be = op->o_bd, db;
+	int rc = SLAP_CB_CONTINUE;
+
+	/* FIXME: used to happen for instance during abandon
+	 * when global overlays are used... */
+	assert( op->o_bd != NULL );
+
+	bi = op->o_bd->bd_info;
+	/* Were we invoked on the frontend? */
+	if ( !bi->bi_access_allowed ) {
+		oi = frontendDB->bd_info->bi_private;
+	} else {
+		oi = op->o_bd->bd_info->bi_private;
+	}
+	on = oi->oi_list;
+
+	for ( ; on; on = on->on_next ) {
+		if ( on->on_bi.bi_access_allowed ) {
+			/* NOTE: do not copy the structure until required */
+		 	if ( !SLAP_ISOVERLAY( op->o_bd ) ) {
+ 				db = *op->o_bd;
+				db.be_flags |= SLAP_DBFLAG_OVERLAY;
+				op->o_bd = &db;
+			}
+
+			op->o_bd->bd_info = (BackendInfo *)on;
+			rc = on->on_bi.bi_access_allowed( op, e,
+				desc, val, access, state, maskp );
+			if ( rc != SLAP_CB_CONTINUE ) break;
+		}
+	}
+
+	if ( rc == SLAP_CB_CONTINUE ) {
+		BI_access_allowed	*bi_access_allowed;
+
+		/* if the database structure was changed, o_bd points to a
+		 * copy of the structure; put the original bd_info in place */
+		if ( SLAP_ISOVERLAY( op->o_bd ) ) {
+			op->o_bd->bd_info = oi->oi_orig;
+		}
+
+		if ( oi->oi_orig->bi_access_allowed ) {
+			bi_access_allowed = oi->oi_orig->bi_access_allowed;
+		} else {
+			bi_access_allowed = slap_access_allowed;
+		}
+
+		rc = bi_access_allowed( op, e,
+			desc, val, access, state, maskp );
+	}
+	/* should not fall thru this far without anything happening... */
+	if ( rc == SLAP_CB_CONTINUE ) {
+		/* access not allowed */
+		rc = 0;
+	}
+
+	op->o_bd = be;
+	op->o_bd->bd_info = bi;
+
+	return rc;
+}
+
 int
 overlay_entry_get_ov(
 	Operation		*op,
@@ -388,83 +467,7 @@
 	return overlay_entry_release_ov( op, e, rw, on );
 }
 
-#ifdef SLAP_OVERLAY_ACCESS
 static int
-over_access_allowed(
-	Operation		*op,
-	Entry			*e,
-	AttributeDescription	*desc,
-	struct berval		*val,
-	slap_access_t		access,
-	AccessControlState	*state,
-	slap_mask_t		*maskp )
-{
-	slap_overinfo *oi;
-	slap_overinst *on;
-	BackendInfo *bi;
-	BackendDB *be = op->o_bd, db;
-	int rc = SLAP_CB_CONTINUE;
-
-	/* FIXME: used to happen for instance during abandon
-	 * when global overlays are used... */
-	assert( op->o_bd != NULL );
-
-	bi = op->o_bd->bd_info;
-	/* Were we invoked on the frontend? */
-	if ( !bi->bi_access_allowed ) {
-		oi = frontendDB->bd_info->bi_private;
-	} else {
-		oi = op->o_bd->bd_info->bi_private;
-	}
-	on = oi->oi_list;
-
-	for ( ; on; on = on->on_next ) {
-		if ( on->on_bi.bi_access_allowed ) {
-			/* NOTE: do not copy the structure until required */
-		 	if ( !SLAP_ISOVERLAY( op->o_bd ) ) {
- 				db = *op->o_bd;
-				db.be_flags |= SLAP_DBFLAG_OVERLAY;
-				op->o_bd = &db;
-			}
-
-			op->o_bd->bd_info = (BackendInfo *)on;
-			rc = on->on_bi.bi_access_allowed( op, e,
-				desc, val, access, state, maskp );
-			if ( rc != SLAP_CB_CONTINUE ) break;
-		}
-	}
-
-	if ( rc == SLAP_CB_CONTINUE ) {
-		BI_access_allowed	*bi_access_allowed;
-
-		/* if the database structure was changed, o_bd points to a
-		 * copy of the structure; put the original bd_info in place */
-		if ( SLAP_ISOVERLAY( op->o_bd ) ) {
-			op->o_bd->bd_info = oi->oi_orig;
-		}
-
-		if ( oi->oi_orig->bi_access_allowed ) {
-			bi_access_allowed = oi->oi_orig->bi_access_allowed;
-		} else {
-			bi_access_allowed = slap_access_allowed;
-		}
-
-		rc = bi_access_allowed( op, e,
-			desc, val, access, state, maskp );
-	}
-	/* should not fall thru this far without anything happening... */
-	if ( rc == SLAP_CB_CONTINUE ) {
-		/* access not allowed */
-		rc = 0;
-	}
-
-	op->o_bd = be;
-	op->o_bd->bd_info = bi;
-
-	return rc;
-}
-
-static int
 over_acl_group(
 	Operation		*op,
 	Entry			*e,
@@ -599,7 +602,6 @@
 
 	return rc;
 }
-#endif /* SLAP_OVERLAY_ACCESS */
 
 /*
  * default return code in case of missing backend function
@@ -867,6 +869,69 @@
 	slap_overinst *on
 )
 {
+	slap_overinst	*tmp;
+
+	/* FIXME: check for duplicates? */
+	for ( tmp = overlays; tmp != NULL; tmp = tmp->on_next ) {
+		if ( strcmp( on->on_bi.bi_type, tmp->on_bi.bi_type ) == 0 ) {
+			Debug( LDAP_DEBUG_ANY,
+				"overlay_register(\"%s\"): "
+				"name already in use.\n",
+				on->on_bi.bi_type, 0, 0 );
+			return -1;
+		}
+
+		if ( on->on_bi.bi_obsolete_names != NULL ) {
+			int	i;
+
+			for ( i = 0; on->on_bi.bi_obsolete_names[ i ] != NULL; i++ ) {
+				if ( strcmp( on->on_bi.bi_obsolete_names[ i ], tmp->on_bi.bi_type ) == 0 ) {
+					Debug( LDAP_DEBUG_ANY,
+						"overlay_register(\"%s\"): "
+						"obsolete name \"%s\" already in use "
+						"by overlay \"%s\".\n",
+						on->on_bi.bi_type,
+						on->on_bi.bi_obsolete_names[ i ],
+						tmp->on_bi.bi_type );
+					return -1;
+				}
+			}
+		}
+
+		if ( tmp->on_bi.bi_obsolete_names != NULL ) {
+			int	i;
+
+			for ( i = 0; tmp->on_bi.bi_obsolete_names[ i ] != NULL; i++ ) {
+				int	j;
+
+				if ( strcmp( on->on_bi.bi_type, tmp->on_bi.bi_obsolete_names[ i ] ) == 0 ) {
+					Debug( LDAP_DEBUG_ANY,
+						"overlay_register(\"%s\"): "
+						"name already in use "
+						"as obsolete by overlay \"%s\".\n",
+						on->on_bi.bi_type,
+						tmp->on_bi.bi_obsolete_names[ i ], 0 );
+					return -1;
+				}
+
+				if ( on->on_bi.bi_obsolete_names != NULL ) {
+					for ( j = 0; on->on_bi.bi_obsolete_names[ j ] != NULL; j++ ) {
+						if ( strcmp( on->on_bi.bi_obsolete_names[ j ], tmp->on_bi.bi_obsolete_names[ i ] ) == 0 ) {
+							Debug( LDAP_DEBUG_ANY,
+								"overlay_register(\"%s\"): "
+								"obsolete name \"%s\" already in use "
+								"as obsolete by overlay \"%s\".\n",
+								on->on_bi.bi_type,
+								on->on_bi.bi_obsolete_names[ j ],
+								tmp->on_bi.bi_type );
+							return -1;
+						}
+					}
+				}
+			}
+		}
+	}
+
 	on->on_next = overlays;
 	overlays = on;
 	return 0;
@@ -874,8 +939,8 @@
 
 /*
  * iterator on registered overlays; overlay_next( NULL ) returns the first
- * overlay; * subsequent calls with the previously returned value allow to 
- * iterate * over the entire list; returns NULL when no more overlays are 
+ * overlay; subsequent calls with the previously returned value allow to 
+ * iterate over the entire list; returns NULL when no more overlays are 
  * registered.
  */
 
@@ -905,10 +970,26 @@
 
 	for ( ; on; on = on->on_next ) {
 		if ( strcmp( on->on_bi.bi_type, over_type ) == 0 ) {
-			break;
+			goto foundit;
 		}
+
+		if ( on->on_bi.bi_obsolete_names != NULL ) {
+			int	i;
+
+			for ( i = 0; on->on_bi.bi_obsolete_names[ i ] != NULL; i++ ) {
+				if ( strcmp( on->on_bi.bi_obsolete_names[ i ], over_type ) == 0 ) {
+					Debug( LDAP_DEBUG_ANY,
+						"overlay_find(\"%s\"): "
+						"obsolete name for \"%s\".\n",
+						on->on_bi.bi_obsolete_names[ i ],
+						on->on_bi.bi_type, 0 );
+					goto foundit;
+				}
+			}
+		}
 	}
 
+foundit:;
 	return on;
 }
 
@@ -962,7 +1043,7 @@
 		return -1;
 	}
 
-	if ( SLAP_DBFLAGS( be ) & SLAP_DBFLAG_GLOBAL_OVERLAY ) {
+	if ( SLAP_ISGLOBALOVERLAY( be ) ) {
 		BackendDB *bd;
 		
 		/* add to all backends... */
@@ -997,7 +1078,7 @@
 			if ( on->on_bi.bi_db_destroy ) {
 				BackendInfo *bi_orig = be->bd_info;
 				be->bd_info = (BackendInfo *)on;
-				on->on_bi.bi_db_destroy( be );
+				on->on_bi.bi_db_destroy( be, NULL );
 				be->bd_info = bi_orig;
 			}
 			free( on );
@@ -1006,14 +1087,77 @@
 	}
 }
 
+void
+overlay_insert( BackendDB *be, slap_overinst *on2, slap_overinst ***prev,
+	int idx )
+{
+	slap_overinfo *oi = (slap_overinfo *)be->bd_info;
+
+	if ( idx == -1 ) {
+		on2->on_next = oi->oi_list;
+		oi->oi_list = on2;
+	} else {
+		int i;
+		slap_overinst *on, *otmp1 = NULL, *otmp2;
+
+		/* Since the list is in reverse order and is singly linked,
+		 * we reverse it to find the idx insertion point. Adding
+		 * on overlay at a specific point should be a pretty
+		 * infrequent occurrence.
+		 */
+		for ( on = oi->oi_list; on; on=otmp2 ) {
+			otmp2 = on->on_next;
+			on->on_next = otmp1;
+			otmp1 = on;
+		}
+		oi->oi_list = NULL;
+		/* advance to insertion point */
+		for ( i=0, on = otmp1; i<idx; i++ ) {
+			otmp1 = on->on_next;
+			on->on_next = oi->oi_list;
+			oi->oi_list = on;
+		}
+		/* insert */
+		on2->on_next = oi->oi_list;
+		oi->oi_list = on2;
+		if ( otmp1 ) {
+			*prev = &otmp1->on_next;
+			/* replace remainder of list */
+			for ( on=otmp1; on; on=otmp1 ) {
+				otmp1 = on->on_next;
+				on->on_next = oi->oi_list;
+				oi->oi_list = on;
+			}
+		}
+	}
+}
+
+void
+overlay_move( BackendDB *be, slap_overinst *on, int idx )
+{
+	slap_overinfo *oi = (slap_overinfo *)be->bd_info;
+	slap_overinst **onp;
+
+	for (onp = &oi->oi_list; *onp; onp= &(*onp)->on_next) {
+		if ( *onp == on ) {
+			*onp = on->on_next;
+			break;
+		}
+	}
+	overlay_insert( be, on, &onp, idx );
+}
+
 /* add an overlay to a particular backend. */
 int
-overlay_config( BackendDB *be, const char *ov )
+overlay_config( BackendDB *be, const char *ov, int idx, BackendInfo **res )
 {
-	slap_overinst *on = NULL, *on2 = NULL;
+	slap_overinst *on = NULL, *on2 = NULL, **prev;
 	slap_overinfo *oi = NULL;
 	BackendInfo *bi = NULL;
 
+	if ( res )
+		*res = NULL;
+
 	on = overlay_find( ov );
 	if ( !on ) {
 		Debug( LDAP_DEBUG_ANY, "overlay \"%s\" not found\n", ov, 0, 0 );
@@ -1024,15 +1168,33 @@
 	 * overlay info structure
 	 */
 	if ( !overlay_is_over( be ) ) {
+		int	isglobal = 0;
+
+		/* NOTE: the first time a global overlay is configured,
+		 * frontendDB gets this flag; it is used later by overlays
+		 * to determine if they're stacked on top of the frontendDB */
+		if ( be->bd_info == frontendDB->bd_info || SLAP_ISGLOBALOVERLAY( be ) ) {
+			isglobal = 1;
+			if ( on->on_bi.bi_flags & SLAPO_BFLAG_DBONLY ) {
+				Debug( LDAP_DEBUG_ANY, "overlay_config(): "
+					"overlay \"%s\" cannot be global.\n",
+					ov, 0, 0 );
+				return 1;
+			}
+
+		} else if ( on->on_bi.bi_flags & SLAPO_BFLAG_GLOBONLY ) {
+			Debug( LDAP_DEBUG_ANY, "overlay_config(): "
+				"overlay \"%s\" can only be global.\n",
+				ov, 0, 0 );
+			return 1;
+		}
+
 		oi = ch_malloc( sizeof( slap_overinfo ) );
 		oi->oi_orig = be->bd_info;
 		oi->oi_bi = *be->bd_info;
 		oi->oi_origdb = be;
 
-		/* NOTE: the first time a global overlay is configured,
-		 * frontendDB gets this flag; it is used later by overlays
-		 * to determine if they're stacked on top of the frontendDB */
-		if ( oi->oi_orig == frontendDB->bd_info ) {
+		if ( isglobal ) {
 			SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLOBAL_OVERLAY;
 		}
 
@@ -1075,11 +1237,9 @@
 		/* these have specific arglists */
 		bi->bi_entry_get_rw = over_entry_get_rw;
 		bi->bi_entry_release_rw = over_entry_release_rw;
-#ifdef SLAP_OVERLAY_ACCESS
 		bi->bi_access_allowed = over_access_allowed;
 		bi->bi_acl_group = over_acl_group;
 		bi->bi_acl_attribute = over_acl_attribute;
-#endif /* SLAP_OVERLAY_ACCESS */
 		
 		bi->bi_connection_init = over_connection_init;
 		bi->bi_connection_destroy = over_connection_destroy;
@@ -1089,35 +1249,54 @@
 	} else {
 		if ( overlay_is_inst( be, ov ) ) {
 			Debug( LDAP_DEBUG_ANY, "overlay_config(): "
-					"warning, overlay \"%s\" "
-					"already in list\n", ov, 0, 0 );
+				"overlay \"%s\" already in list\n",
+				ov, 0, 0 );
+			if ( SLAPO_SINGLE( be ) ) {
+				return 1;
+			}
 		}
 
 		oi = be->bd_info->bi_private;
 	}
 
-	/* Insert new overlay on head of list. Overlays are executed
-	 * in reverse of config order...
+	/* Insert new overlay into list. By default overlays are
+	 * added to head of list and executed in LIFO order.
 	 */
 	on2 = ch_calloc( 1, sizeof(slap_overinst) );
 	*on2 = *on;
 	on2->on_info = oi;
-	on2->on_next = oi->oi_list;
-	oi->oi_list = on2;
 
+	prev = &oi->oi_list;
+	/* Do we need to find the insertion point? */
+	if ( idx >= 0 ) {
+		int i;
+
+		/* count current overlays */
+		for ( i=0, on=oi->oi_list; on; on=on->on_next, i++ );
+
+		/* are we just appending a new one? */
+		if ( idx >= i )
+			idx = -1;
+	}
+	overlay_insert( be, on2, &prev, idx );
+
 	/* Any initialization needed? */
-	if ( on->on_bi.bi_db_init ) {
+	if ( on2->on_bi.bi_db_init ) {
 		int rc;
 		be->bd_info = (BackendInfo *)on2;
-		rc = on2->on_bi.bi_db_init( be );
+		rc = on2->on_bi.bi_db_init( be, NULL );
 		be->bd_info = (BackendInfo *)oi;
 		if ( rc ) {
-			oi->oi_list = on2->on_next;
+			*prev = on2->on_next;
 			ch_free( on2 );
+			on2 = NULL;
 			return rc;
 		}
 	}
 
+	if ( res )
+		*res = &on2->on_bi;
+
 	return 0;
 }
 

Modified: openldap/trunk/servers/slapd/bconfig.c
===================================================================
--- openldap/trunk/servers/slapd/bconfig.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/bconfig.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* bconfig.c - the config backend */
-/* $OpenLDAP: pkg/ldap/servers/slapd/bconfig.c,v 1.17.2.54 2007/09/02 11:51:09 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/bconfig.c,v 1.202.2.22 2007/12/03 15:04:31 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2005-2007 The OpenLDAP Foundation.
@@ -37,9 +37,14 @@
 
 #include "config.h"
 
-static struct berval config_rdn = BER_BVC("cn=config");
-static struct berval schema_rdn = BER_BVC("cn=schema");
+#define	CONFIG_RDN	"cn=config"
+#define	SCHEMA_RDN	"cn=schema"
 
+static struct berval config_rdn = BER_BVC(CONFIG_RDN);
+static struct berval schema_rdn = BER_BVC(SCHEMA_RDN);
+
+extern int slap_DN_strict;	/* dn.c */
+
 #ifdef SLAPD_MODULES
 typedef struct modpath_s {
 	struct modpath_s *mp_next;
@@ -69,13 +74,10 @@
 	int		cb_use_ldif;
 } CfBackInfo;
 
-/* These do nothing in slapd, they're kept only to make them
- * editable here.
- */
-static char *replica_pidFile, *replica_argsFile;
-static int replicationInterval;
+static CfBackInfo cfBackInfo;
 
 static char	*passwd_salt;
+static FILE *logfile;
 static char	*logfileName;
 #ifdef SLAP_AUTH_REWRITE
 static BerVarray authz_rewrites;
@@ -85,15 +87,25 @@
 
 /* Private state */
 static AttributeDescription *cfAd_backend, *cfAd_database, *cfAd_overlay,
-	*cfAd_include;
+	*cfAd_include, *cfAd_attr, *cfAd_oc, *cfAd_om;
 
 static ConfigFile *cfn;
 
 static Avlnode *CfOcTree;
 
+/* System schema state */
+extern AttributeType *at_sys_tail;	/* at.c */
+extern ObjectClass *oc_sys_tail;	/* oc.c */
+extern OidMacro *om_sys_tail;	/* oidm.c */
+static AttributeType *cf_at_tail;
+static ObjectClass *cf_oc_tail;
+static OidMacro *cf_om_tail;
+
 static int config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca,
-	SlapReply *rs, int *renumber );
+	SlapReply *rs, int *renumber, Operation *op );
 
+static int config_check_schema( Operation *op, CfBackInfo *cfb );
+
 static ConfigDriver config_fname;
 static ConfigDriver config_cfdir;
 static ConfigDriver config_generic;
@@ -114,10 +126,10 @@
 static ConfigDriver config_security;
 static ConfigDriver config_referral;
 static ConfigDriver config_loglevel;
-static ConfigDriver config_replica;
 static ConfigDriver config_updatedn;
 static ConfigDriver config_updateref;
 static ConfigDriver config_include;
+static ConfigDriver config_obsolete;
 #ifdef HAVE_TLS
 static ConfigDriver config_tls_option;
 static ConfigDriver config_tls_config;
@@ -137,6 +149,7 @@
 	CFG_TLS_DH_FILE,
 	CFG_TLS_VERIFY,
 	CFG_TLS_CRLCHECK,
+	CFG_TLS_CRL_FILE,
 	CFG_CONCUR,
 	CFG_THREADS,
 	CFG_SALT,
@@ -149,7 +162,6 @@
 	CFG_DIT,
 	CFG_ATTR,
 	CFG_ATOPT,
-	CFG_REPLOG,
 	CFG_ROOTDSE,
 	CFG_LOGFILE,
 	CFG_PLUGIN,
@@ -162,6 +174,12 @@
 	CFG_SSTR_IF_MAX,
 	CFG_SSTR_IF_MIN,
 	CFG_TTHREADS,
+	CFG_MIRRORMODE,
+	CFG_HIDDEN,
+	CFG_MONITORING,
+	CFG_SERVERID,
+	CFG_SORTVALS,
+	CFG_IX_INTLEN,
 
 	CFG_LAST
 };
@@ -178,16 +196,26 @@
 	{ "OLcfgBkAt", "OLcfgAt:1" },
 	{ "OLcfgDbAt", "OLcfgAt:2" },
 	{ "OLcfgOvAt", "OLcfgAt:3" },
+	{ "OLcfgCtAt", "OLcfgAt:4" },	/* contrib modules */
 	{ "OLcfgOc", "OLcfg:4" },
 	{ "OLcfgGlOc", "OLcfgOc:0" },
 	{ "OLcfgBkOc", "OLcfgOc:1" },
 	{ "OLcfgDbOc", "OLcfgOc:2" },
 	{ "OLcfgOvOc", "OLcfgOc:3" },
+	{ "OLcfgCtOc", "OLcfgOc:4" },	/* contrib modules */
+
+	/* Syntaxes. We should just start using the standard names and
+	 * document that they are predefined and available for users
+	 * to reference in their own schema. Defining schema without
+	 * OID macros is for masochists...
+	 */
 	{ "OMsyn", "1.3.6.1.4.1.1466.115.121.1" },
-	{ "OMsInteger", "OMsyn:27" },
 	{ "OMsBoolean", "OMsyn:7" },
 	{ "OMsDN", "OMsyn:12" },
 	{ "OMsDirectoryString", "OMsyn:15" },
+	{ "OMsIA5String", "OMsyn:26" },
+	{ "OMsInteger", "OMsyn:27" },
+	{ "OMsOID", "OMsyn:38" },
 	{ "OMsOctetString", "OMsyn:40" },
 	{ NULL, NULL }
 };
@@ -196,9 +224,12 @@
  * Backend/Database registry
  *
  * OLcfg{Bk|Db}{Oc|At}:0		-> common
- * OLcfg{Bk|Db}{Oc|At}:1		-> bdb
- * OLcfg{Bk|Db}{Oc|At}:2		-> ldif
- * OLcfg{Bk|Db}{Oc|At}:3		-> ldap?
+ * OLcfg{Bk|Db}{Oc|At}:1		-> back-bdb(/back-hdb)
+ * OLcfg{Bk|Db}{Oc|At}:2		-> back-ldif
+ * OLcfg{Bk|Db}{Oc|At}:3		-> back-ldap
+ * OLcfg{Bk|Db}{Oc|At}:4		-> back-monitor
+ * OLcfg{Bk|Db}{Oc|At}:5		-> back-relay
+ * OLcfg{Bk|Db}{Oc|At}:6		-> back-sql
  */
 
 /*
@@ -209,7 +240,19 @@
  * OLcfgOv{Oc|At}:3			-> chain
  * OLcfgOv{Oc|At}:4			-> accesslog
  * OLcfgOv{Oc|At}:5			-> valsort
- * OLcfgOv{Oc|At}:6			-> smbk5pwd (use a separate arc for contrib?)
+ * OLcfgOv{Oc|At}:7			-> distproc
+ * OLcfgOv{Oc|At}:8			-> dynlist
+ * OLcfgOv{Oc|At}:9			-> dds
+ * OLcfgOv{Oc|At}:10			-> unique
+ * OLcfgOv{Oc|At}:11			-> refint
+ * OLcfgOv{Oc|At}:12 			-> ppolicy
+ * OLcfgOv{Oc|At}:13			-> constraint
+ * OLcfgOv{Oc|At}:14			-> translucent
+ * OLcfgOv{Oc|At}:15			-> auditlog
+ * OLcfgOv{Oc|At}:16			-> rwm
+ * OLcfgOv{Oc|At}:17			-> dyngroup
+ * OLcfgOv{Oc|At}:18			-> memberof
+ * OLcfgOv{Oc|At}:19			-> collect
  */
 
 /* alphabetical ordering */
@@ -245,8 +288,8 @@
 		&config_generic, "( OLcfgGlAt:5 NAME 'olcAttributeOptions' "
 			"EQUALITY caseIgnoreMatch "
 			"SYNTAX OMsDirectoryString )", NULL, NULL },
-	{ "attribute",	"attribute", 2, 0, 9,
-		ARG_PAREN|ARG_MAGIC|CFG_ATTR|ARG_NO_DELETE|ARG_NO_INSERT,
+	{ "attribute",	"attribute", 2, 0, STRLENOF( "attribute" ),
+		ARG_PAREN|ARG_MAGIC|CFG_ATTR,
 		&config_generic, "( OLcfgGlAt:4 NAME 'olcAttributeTypes' "
 			"DESC 'OpenLDAP attributeTypes' "
 			"EQUALITY caseIgnoreMatch "
@@ -309,6 +352,9 @@
 #endif
 		"( OLcfgGlAt:17 NAME 'olcGentleHUP' "
 			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+	{ "hidden", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_HIDDEN,
+		&config_generic, "( OLcfgDbAt:0.17 NAME 'olcHidden' "
+			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
 	{ "idletimeout", "timeout", 2, 2, 0, ARG_INT,
 		&global_idletimeout, "( OLcfgGlAt:18 NAME 'olcIdleTimeout' "
 			"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
@@ -327,6 +373,9 @@
 	{ "index_substr_any_step", "step", 2, 2, 0, ARG_INT|ARG_NONZERO,
 		&index_substr_any_step, "( OLcfgGlAt:23 NAME 'olcIndexSubstrAnyStep' "
 			"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+	{ "index_intlen", "len", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_IX_INTLEN,
+		&config_generic, "( OLcfgGlAt:84 NAME 'olcIndexIntLen' "
+			"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
 	{ "lastmod", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_LASTMOD,
 		&config_generic, "( OLcfgDbAt:0.4 NAME 'olcLastMod' "
 			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
@@ -347,6 +396,9 @@
 	{ "maxDerefDepth", "depth", 2, 2, 0, ARG_DB|ARG_INT|ARG_MAGIC|CFG_DEPTH,
 		&config_generic, "( OLcfgDbAt:0.6 NAME 'olcMaxDerefDepth' "
 			"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+	{ "mirrormode", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_MIRRORMODE,
+		&config_generic, "( OLcfgDbAt:0.16 NAME 'olcMirrorMode' "
+			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
 	{ "moduleload",	"file", 2, 0, 0,
 #ifdef SLAPD_MODULES
 		ARG_MAGIC|CFG_MODLOAD|ARG_NO_DELETE, &config_generic,
@@ -364,13 +416,17 @@
 #endif
 		"( OLcfgGlAt:31 NAME 'olcModulePath' "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
-	{ "objectclass", "objectclass", 2, 0, 0, ARG_PAREN|ARG_MAGIC|CFG_OC|ARG_NO_DELETE|ARG_NO_INSERT,
+	{ "monitoring", "TRUE|FALSE", 2, 2, 0,
+		ARG_MAGIC|CFG_MONITORING|ARG_DB|ARG_ON_OFF, &config_generic,
+		"( OLcfgDbAt:0.18 NAME 'olcMonitoring' "
+			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+	{ "objectclass", "objectclass", 2, 0, 0, ARG_PAREN|ARG_MAGIC|CFG_OC,
 		&config_generic, "( OLcfgGlAt:32 NAME 'olcObjectClasses' "
 		"DESC 'OpenLDAP object classes' "
 		"EQUALITY caseIgnoreMatch "
 		"SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )",
 			NULL, NULL },
-	{ "objectidentifier", NULL,	0, 0, 0, ARG_MAGIC|CFG_OID,
+	{ "objectidentifier", "name> <oid",	3, 3, 0, ARG_MAGIC|CFG_OID,
 		&config_generic, "( OLcfgGlAt:33 NAME 'olcObjectIdentifier' "
 			"EQUALITY caseIgnoreMatch "
 			"SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
@@ -411,20 +467,20 @@
 		&config_referral, "( OLcfgGlAt:41 NAME 'olcReferral' "
 			"SUP labeledURI SINGLE-VALUE )", NULL, NULL },
 	{ "replica", "host or uri", 2, 0, 0, ARG_DB|ARG_MAGIC,
-		&config_replica, "( OLcfgDbAt:0.7 NAME 'olcReplica' "
+		&config_obsolete, "( OLcfgDbAt:0.7 NAME 'olcReplica' "
 			"EQUALITY caseIgnoreMatch "
 			"SUP labeledURI X-ORDERED 'VALUES' )", NULL, NULL },
-	{ "replica-argsfile", NULL, 0, 0, 0, ARG_STRING,
-		&replica_argsFile, "( OLcfgGlAt:43 NAME 'olcReplicaArgsFile' "
+	{ "replica-argsfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC,
+		&config_obsolete, "( OLcfgGlAt:43 NAME 'olcReplicaArgsFile' "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
-	{ "replica-pidfile", NULL, 0, 0, 0, ARG_STRING,
-		&replica_pidFile, "( OLcfgGlAt:44 NAME 'olcReplicaPidFile' "
+	{ "replica-pidfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC,
+		&config_obsolete, "( OLcfgGlAt:44 NAME 'olcReplicaPidFile' "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
-	{ "replicationInterval", NULL, 0, 0, 0, ARG_INT,
-		&replicationInterval, "( OLcfgGlAt:45 NAME 'olcReplicationInterval' "
+	{ "replicationInterval", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC,
+		&config_obsolete, "( OLcfgGlAt:45 NAME 'olcReplicationInterval' "
 			"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-	{ "replogfile", "filename", 2, 2, 0, ARG_MAY_DB|ARG_MAGIC|ARG_STRING|CFG_REPLOG,
-		&config_generic, "( OLcfgGlAt:46 NAME 'olcReplogFile' "
+	{ "replogfile", "filename", 2, 2, 0, ARG_MAY_DB|ARG_MAGIC,
+		&config_obsolete, "( OLcfgGlAt:46 NAME 'olcReplogFile' "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
 	{ "require", "features", 2, 0, 7, ARG_MAY_DB|ARG_MAGIC,
 		&config_requires, "( OLcfgGlAt:47 NAME 'olcRequires' "
@@ -456,7 +512,7 @@
 		&config_generic, NULL, NULL, NULL },
 	{ "sasl-host", "host", 2, 2, 0,
 #ifdef HAVE_CYRUS_SASL
-		ARG_STRING|ARG_UNIQUE, &global_host,
+		ARG_STRING|ARG_UNIQUE, &sasl_host,
 #else
 		ARG_IGNORED, NULL,
 #endif
@@ -489,6 +545,10 @@
 		&config_security, "( OLcfgGlAt:59 NAME 'olcSecurity' "
 			"EQUALITY caseIgnoreMatch "
 			"SYNTAX OMsDirectoryString )", NULL, NULL },
+	{ "serverID", "number> <[URI]", 2, 3, 0, ARG_MAGIC|CFG_SERVERID,
+		&config_generic, "( OLcfgGlAt:81 NAME 'olcServerID' "
+			"EQUALITY caseIgnoreMatch "
+			"SYNTAX OMsDirectoryString )", NULL, NULL },
 	{ "sizelimit", "limit",	2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
 		&config_sizelimit, "( OLcfgGlAt:60 NAME 'olcSizeLimit' "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
@@ -498,14 +558,11 @@
 	{ "sockbuf_max_incoming_auth", "max", 2, 2, 0, ARG_BER_LEN_T,
 		&sockbuf_max_incoming_auth, "( OLcfgGlAt:62 NAME 'olcSockbufMaxIncomingAuth' "
 			"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-	{ "srvtab", "file", 2, 2, 0,
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-		ARG_STRING, &ldap_srvtab,
-#else
-		ARG_IGNORED, NULL,
-#endif
-		"( OLcfgGlAt:63 NAME 'olcSrvtab' "
-			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+	{ "sortvals", "attr", 2, 0, 0, ARG_MAGIC|CFG_SORTVALS,
+		&config_generic, "( OLcfgGlAt:83 NAME 'olcSortVals' "
+			"DESC 'Attributes whose values will always be sorted' "
+			"EQUALITY caseIgnoreMatch "
+			"SYNTAX OMsDirectoryString )", NULL, NULL },
 	{ "subordinate", "[advertise]", 1, 2, 0, ARG_DB|ARG_MAGIC,
 		&config_subordinate, "( OLcfgDbAt:0.15 NAME 'olcSubordinate' "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
@@ -515,7 +572,8 @@
 			"SYNTAX OMsDN )", NULL, NULL },
 	{ "syncrepl", NULL, 0, 0, 0, ARG_DB|ARG_MAGIC,
 		&syncrepl_config, "( OLcfgDbAt:0.11 NAME 'olcSyncrepl' "
-			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+			"EQUALITY caseIgnoreMatch "
+			"SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
 	{ "threads", "count", 2, 2, 0,
 #ifdef NO_THREADS
 		ARG_IGNORED, NULL,
@@ -575,6 +633,14 @@
 #endif
 		"( OLcfgGlAt:73 NAME 'olcTLSCRLCheck' "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+	{ "TLSCRLFile", NULL, 0, 0, 0,
+#if defined(HAVE_GNUTLS)
+		CFG_TLS_CRL_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
+#else
+		ARG_IGNORED, NULL,
+#endif
+		"( OLcfgGlAt:82 NAME 'olcTLSCRLFile' "
+			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
 	{ "TLSRandFile", NULL, 0, 0, 0,
 #ifdef HAVE_TLS
 		CFG_TLS_RAND|ARG_STRING|ARG_MAGIC, &config_tls_option,
@@ -647,21 +713,20 @@
 		 "olcConnMaxPending $ olcConnMaxPendingAuth $ "
 		 "olcDisallows $ olcGentleHUP $ olcIdleTimeout $ "
 		 "olcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ "
-		 "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcLocalSSF $ "
-		 "olcLogLevel $ "
+		 "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ "
+		 "olcLocalSSF $ olcLogLevel $ "
 		 "olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ "
 		 "olcPluginLogFile $ olcReadOnly $ olcReferral $ "
-		 "olcReplicaPidFile $ olcReplicaArgsFile $ olcReplicationInterval $ "
 		 "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
 		 "olcRootDSE $ "
 		 "olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
-		 "olcSecurity $ olcSizeLimit $ "
-		 "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcSrvtab $ "
+		 "olcSecurity $ olcServerID $ olcSizeLimit $ "
+		 "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ "
 		 "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
 		 "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
 		 "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
 		 "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
-		 "olcToolThreads $ "
+		 "olcTLSCRLFile $ olcToolThreads $ "
 		 "olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
 		 "olcDitContentRules ) )", Cft_Global },
 	{ "( OLcfgGlOc:2 "
@@ -681,11 +746,14 @@
 		"DESC 'OpenLDAP Database-specific options' "
 		"SUP olcConfig STRUCTURAL "
 		"MUST olcDatabase "
-		"MAY ( olcSuffix $ olcSubordinate $ olcAccess $ olcLastMod $ olcLimits $ "
+		"MAY ( olcHidden $ olcSuffix $ olcSubordinate $ olcAccess $ "
+		 "olcLastMod $ olcLimits $ "
 		 "olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ "
+		 "olcReplicaArgsFile $ olcReplicaPidFile $ olcReplicationInterval $ "
 		 "olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
 		 "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncrepl $ "
-		 "olcTimeLimit $ olcUpdateDN $ olcUpdateRef ) )",
+		 "olcTimeLimit $ olcUpdateDN $ olcUpdateRef $ olcMirrorMode $ "
+		 "olcMonitoring ) )",
 		 	Cft_Database, NULL, cfAddDatabase },
 	{ "( OLcfgGlOc:5 "
 		"NAME 'olcOverlayConfig' "
@@ -698,7 +766,8 @@
 		"SUP olcConfig STRUCTURAL "
 		"MUST olcInclude "
 		"MAY ( cn $ olcRootDSE ) )",
-		Cft_Include, NULL, cfAddInclude },
+		/* Used to be Cft_Include, that def has been removed */
+		Cft_Abstract, NULL, cfAddInclude },
 	/* This should be STRUCTURAL like all the other database classes, but
 	 * that would mean inheriting all of the olcDatabaseConfig attributes,
 	 * which causes them to be merged twice in config_build_entry.
@@ -707,7 +776,7 @@
 		"NAME 'olcFrontendConfig' "
 		"DESC 'OpenLDAP frontend configuration' "
 		"AUXILIARY "
-		"MAY ( olcDefaultSearchBase $ olcPasswordHash ) )",
+		"MAY ( olcDefaultSearchBase $ olcPasswordHash $ olcSortVals ) )",
 		Cft_Database, NULL, NULL },
 #ifdef SLAPD_MODULES
 	{ "( OLcfgGlOc:8 "
@@ -720,9 +789,23 @@
 	{ NULL, 0, NULL }
 };
 
+typedef struct ServerID {
+	struct ServerID *si_next;
+	struct berval si_url;
+	int si_num;
+} ServerID;
+
+static ServerID *sid_list;
+
+typedef struct ADlist {
+	struct ADlist *al_next;
+	AttributeDescription *al_desc;
+} ADlist;
+
+static ADlist *sortVals;
+
 static int
 config_generic(ConfigArgs *c) {
-	char *p;
 	int i;
 
 	if ( c->op == SLAP_CONFIG_EMIT ) {
@@ -747,7 +830,6 @@
 			if ( c->be->be_limits ) {
 				char buf[4096*3];
 				struct berval bv;
-				int i;
 
 				for ( i=0; c->be->be_limits[i]; i++ ) {
 					bv.bv_len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i );
@@ -758,7 +840,8 @@
 						break;
 					}
 					bv.bv_val = buf + bv.bv_len;
-					limits_unparse( c->be->be_limits[i], &bv );
+					limits_unparse( c->be->be_limits[i], &bv,
+							sizeof( buf ) - ( bv.bv_val - buf ) );
 					bv.bv_len += bv.bv_val - buf;
 					bv.bv_val = buf;
 					value_add_one( &c->rvalue_vals, &bv );
@@ -792,6 +875,13 @@
 		case CFG_DEPTH:
 			c->value_int = c->be->be_max_deref_depth;
 			break;
+		case CFG_HIDDEN:
+			if ( SLAP_DBHIDDEN( c->be )) {
+				c->value_int = 1;
+			} else {
+				rc = 1;
+			}
+			break;
 		case CFG_OID: {
 			ConfigFile *cf = c->private;
 			if ( !cf )
@@ -857,7 +947,7 @@
 				AC_MEMCPY( abv.bv_val, ibuf, abv.bv_len );
 				/* Turn TAB / EOL into plain space */
 				for (src=bv.bv_val,dst=abv.bv_val+abv.bv_len; *src; src++) {
-					if (isspace(*src)) *dst++ = ' ';
+					if (isspace((unsigned char)*src)) *dst++ = ' ';
 					else *dst++ = *src;
 				}
 				*dst = '\0';
@@ -871,10 +961,6 @@
 			rc = (!i);
 			break;
 		}
-		case CFG_REPLOG:
-			if ( c->be->be_replogfile )
-				c->value_string = ch_strdup( c->be->be_replogfile );
-			break;
 		case CFG_ROOTDSE: {
 			ConfigFile *cf = c->private;
 			if ( cf->c_dseFiles ) {
@@ -884,6 +970,30 @@
 			}
 			}
 			break;
+		case CFG_SERVERID:
+			if ( sid_list ) {
+				ServerID *si;
+				struct berval bv;
+
+				for ( si = sid_list; si; si=si->si_next ) {
+					assert( si->si_num >= 0 && si->si_num <= SLAP_SYNC_SID_MAX );
+					if ( !BER_BVISEMPTY( &si->si_url )) {
+						bv.bv_len = si->si_url.bv_len + 6;
+						bv.bv_val = ch_malloc( bv.bv_len );
+						sprintf( bv.bv_val, "%d %s", si->si_num,
+							si->si_url.bv_val );
+						ber_bvarray_add( &c->rvalue_vals, &bv );
+					} else {
+						char buf[5];
+						bv.bv_val = buf;
+						bv.bv_len = sprintf( buf, "%d", si->si_num );
+						value_add_one( &c->rvalue_vals, &bv );
+					}
+				}
+			} else {
+				rc = 1;
+			}
+			break;
 		case CFG_LOGFILE:
 			if ( logfileName )
 				c->value_string = ch_strdup( logfileName );
@@ -893,12 +1003,32 @@
 		case CFG_LASTMOD:
 			c->value_int = (SLAP_NOLASTMOD(c->be) == 0);
 			break;
+		case CFG_MIRRORMODE:
+			if ( SLAP_SHADOW(c->be))
+				c->value_int = (SLAP_SINGLE_SHADOW(c->be) == 0);
+			else
+				rc = 1;
+			break;
+		case CFG_MONITORING:
+			c->value_int = (SLAP_DBMONITORING(c->be) != 0);
+			break;
 		case CFG_SSTR_IF_MAX:
 			c->value_int = index_substr_if_maxlen;
 			break;
 		case CFG_SSTR_IF_MIN:
 			c->value_int = index_substr_if_minlen;
 			break;
+		case CFG_IX_INTLEN:
+			c->value_int = index_intlen;
+			break;
+		case CFG_SORTVALS: {
+			ADlist *sv;
+			rc = 1;
+			for ( sv = sortVals; sv; sv = sv->al_next ) {
+				value_add_one( &c->rvalue_vals, &sv->al_desc->ad_cname );
+				rc = 0;
+			}
+			} break;
 #ifdef SLAPD_MODULES
 		case CFG_MODLOAD: {
 			ModPaths *mp = c->private;
@@ -979,6 +1109,8 @@
 		case CFG_AZPOLICY:
 		case CFG_DEPTH:
 		case CFG_LASTMOD:
+		case CFG_MIRRORMODE:
+		case CFG_MONITORING:
 		case CFG_SASLSECP:
 		case CFG_SSTR_IF_MAX:
 		case CFG_SSTR_IF_MIN:
@@ -997,16 +1129,41 @@
 			passwd_salt = NULL;
 			break;
 
-		case CFG_REPLOG:
-			ch_free( c->be->be_replogfile );
-			c->be->be_replogfile = NULL;
-			break;
-
 		case CFG_LOGFILE:
 			ch_free( logfileName );
 			logfileName = NULL;
+			if ( logfile ) {
+				fclose( logfile );
+				logfile = NULL;
+			}
 			break;
 
+		case CFG_SERVERID: {
+			ServerID *si, **sip;
+
+			for ( i=0, si = sid_list, sip = &sid_list;
+				si; si = *sip, i++ ) {
+				if ( c->valx == -1 || i == c->valx ) {
+					*sip = si->si_next;
+					ch_free( si );
+					if ( c->valx >= 0 )
+						break;
+				} else {
+					sip = &si->si_next;
+				}
+			}
+			}
+			break;
+		case CFG_HIDDEN:
+			c->be->be_flags &= ~SLAP_DBFLAG_HIDDEN;
+			break;
+
+		case CFG_IX_INTLEN:
+			index_intlen = SLAP_INDEX_INTLEN_DEFAULT;
+			index_intlen_strlen = SLAP_INDEX_INTLEN_STRLEN(
+				SLAP_INDEX_INTLEN_DEFAULT );
+			break;
+
 		case CFG_ACL:
 			if ( c->valx < 0 ) {
 				AccessControl *end;
@@ -1031,6 +1188,103 @@
 			}
 			break;
 
+		case CFG_OC: {
+			CfEntryInfo *ce;
+			/* Can be NULL when undoing a failed add */
+			if ( c->ca_entry ) {
+				ce = c->ca_entry->e_private;
+				/* can't modify the hardcoded schema */
+				if ( ce->ce_parent->ce_type == Cft_Global )
+					return 1;
+				}
+			}
+			cfn = c->private;
+			if ( c->valx < 0 ) {
+				ObjectClass *oc;
+
+				for( oc = cfn->c_oc_head; oc; oc_next( &oc )) {
+					oc_delete( oc );
+					if ( oc  == cfn->c_oc_tail )
+						break;
+				}
+				cfn->c_oc_head = cfn->c_oc_tail = NULL;
+			} else {
+				ObjectClass *oc, *prev = NULL;
+
+				for ( i=0, oc=cfn->c_oc_head; i<c->valx; i++) {
+					prev = oc;
+					oc_next( &oc );
+				}
+				oc_delete( oc );
+				if ( cfn->c_oc_tail == oc ) {
+					cfn->c_oc_tail = prev;
+				}
+				if ( cfn->c_oc_head == oc ) {
+					oc_next( &oc );
+					cfn->c_oc_head = oc;
+				}
+			}
+			break;
+
+		case CFG_ATTR: {
+			CfEntryInfo *ce;
+			/* Can be NULL when undoing a failed add */
+			if ( c->ca_entry ) {
+				ce = c->ca_entry->e_private;
+				/* can't modify the hardcoded schema */
+				if ( ce->ce_parent->ce_type == Cft_Global )
+					return 1;
+				}
+			}
+			cfn = c->private;
+			if ( c->valx < 0 ) {
+				AttributeType *at;
+
+				for( at = cfn->c_at_head; at; at_next( &at )) {
+					at_delete( at );
+					if ( at  == cfn->c_at_tail )
+						break;
+				}
+				cfn->c_at_head = cfn->c_at_tail = NULL;
+			} else {
+				AttributeType *at, *prev = NULL;
+
+				for ( i=0, at=cfn->c_at_head; i<c->valx; i++) {
+					prev = at;
+					at_next( &at );
+				}
+				at_delete( at );
+				if ( cfn->c_at_tail == at ) {
+					cfn->c_at_tail = prev;
+				}
+				if ( cfn->c_at_head == at ) {
+					at_next( &at );
+					cfn->c_at_head = at;
+				}
+			}
+			break;
+		case CFG_SORTVALS:
+			if ( c->valx < 0 ) {
+				ADlist *sv;
+				for ( sv = sortVals; sv; sv = sortVals ) {
+					sortVals = sv->al_next;
+					sv->al_desc->ad_type->sat_flags &= ~SLAP_AT_SORTED_VAL;
+					ch_free( sv );
+				}
+			} else {
+				ADlist *sv, **prev;
+				int i = 0;
+
+				for ( prev = &sortVals, sv = sortVals; i < c->valx; i++ ) {
+					prev = &sv->al_next;
+					sv = sv->al_next;
+				}
+				sv->al_desc->ad_type->sat_flags &= ~SLAP_AT_SORTED_VAL;
+				*prev = sv->al_next;
+				ch_free( sv );
+			}
+			break;
+
 		case CFG_LIMITS:
 			/* FIXME: there is no limits_free function */
 		case CFG_ATOPT:
@@ -1039,9 +1293,7 @@
 			/* FIXME: there is no way to remove attributes added by
 				a DSE file */
 		case CFG_OID:
-		case CFG_OC:
 		case CFG_DIT:
-		case CFG_ATTR:
 		case CFG_MODPATH:
 		default:
 			rc = 1;
@@ -1050,14 +1302,12 @@
 		return rc;
 	}
 
- 	p = strchr(c->line,'(' /*')'*/);
-
 	switch(c->type) {
 		case CFG_BACKEND:
 			if(!(c->bi = backend_info(c->argv[1]))) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> failed init", c->argv[0] );
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> failed init", c->argv[0] );
 				Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
-					c->log, c->msg, c->argv[1] );
+					c->log, c->cr_msg, c->argv[1] );
 				return(1);
 			}
 			break;
@@ -1071,11 +1321,11 @@
 			} else if ( !strcasecmp( c->argv[1], "frontend" )) {
 				c->be = frontendDB;
 			} else {
-				c->be = backend_db_init(c->argv[1], NULL);
+				c->be = backend_db_init(c->argv[1], NULL, c->valx, &c->reply);
 				if ( !c->be ) {
-					snprintf( c->msg, sizeof( c->msg ), "<%s> failed init", c->argv[0] );
-					Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
-						c->log, c->msg, c->argv[1] );
+					if ( c->cr_msg[0] == 0 )
+						snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> failed init", c->argv[0] );
+					Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n", c->log, c->cr_msg, c->argv[1] );
 					return(1);
 				}
 			}
@@ -1087,19 +1337,19 @@
 
 		case CFG_THREADS:
 			if ( c->value_int < 2 ) {
-				snprintf( c->msg, sizeof( c->msg ),
+				snprintf( c->cr_msg, sizeof( c->cr_msg ),
 					"threads=%d smaller than minimum value 2",
 					c->value_int );
 				Debug(LDAP_DEBUG_ANY, "%s: %s.\n",
-					c->log, c->msg, 0 );
+					c->log, c->cr_msg, 0 );
 				return 1;
 
 			} else if ( c->value_int > 2 * SLAP_MAX_WORKER_THREADS ) {
-				snprintf( c->msg, sizeof( c->msg ),
+				snprintf( c->cr_msg, sizeof( c->cr_msg ),
 					"warning, threads=%d larger than twice the default (2*%d=%d); YMMV",
 					c->value_int, SLAP_MAX_WORKER_THREADS, 2 * SLAP_MAX_WORKER_THREADS );
 				Debug(LDAP_DEBUG_ANY, "%s: %s.\n",
-					c->log, c->msg, 0 );
+					c->log, c->cr_msg, 0 );
 			}
 			if ( slapMode & SLAP_SERVER_MODE )
 				ldap_pvt_thread_pool_maxthreads(&connection_pool, c->value_int);
@@ -1133,9 +1383,9 @@
 		case CFG_AZPOLICY:
 			ch_free(c->value_string);
 			if (slap_sasl_setpolicy( c->argv[1] )) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse value", c->argv[0] );
 				Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-					c->log, c->msg, c->argv[1] );
+					c->log, c->cr_msg, c->argv[1] );
 				return(1);
 			}
 			break;
@@ -1150,9 +1400,9 @@
 			{
 			char *txt = slap_sasl_secprops( c->argv[1] );
 			if ( txt ) {
-				snprintf( c->msg, sizeof(c->msg), "<%s> %s",
+				snprintf( c->cr_msg, sizeof(c->cr_msg), "<%s> %s",
 					c->argv[0], txt );
-				Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
+				Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->cr_msg, 0 );
 				return(1);
 			}
 			break;
@@ -1166,7 +1416,9 @@
 		case CFG_OID: {
 			OidMacro *om;
 
-			if(parse_oidm(c->fname, c->lineno, c->argc, c->argv, 1, &om))
+			if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
+				cfn = c->private;
+			if(parse_oidm(c, 1, &om))
 				return(1);
 			if (!cfn->c_om_head) cfn->c_om_head = om;
 			cfn->c_om_tail = om;
@@ -1174,32 +1426,80 @@
 			break;
 
 		case CFG_OC: {
-			ObjectClass *oc;
+			ObjectClass *oc, *prev;
 
-			if(parse_oc(c->fname, c->lineno, p, c->argv, &oc)) return(1);
+			if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
+				cfn = c->private;
+			if ( c->valx < 0 ) {
+				prev = cfn->c_oc_tail;
+			} else {
+				prev = NULL;
+				/* If adding anything after the first, prev is easy */
+				if ( c->valx ) {
+					int i;
+					for (i=0, oc = cfn->c_oc_head; i<c->valx; i++) {
+						prev = oc;
+						oc_next( &oc );
+					}
+				} else
+				/* If adding the first, and head exists, find its prev */
+					if (cfn->c_oc_head) {
+					for ( oc_start( &oc ); oc != cfn->c_oc_head; ) {
+						prev = oc;
+						oc_next( &oc );
+					}
+				}
+				/* else prev is NULL, append to end of global list */
+			}
+			if(parse_oc(c, &oc, prev)) return(1);
 			if (!cfn->c_oc_head) cfn->c_oc_head = oc;
-			cfn->c_oc_tail = oc;
+			if (cfn->c_oc_tail == prev) cfn->c_oc_tail = oc;
 			}
 			break;
 
+		case CFG_ATTR: {
+			AttributeType *at, *prev;
+
+			if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
+				cfn = c->private;
+			if ( c->valx < 0 ) {
+				prev = cfn->c_at_tail;
+			} else {
+				prev = NULL;
+				/* If adding anything after the first, prev is easy */
+				if ( c->valx ) {
+					int i;
+					for (i=0, at = cfn->c_at_head; i<c->valx; i++) {
+						prev = at;
+						at_next( &at );
+					}
+				} else
+				/* If adding the first, and head exists, find its prev */
+					if (cfn->c_at_head) {
+					for ( at_start( &at ); at != cfn->c_at_head; ) {
+						prev = at;
+						at_next( &at );
+					}
+				}
+				/* else prev is NULL, append to end of global list */
+			}
+			if(parse_at(c, &at, prev)) return(1);
+			if (!cfn->c_at_head) cfn->c_at_head = at;
+			if (cfn->c_at_tail == prev) cfn->c_at_tail = at;
+			}
+			break;
+
 		case CFG_DIT: {
 			ContentRule *cr;
 
-			if(parse_cr(c->fname, c->lineno, p, c->argv, &cr)) return(1);
+			if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
+				cfn = c->private;
+			if(parse_cr(c, &cr)) return(1);
 			if (!cfn->c_cr_head) cfn->c_cr_head = cr;
 			cfn->c_cr_tail = cr;
 			}
 			break;
 
-		case CFG_ATTR: {
-			AttributeType *at;
-
-			if(parse_at(c->fname, c->lineno, p, c->argv, &at)) return(1);
-			if (!cfn->c_at_head) cfn->c_at_head = at;
-			cfn->c_at_tail = at;
-			}
-			break;
-
 		case CFG_ATOPT:
 			ad_define_option(NULL, NULL, 0);
 			for(i = 1; i < c->argc; i++)
@@ -1207,6 +1507,63 @@
 					return(1);
 			break;
 
+		case CFG_IX_INTLEN:
+			if ( c->value_int < SLAP_INDEX_INTLEN_DEFAULT )
+				c->value_int = SLAP_INDEX_INTLEN_DEFAULT;
+			else if ( c->value_int > 255 )
+				c->value_int = 255;
+			index_intlen = c->value_int;
+			index_intlen_strlen = SLAP_INDEX_INTLEN_STRLEN(
+				index_intlen );
+			break;
+			
+		case CFG_SORTVALS: {
+			ADlist *svnew = NULL, *svtail, *sv;
+
+			for ( i = 1; i < c->argc; i++ ) {
+				AttributeDescription *ad = NULL;
+				const char *text;
+				int rc;
+
+				rc = slap_str2ad( c->argv[i], &ad, &text );
+				if ( rc ) {
+					snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown attribute type #%d",
+						c->argv[0], i );
+sortval_reject:
+					Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+						c->log, c->cr_msg, c->argv[i] );
+					for ( sv = svnew; sv; sv = svnew ) {
+						svnew = sv->al_next;
+						ch_free( sv );
+					}
+					return 1;
+				}
+				if (( ad->ad_type->sat_flags & SLAP_AT_ORDERED ) ||
+					ad->ad_type->sat_single_value ) {
+					snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> inappropriate attribute type #%d",
+						c->argv[0], i );
+					goto sortval_reject;
+				}
+				sv = ch_malloc( sizeof( ADlist ));
+				sv->al_desc = ad;
+				if ( !svnew ) {
+					svnew = sv;
+				} else {
+					svtail->al_next = sv;
+				}
+				svtail = sv;
+			}
+			sv->al_next = NULL;
+			for ( sv = svnew; sv; sv = sv->al_next )
+				sv->al_desc->ad_type->sat_flags |= SLAP_AT_SORTED_VAL;
+			for ( sv = sortVals; sv && sv->al_next; sv = sv->al_next );
+			if ( sv )
+				sv->al_next = svnew;
+			else
+				sortVals = svnew;
+			}
+			break;
+
 		case CFG_ACL:
 			/* Don't append to the global ACL if we're on a specific DB */
 			i = c->valx;
@@ -1222,34 +1579,138 @@
 			}
 			break;
 
-		case CFG_REPLOG:
-			if(SLAP_MONITOR(c->be)) {
-				Debug(LDAP_DEBUG_ANY, "%s: "
-					"\"replogfile\" should not be used "
-					"inside monitor database\n",
-					c->log, 0, 0);
-				return(0);	/* FIXME: should this be an error? */
-			}
-
-			c->be->be_replogfile = c->value_string;
-			break;
-
 		case CFG_ROOTDSE:
-			if(read_root_dse_file(c->argv[1])) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> could not read file", c->argv[0] );
+			if(root_dse_read_file(c->argv[1])) {
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> could not read file", c->argv[0] );
 				Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
-					c->log, c->msg, c->argv[1] );
+					c->log, c->cr_msg, c->argv[1] );
 				return(1);
 			}
 			{
 				struct berval bv;
 				ber_str2bv( c->argv[1], 0, 1, &bv );
+				if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
+					cfn = c->private;
 				ber_bvarray_add( &cfn->c_dseFiles, &bv );
 			}
 			break;
 
+		case CFG_SERVERID:
+			{
+				ServerID *si, **sip;
+				LDAPURLDesc *lud;
+				int num;
+				if ( lutil_atoi( &num, c->argv[1] ) ||
+					num < 0 || num > SLAP_SYNC_SID_MAX )
+				{
+					snprintf( c->cr_msg, sizeof( c->cr_msg ),
+						"<%s> illegal server ID", c->argv[0] );
+					Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+						c->log, c->cr_msg, c->argv[1] );
+					return 1;
+				}
+				/* only one value allowed if no URL is given */
+				if ( c->argc > 2 ) {
+					int len;
+
+					if ( sid_list && BER_BVISEMPTY( &sid_list->si_url )) {
+						snprintf( c->cr_msg, sizeof( c->cr_msg ),
+							"<%s> only one server ID allowed now", c->argv[0] );
+						Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+							c->log, c->cr_msg, c->argv[1] );
+						return 1;
+					}
+
+					if ( ldap_url_parse( c->argv[2], &lud )) {
+						snprintf( c->cr_msg, sizeof( c->cr_msg ),
+							"<%s> invalid URL", c->argv[0] );
+						Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+							c->log, c->cr_msg, c->argv[2] );
+						return 1;
+					}
+					len = strlen( c->argv[2] );
+					si = ch_malloc( sizeof(ServerID) + len + 1 );
+					si->si_url.bv_val = (char *)(si+1);
+					si->si_url.bv_len = len;
+					strcpy( si->si_url.bv_val, c->argv[2] );
+				} else {
+					if ( sid_list ) {
+						snprintf( c->cr_msg, sizeof( c->cr_msg ),
+							"<%s> unqualified server ID not allowed now", c->argv[0] );
+						Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+							c->log, c->cr_msg, c->argv[1] );
+						return 1;
+					}
+					si = ch_malloc( sizeof(ServerID) );
+					BER_BVZERO( &si->si_url );
+					slap_serverID = num;
+					Debug( LDAP_DEBUG_CONFIG,
+						"%s: SID=%d\n",
+						c->log, slap_serverID, 0 );
+				}
+				si->si_next = NULL;
+				si->si_num = num;
+				for ( sip = &sid_list; *sip; sip = &(*sip)->si_next );
+				*sip = si;
+
+				if (( slapMode & SLAP_SERVER_MODE ) && c->argc > 2 ) {
+					/* If hostname is empty, or is localhost, or matches
+					 * our hostname, this serverID refers to this host.
+					 * Compare it against listeners and ports.
+					 */
+					if ( !lud->lud_host || !lud->lud_host[0] ||
+						!strncasecmp("localhost", lud->lud_host,
+							STRLENOF("localhost")) ||
+						!strcasecmp( global_host, lud->lud_host )) {
+						Listener **l = slapd_get_listeners();
+						int i;
+
+						for ( i=0; l[i]; i++ ) {
+							LDAPURLDesc *lu2;
+							int isMe = 0;
+							ldap_url_parse( l[i]->sl_url.bv_val, &lu2 );
+							do {
+								if ( strcasecmp( lud->lud_scheme,
+									lu2->lud_scheme ))
+									break;
+								if ( lud->lud_port != lu2->lud_port )
+									break;
+								/* Listener on ANY address */
+								if ( !lu2->lud_host || !lu2->lud_host[0] ) {
+									isMe = 1;
+									break;
+								}
+								/* URL on ANY address */
+								if ( !lud->lud_host || !lud->lud_host[0] ) {
+									isMe = 1;
+									break;
+								}
+								/* Listener has specific host, must
+								 * match it
+								 */
+								if ( !strcasecmp( lud->lud_host,
+									lu2->lud_host )) {
+									isMe = 1;
+									break;
+								}
+							} while(0);
+							ldap_free_urldesc( lu2 );
+							if ( isMe ) {
+								slap_serverID = si->si_num;
+								Debug( LDAP_DEBUG_CONFIG,
+									"%s: SID=%d (listener=%s)\n",
+									c->log, slap_serverID,
+									l[i]->sl_url.bv_val );
+								break;
+							}
+						}
+					}
+				}
+				if ( c->argc > 2 )
+					ldap_free_urldesc( lud );
+			}
+			break;
 		case CFG_LOGFILE: {
-				FILE *logfile;
 				if ( logfileName ) ch_free( logfileName );
 				logfileName = c->value_string;
 				logfile = fopen(logfileName, "w");
@@ -1258,10 +1719,10 @@
 
 		case CFG_LASTMOD:
 			if(SLAP_NOLASTMODCMD(c->be)) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> not available for %s database",
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> not available for %s database",
 					c->argv[0], c->be->bd_info->bi_type );
 				Debug(LDAP_DEBUG_ANY, "%s: %s\n",
-					c->log, c->msg, 0 );
+					c->log, c->cr_msg, 0 );
 				return(1);
 			}
 			if(c->value_int)
@@ -1270,11 +1731,39 @@
 				SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_NOLASTMOD;
 			break;
 
+		case CFG_MIRRORMODE:
+			if(!SLAP_SHADOW(c->be)) {
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> database is not a shadow",
+					c->argv[0] );
+				Debug(LDAP_DEBUG_ANY, "%s: %s\n",
+					c->log, c->cr_msg, 0 );
+				return(1);
+			}
+			if(c->value_int)
+				SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_SINGLE_SHADOW;
+			else
+				SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_SINGLE_SHADOW;
+			break;
+
+		case CFG_MONITORING:
+			if(c->value_int)
+				SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_MONITORING;
+			else
+				SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_MONITORING;
+			break;
+
+		case CFG_HIDDEN:
+			if (c->value_int)
+				SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_HIDDEN;
+			else
+				SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_HIDDEN;
+			break;
+
 		case CFG_SSTR_IF_MAX:
 			if (c->value_int < index_substr_if_minlen) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value", c->argv[0] );
 				Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
-					c->log, c->msg, c->value_int );
+					c->log, c->cr_msg, c->value_int );
 				return(1);
 			}
 			index_substr_if_maxlen = c->value_int;
@@ -1282,9 +1771,9 @@
 
 		case CFG_SSTR_IF_MIN:
 			if (c->value_int > index_substr_if_maxlen) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value", c->argv[0] );
 				Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
-					c->log, c->msg, c->value_int );
+					c->log, c->cr_msg, c->value_int );
 				return(1);
 			}
 			index_substr_if_minlen = c->value_int;
@@ -1299,10 +1788,10 @@
 				modcur = c->private;
 				/* This should never fail */
 				if ( module_path( modcur->mp_path.bv_val )) {
-					snprintf( c->msg, sizeof( c->msg ), "<%s> module path no longer valid",
+					snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> module path no longer valid",
 						c->argv[0] );
 					Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
-						c->log, c->msg, modcur->mp_path.bv_val );
+						c->log, c->cr_msg, modcur->mp_path.bv_val );
 					return(1);
 				}
 			}
@@ -1314,14 +1803,18 @@
 				char *ptr;
 				if ( c->op == SLAP_CONFIG_ADD ) {
 					ptr = c->line + STRLENOF("moduleload");
-					while (!isspace(*ptr)) ptr++;
-					while (isspace(*ptr)) ptr++;
+					while (!isspace((unsigned char) *ptr)) ptr++;
+					while (isspace((unsigned char) *ptr)) ptr++;
 				} else {
 					ptr = c->line;
 				}
 				ber_str2bv(ptr, 0, 1, &bv);
 				ber_bvarray_add( &modcur->mp_loads, &bv );
 			}
+			/* Check for any new hardcoded schema */
+			if ( c->op == LDAP_MOD_ADD && CONFIG_ONLINE_ADD( c )) {
+				config_check_schema( NULL, &cfBackInfo );
+			}
 			break;
 
 		case CFG_MODPATH:
@@ -1386,13 +1879,10 @@
 
 
 		default:
-			Debug( SLAPD_DEBUG_CONFIG_ERROR,
-				"%s: unknown CFG_TYPE %d"
-				SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+			Debug( LDAP_DEBUG_ANY,
+				"%s: unknown CFG_TYPE %d.\n",
 				c->log, c->type, 0 );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
 			return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
 
 	}
 	return(0);
@@ -1459,7 +1949,7 @@
 	return(0);
 }
 
-/* For backward compatibility we allow this in the global entry
+/* For RE23 compatibility we allow this in the global entry
  * but we now defer it to the frontend entry to allow modules
  * to load new hash types.
  */
@@ -1493,17 +1983,17 @@
 	}
 	for(i = 1; i < c->argc; i++) {
 		if(!lutil_passwd_scheme(c->argv[i])) {
-			snprintf( c->msg, sizeof( c->msg ), "<%s> scheme not available", c->argv[0] );
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> scheme not available", c->argv[0] );
 			Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
-				c->log, c->msg, c->argv[i]);
+				c->log, c->cr_msg, c->argv[i]);
 		} else {
 			ldap_charray_add(&default_passwd_hash, c->argv[i]);
 		}
 	}
 	if(!default_passwd_hash) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> no valid hashes found", c->argv[0] );
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> no valid hashes found", c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s\n",
-			c->log, c->msg, 0 );
+			c->log, c->cr_msg, 0 );
 		return(1);
 	}
 	return(0);
@@ -1542,7 +2032,7 @@
 		struct berval bv;
 		bv.bv_val = buf;
 		bv.bv_len = 0;
-		limits_unparse_one( lim, SLAP_LIMIT_SIZE, &bv );
+		limits_unparse_one( lim, SLAP_LIMIT_SIZE, &bv, sizeof( buf ) );
 		if ( !BER_BVISEMPTY( &bv ))
 			value_add_one( &c->rvalue_vals, &bv );
 		else
@@ -1562,9 +2052,9 @@
 		if(!strncasecmp(c->argv[i], "size", 4)) {
 			rc = limits_parse_one(c->argv[i], lim);
 			if ( rc ) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse value", c->argv[0] );
 				Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-					c->log, c->msg, c->argv[i]);
+					c->log, c->cr_msg, c->argv[i]);
 				return(1);
 			}
 		} else {
@@ -1572,9 +2062,9 @@
 				lim->lms_s_soft = -1;
 			} else {
 				if ( lutil_atoix( &lim->lms_s_soft, c->argv[i], 0 ) != 0 ) {
-					snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
+					snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse limit", c->argv[0]);
 					Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-						c->log, c->msg, c->argv[i]);
+						c->log, c->cr_msg, c->argv[i]);
 					return(1);
 				}
 			}
@@ -1593,7 +2083,7 @@
 		struct berval bv;
 		bv.bv_val = buf;
 		bv.bv_len = 0;
-		limits_unparse_one( lim, SLAP_LIMIT_TIME, &bv );
+		limits_unparse_one( lim, SLAP_LIMIT_TIME, &bv, sizeof( buf ) );
 		if ( !BER_BVISEMPTY( &bv ))
 			value_add_one( &c->rvalue_vals, &bv );
 		else
@@ -1609,9 +2099,9 @@
 		if(!strncasecmp(c->argv[i], "time", 4)) {
 			rc = limits_parse_one(c->argv[i], lim);
 			if ( rc ) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse value", c->argv[0] );
 				Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-					c->log, c->msg, c->argv[i]);
+					c->log, c->cr_msg, c->argv[i]);
 				return(1);
 			}
 		} else {
@@ -1619,9 +2109,9 @@
 				lim->lms_t_soft = -1;
 			} else {
 				if ( lutil_atoix( &lim->lms_t_soft, c->argv[i], 0 ) != 0 ) {
-					snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
+					snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse limit", c->argv[0]);
 					Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-						c->log, c->msg, c->argv[i]);
+						c->log, c->cr_msg, c->argv[i]);
 					return(1);
 				}
 			}
@@ -1633,28 +2123,21 @@
 
 static int
 config_overlay(ConfigArgs *c) {
-	slap_overinfo *oi;
 	if (c->op == SLAP_CONFIG_EMIT) {
 		return 1;
 	} else if ( c->op == LDAP_MOD_DELETE ) {
 		assert(0);
 	}
-	if(c->argv[1][0] == '-' && overlay_config(c->be, &c->argv[1][1])) {
+	if(c->argv[1][0] == '-' && overlay_config(c->be, &c->argv[1][1],
+		c->valx, &c->bi)) {
 		/* log error */
-		Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: (optional) %s overlay \"%s\" configuration failed"
-			SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+		Debug( LDAP_DEBUG_ANY,
+			"%s: (optional) %s overlay \"%s\" configuration failed.\n",
 			c->log, c->be == frontendDB ? "global " : "", &c->argv[1][1]);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
 		return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
-	} else if(overlay_config(c->be, c->argv[1])) {
+	} else if(overlay_config(c->be, c->argv[1], c->valx, &c->bi)) {
 		return(1);
 	}
-	/* Setup context for subsequent config directives.
-	 * The newly added overlay is at the head of the list.
-	 */
-	oi = (slap_overinfo *)c->be->bd_info;
-	c->bi = &oi->oi_list->on_bi;
 	return(0);
 }
 
@@ -1765,54 +2248,71 @@
 			int i = c->valx;
 			ch_free( c->be->be_suffix[i].bv_val );
 			ch_free( c->be->be_nsuffix[i].bv_val );
-			for (; c->be->be_suffix[i].bv_val; i++) {
+			do {
 				c->be->be_suffix[i] = c->be->be_suffix[i+1];
 				c->be->be_nsuffix[i] = c->be->be_nsuffix[i+1];
-			}
+				i++;
+			} while ( !BER_BVISNULL( &c->be->be_suffix[i] ) );
 		}
 		return 0;
 	}
 
 #ifdef SLAPD_MONITOR_DN
 	if(!strcasecmp(c->argv[1], SLAPD_MONITOR_DN)) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> DN is reserved for monitoring slapd",
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> DN is reserved for monitoring slapd",
 			c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
-			c->log, c->msg, SLAPD_MONITOR_DN);
+			c->log, c->cr_msg, SLAPD_MONITOR_DN);
 		return(1);
 	}
 #endif
 
+	if (SLAP_DB_ONE_SUFFIX( c->be ) && c->be->be_suffix ) {
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> Only one suffix is allowed on this %s backend",
+			c->argv[0], c->be->bd_info->bi_type );
+		Debug(LDAP_DEBUG_ANY, "%s: %s\n",
+			c->log, c->cr_msg, 0);
+		return(1);
+	}
+
 	pdn = c->value_dn;
 	ndn = c->value_ndn;
-	tbe = select_backend(&ndn, 0, 0);
+
+	if (SLAP_DBHIDDEN( c->be ))
+		tbe = NULL;
+	else
+		tbe = select_backend(&ndn, 0);
 	if(tbe == c->be) {
-		Debug( SLAPD_DEBUG_CONFIG_ERROR,
-			"%s: suffix already served by this backend!"
-			SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+		Debug( LDAP_DEBUG_ANY, "%s: suffix already served by this backend!.\n",
 			c->log, 0, 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
 		return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
 		free(pdn.bv_val);
 		free(ndn.bv_val);
 	} else if(tbe) {
-		char	*type = tbe->bd_info->bi_type;
+		BackendDB *b2 = tbe;
 
-		if ( overlay_is_over( tbe ) ) {
-			slap_overinfo	*oi = (slap_overinfo *)tbe->bd_info->bi_private;
-			type = oi->oi_orig->bi_type;
+		/* Does tbe precede be? */
+		while (( b2 = LDAP_STAILQ_NEXT(b2, be_next )) && b2 && b2 != c->be );
+
+		if ( b2 ) {
+			char	*type = tbe->bd_info->bi_type;
+
+			if ( overlay_is_over( tbe ) ) {
+				slap_overinfo	*oi = (slap_overinfo *)tbe->bd_info->bi_private;
+				type = oi->oi_orig->bi_type;
+			}
+
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> namingContext \"%s\" "
+				"already served by a preceding %s database",
+				c->argv[0], pdn.bv_val, type );
+			Debug(LDAP_DEBUG_ANY, "%s: %s serving namingContext \"%s\"\n",
+				c->log, c->cr_msg, tbe->be_suffix[0].bv_val);
+			free(pdn.bv_val);
+			free(ndn.bv_val);
+			return(1);
 		}
-
-		snprintf( c->msg, sizeof( c->msg ), "<%s> namingContext \"%s\" already served by "
-			"a preceding %s database serving namingContext",
-			c->argv[0], pdn.bv_val, type );
-		Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-			c->log, c->msg, tbe->be_suffix[0].bv_val);
-		free(pdn.bv_val);
-		free(ndn.bv_val);
-		return(1);
-	} else if(pdn.bv_len == 0 && default_search_nbase.bv_len) {
+	}
+	if(pdn.bv_len == 0 && default_search_nbase.bv_len) {
 		Debug(LDAP_DEBUG_ANY, "%s: suffix DN empty and default search "
 			"base provided \"%s\" (assuming okay)\n",
 			c->log, default_search_base.bv_val, 0);
@@ -1866,12 +2366,12 @@
 		return 0;
 	}
 
-	tbe = select_backend(&c->be->be_rootndn, 0, 0);
+	tbe = select_backend(&c->be->be_rootndn, 0);
 	if(tbe != c->be) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> can only be set when rootdn is under suffix",
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> can only be set when rootdn is under suffix",
 			c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s\n",
-			c->log, c->msg, 0);
+			c->log, c->cr_msg, 0);
 		return(1);
 	}
 	if ( !BER_BVISNULL( &c->be->be_rootpw ))
@@ -1892,14 +2392,15 @@
 		{ BER_BVC("modrdn"),		0 },
 		{ BER_BVC("delete"),		SLAP_RESTRICT_OP_DELETE },
 		{ BER_BVC("search"),		SLAP_RESTRICT_OP_SEARCH },
-		{ BER_BVC("compare"),	SLAP_RESTRICT_OP_COMPARE },
+		{ BER_BVC("compare"),		SLAP_RESTRICT_OP_COMPARE },
 		{ BER_BVC("read"),		SLAP_RESTRICT_OP_READS },
 		{ BER_BVC("write"),		SLAP_RESTRICT_OP_WRITES },
-		{ BER_BVC("extended"),	SLAP_RESTRICT_OP_EXTENDED },
+		{ BER_BVC("extended"),		SLAP_RESTRICT_OP_EXTENDED },
 		{ BER_BVC("extended=" LDAP_EXOP_START_TLS ),		SLAP_RESTRICT_EXOP_START_TLS },
 		{ BER_BVC("extended=" LDAP_EXOP_MODIFY_PASSWD ),	SLAP_RESTRICT_EXOP_MODIFY_PASSWD },
 		{ BER_BVC("extended=" LDAP_EXOP_X_WHO_AM_I ),		SLAP_RESTRICT_EXOP_WHOAMI },
 		{ BER_BVC("extended=" LDAP_EXOP_X_CANCEL ),		SLAP_RESTRICT_EXOP_CANCEL },
+		{ BER_BVC("all"),		SLAP_RESTRICT_OP_ALL },
 		{ BER_BVNULL,	0 }
 	};
 
@@ -1917,9 +2418,9 @@
 	}
 	i = verbs_to_mask( c->argc, c->argv, restrictable_ops, &restrictops );
 	if ( i ) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> unknown operation", c->argv[0] );
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown operation", c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
-			c->log, c->msg, c->argv[i]);
+			c->log, c->cr_msg, c->argv[i]);
 		return(1);
 	}
 	if ( restrictops & SLAP_RESTRICT_OP_EXTENDED )
@@ -1937,6 +2438,7 @@
 		{ BER_BVC("bind_anon_cred"),	SLAP_ALLOW_BIND_ANON_CRED },
 		{ BER_BVC("bind_anon_dn"),	SLAP_ALLOW_BIND_ANON_DN },
 		{ BER_BVC("update_anon"),	SLAP_ALLOW_UPDATE_ANON },
+		{ BER_BVC("proxy_authz_anon"),	SLAP_ALLOW_PROXY_AUTHZ_ANON },
 		{ BER_BVNULL,	0 }
 	};
 	if (c->op == SLAP_CONFIG_EMIT) {
@@ -1952,9 +2454,9 @@
 	}
 	i = verbs_to_mask(c->argc, c->argv, allowable_ops, &allows);
 	if ( i ) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown feature", c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
-			c->log, c->msg, c->argv[i]);
+			c->log, c->cr_msg, c->argv[i]);
 		return(1);
 	}
 	global_allows |= allows;
@@ -1968,7 +2470,6 @@
 	slap_verbmasks disallowable_ops[] = {
 		{ BER_BVC("bind_anon"),		SLAP_DISALLOW_BIND_ANON },
 		{ BER_BVC("bind_simple"),	SLAP_DISALLOW_BIND_SIMPLE },
-		{ BER_BVC("bind_krb4"),		SLAP_DISALLOW_BIND_KRBV4 },
 		{ BER_BVC("tls_2_anon"),		SLAP_DISALLOW_TLS_2_ANON },
 		{ BER_BVC("tls_authc"),		SLAP_DISALLOW_TLS_AUTHC },
 		{ BER_BVNULL, 0 }
@@ -1986,9 +2487,9 @@
 	}
 	i = verbs_to_mask(c->argc, c->argv, disallowable_ops, &disallows);
 	if ( i ) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown feature", c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
-			c->log, c->msg, c->argv[i]);
+			c->log, c->cr_msg, c->argv[i]);
 		return(1);
 	}
 	global_disallows |= disallows;
@@ -2029,13 +2530,13 @@
 	i = verbs_to_mask(argc, argv, requires_ops, &requires);
 	if ( i ) {
 		if (strcasecmp( c->argv[ i ], "none" ) == 0 ) {
-			snprintf( c->msg, sizeof( c->msg ), "<%s> \"none\" (#%d) must be listed first", c->argv[0], i - 1 );
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> \"none\" (#%d) must be listed first", c->argv[0], i - 1 );
 			Debug(LDAP_DEBUG_ANY, "%s: %s\n",
-				c->log, c->msg, 0);
+				c->log, c->cr_msg, 0);
 		} else {
-			snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature #%d", c->argv[0], i - 1 );
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown feature #%d", c->argv[0], i - 1 );
 			Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-				c->log, c->msg, c->argv[i]);
+				c->log, c->cr_msg, c->argv[i]);
 		}
 		return(1);
 	}
@@ -2062,8 +2563,10 @@
 		{ BER_BVC("Stats2"),	LDAP_DEBUG_STATS2 },
 		{ BER_BVC("Shell"),	LDAP_DEBUG_SHELL },
 		{ BER_BVC("Parse"),	LDAP_DEBUG_PARSE },
+#if 0	/* no longer used (nor supported) */
 		{ BER_BVC("Cache"),	LDAP_DEBUG_CACHE },
 		{ BER_BVC("Index"),	LDAP_DEBUG_INDEX },
+#endif
 		{ BER_BVC("Sync"),	LDAP_DEBUG_SYNC },
 		{ BER_BVC("None"),	LDAP_DEBUG_NONE },
 		{ BER_BVNULL,		0 }
@@ -2188,6 +2691,28 @@
 	return mask_to_verbs( loglevel_ops, l, bva );
 }
 
+int
+loglevel_print( FILE *out )
+{
+	int	i;
+
+	if ( loglevel_ops == NULL ) {
+		loglevel_init();
+	}
+
+	fprintf( out, "Installed log subsystems:\n\n" );
+	for ( i = 0; !BER_BVISNULL( &loglevel_ops[ i ].word ); i++ ) {
+		fprintf( out, "\t%-30s (%lu)\n",
+			loglevel_ops[ i ].word.bv_val,
+			loglevel_ops[ i ].mask );
+	}
+
+	fprintf( out, "\nNOTE: custom log subsystems may be later installed "
+		"by specific code\n\n" );
+
+	return 0;
+}
+
 static int config_syslog;
 
 static int
@@ -2220,18 +2745,18 @@
 	for( i=1; i < c->argc; i++ ) {
 		int	level;
 
-		if ( isdigit( c->argv[i][0] ) || c->argv[i][0] == '-' ) {
+		if ( isdigit((unsigned char)c->argv[i][0]) || c->argv[i][0] == '-' ) {
 			if( lutil_atoi( &level, c->argv[i] ) != 0 ) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse level", c->argv[0] );
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse level", c->argv[0] );
 				Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-					c->log, c->msg, c->argv[i]);
+					c->log, c->cr_msg, c->argv[i]);
 				return( 1 );
 			}
 		} else {
 			if ( str2loglevel( c->argv[i], &level ) ) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> unknown level", c->argv[0] );
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown level", c->argv[0] );
 				Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-					c->log, c->msg, c->argv[i]);
+					c->log, c->cr_msg, c->argv[i]);
 				return( 1 );
 			}
 		}
@@ -2270,9 +2795,9 @@
 		return 0;
 	}
 	if(validate_global_referral(c->argv[1])) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> invalid URL", c->argv[0] );
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid URL", c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
-			c->log, c->msg, c->argv[1]);
+			c->log, c->cr_msg, c->argv[1]);
 		return(1);
 	}
 
@@ -2330,7 +2855,7 @@
 	}
 	for(i = 1; i < c->argc; i++) {
 		slap_ssf_t *tgt = NULL;
-		char *src;
+		char *src = NULL;
 		for ( j=0; !BER_BVISNULL( &sec_keys[j].key ); j++ ) {
 			if(!strncasecmp(c->argv[i], sec_keys[j].key.bv_val,
 				sec_keys[j].key.bv_len)) {
@@ -2340,16 +2865,16 @@
 			}
 		}
 		if ( !tgt ) {
-			snprintf( c->msg, sizeof( c->msg ), "<%s> unknown factor", c->argv[0] );
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown factor", c->argv[0] );
 			Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
-				c->log, c->msg, c->argv[i]);
+				c->log, c->cr_msg, c->argv[i]);
 			return(1);
 		}
 
 		if ( lutil_atou( tgt, src ) != 0 ) {
-			snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse factor", c->argv[0] );
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse factor", c->argv[0] );
 			Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-				c->log, c->msg, c->argv[i]);
+				c->log, c->cr_msg, c->argv[i]);
 			return(1);
 		}
 	}
@@ -2357,10 +2882,14 @@
 }
 
 char *
-anlist_unparse( AttributeName *an, char *ptr ) {
+anlist_unparse( AttributeName *an, char *ptr, ber_len_t buflen ) {
 	int comma = 0;
+	char *start = ptr;
 
 	for (; !BER_BVISNULL( &an->an_name ); an++) {
+		/* if buflen == 0, assume the buffer size has been 
+		 * already checked otherwise */
+		if ( buflen > 0 && buflen - ( ptr - start ) < comma + an->an_name.bv_len ) return NULL;
 		if ( comma ) *ptr++ = ',';
 		ptr = lutil_strcopy( ptr, an->an_name.bv_val );
 		comma = 1;
@@ -2368,238 +2897,7 @@
 	return ptr;
 }
 
-static void
-replica_unparse( struct slap_replica_info *ri, int i, struct berval *bv )
-{
-	int len;
-	char *ptr;
-	struct berval bc = BER_BVNULL;
-	char numbuf[32];
-
-	assert( !BER_BVISNULL( &ri->ri_bindconf.sb_uri ) );
-	
-	BER_BVZERO( bv );
-
-	len = snprintf(numbuf, sizeof( numbuf ), SLAP_X_ORDERED_FMT, i );
-	if ( len >= sizeof( numbuf ) ) {
-		/* FIXME: how can indicate error? */
-		return;
-	}
-
-	if ( ri->ri_nsuffix ) {
-		for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
-			len += ri->ri_nsuffix[i].bv_len + STRLENOF(" suffix=\"\"");
-		}
-	}
-	if ( ri->ri_attrs ) {
-		len += STRLENOF(" attrs");
-		if ( ri->ri_exclude ) len++;
-		for (i=0; !BER_BVISNULL( &ri->ri_attrs[i].an_name ); i++) {
-			len += 1 + ri->ri_attrs[i].an_name.bv_len;
-		}
-	}
-	bindconf_unparse( &ri->ri_bindconf, &bc );
-	len += bc.bv_len;
-
-	bv->bv_val = ch_malloc(len + 1);
-	bv->bv_len = len;
-
-	ptr = lutil_strcopy( bv->bv_val, numbuf );
-
-	/* start with URI from bindconf */
-	assert( !BER_BVISNULL( &bc ) );
-	if ( bc.bv_val ) {
-		strcpy( ptr, bc.bv_val );
-		ch_free( bc.bv_val );
-	}
-
-	if ( ri->ri_nsuffix ) {
-		for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
-			ptr = lutil_strcopy( ptr, " suffix=\"" );
-			ptr = lutil_strcopy( ptr, ri->ri_nsuffix[i].bv_val );
-			*ptr++ = '"';
-		}
-	}
-	if ( ri->ri_attrs ) {
-		ptr = lutil_strcopy( ptr, " attrs" );
-		if ( ri->ri_exclude ) *ptr++ = '!';
-		*ptr++ = '=';
-		ptr = anlist_unparse( ri->ri_attrs, ptr );
-	}
-}
-
 static int
-config_replica(ConfigArgs *c) {
-	int i, nr = -1;
-	char *replicahost = NULL, *replicauri = NULL;
-	LDAPURLDesc *ludp;
-
-	if (c->op == SLAP_CONFIG_EMIT) {
-		if (c->be->be_replica) {
-			struct berval bv;
-			for (i=0;c->be->be_replica[i]; i++) {
-				replica_unparse( c->be->be_replica[i], i, &bv );
-				ber_bvarray_add( &c->rvalue_vals, &bv );
-			}
-			return 0;
-		}
-		return 1;
-	} else if ( c->op == LDAP_MOD_DELETE ) {
-		/* FIXME: there is no replica_free function */
-		if ( c->valx < 0 ) {
-		} else {
-		}
-	}
-	if(SLAP_MONITOR(c->be)) {
-		Debug(LDAP_DEBUG_ANY, "%s: "
-			"\"replica\" should not be used inside monitor database\n",
-			c->log, 0, 0);
-		return(0);	/* FIXME: should this be an error? */
-	}
-
-	for(i = 1; i < c->argc; i++) {
-		if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
-			ber_len_t	len;
-
-			if ( replicauri ) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] );
-				Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
-				return(1);
-			}
-
-			replicahost = c->argv[i] + STRLENOF("host=");
-			len = strlen( replicahost ) + STRLENOF("ldap://");
-			replicauri = ch_malloc( len + 1 );
-			snprintf( replicauri, len + 1, "ldap://%s", replicahost );
-			replicahost = replicauri + STRLENOF( "ldap://");
-			nr = add_replica_info(c->be, replicauri, replicahost);
-			break;
-		} else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
-			ber_len_t	len;
-
-			if ( replicauri ) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] );
-				Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
-				return(1);
-			}
-
-			if(ldap_url_parse(c->argv[i] + STRLENOF("uri="), &ludp) != LDAP_SUCCESS) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri", c->argv[0] );
-				Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
-				return(1);
-			}
-			if(!ludp->lud_host) {
-				ldap_free_urldesc(ludp);
-				snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri - missing hostname",
-					c->argv[0] );
-				Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
-				return(1);
-			}
-
-			len = strlen(ludp->lud_scheme) + strlen(ludp->lud_host) +
-				STRLENOF("://") + 1;
-			if (ludp->lud_port != LDAP_PORT) {
-				if (ludp->lud_port < 1 || ludp->lud_port > 65535) {
-					ldap_free_urldesc(ludp);
-					snprintf( c->msg, sizeof( c->msg ), "<%s> invalid port",
-						c->argv[0] );
-					Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
-					return(1);
-				}
-				len += STRLENOF(":65535");
-			}
-			replicauri = ch_malloc( len );
-			replicahost = lutil_strcopy( replicauri, ludp->lud_scheme );
-			replicahost = lutil_strcopy( replicahost, "://" );
-			if (ludp->lud_port == LDAP_PORT) {
-				strcpy( replicahost, ludp->lud_host );
-			} else {
-				sprintf( replicahost, "%s:%d",ludp->lud_host,ludp->lud_port );
-			}
-			ldap_free_urldesc(ludp);
-			nr = add_replica_info(c->be, replicauri, replicahost);
-			break;
-		}
-	}
-	if(i == c->argc) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> missing host or uri", c->argv[0] );
-		Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
-		return(1);
-	} else if(nr == -1) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> unable to add replica", c->argv[0] );
-		Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg,
-			replicauri ? replicauri : "" );
-		return(1);
-	} else {
-		for(i = 1; i < c->argc; i++) {
-			if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
-				/* dealt with separately; don't let it get to bindconf */
-				;
-
-			} else if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
-				/* dealt with separately; don't let it get to bindconf */
-				;
-
-
-			} else if(!strncasecmp(c->argv[i], "suffix=", STRLENOF( "suffix="))) {
-				switch(add_replica_suffix(c->be, nr, c->argv[i] + STRLENOF("suffix="))) {
-					case 1:
-						Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
-						"suffix \"%s\" in \"replica\" line is not valid for backend"
-						SLAPD_CONF_UNKNOWN_IGNORED ".\n",
-						c->log, c->argv[i] + STRLENOF("suffix="), 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-						return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
-						break;
-					case 2:
-						Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
-						"unable to normalize suffix in \"replica\" line"
-						SLAPD_CONF_UNKNOWN_IGNORED ".\n",
-						c->log, 0, 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-						return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
-						break;
-				}
-
-			} else if (!strncasecmp(c->argv[i], "attr", STRLENOF("attr"))
-				|| !strncasecmp(c->argv[i], "attrs", STRLENOF("attrs")))
-			{
-				int exclude = 0;
-				char *arg = c->argv[i] + STRLENOF("attr");
-				if (arg[0] == 's') {
-					arg++;
-				} else {
-					Debug( LDAP_DEBUG_ANY,
-						"%s: \"attr\" "
-						"is deprecated (and undocumented); "
-						"use \"attrs\" instead.\n",
-						c->log, 0, 0 );
-				}
-				if(arg[0] == '!') {
-					arg++;
-					exclude = 1;
-				}
-				if(arg[0] != '=') {
-					continue;
-				}
-				if(add_replica_attrs(c->be, nr, arg + 1, exclude)) {
-					snprintf( c->msg, sizeof( c->msg ), "<%s> unknown attribute", c->argv[0] );
-					Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
-						c->log, c->msg, arg + 1);
-					return(1);
-				}
-			} else if ( bindconf_parse( c->argv[i],
-					&c->be->be_replica[nr]->ri_bindconf ) ) {
-				return(1);
-			}
-		}
-	}
-	return(0);
-}
-
-static int
 config_updatedn(ConfigArgs *c) {
 	if (c->op == SLAP_CONFIG_EMIT) {
 		if (!BER_BVISEMPTY(&c->be->be_update_ndn)) {
@@ -2615,9 +2913,9 @@
 		return 0;
 	}
 	if(SLAP_SHADOW(c->be)) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> database already shadowed", c->argv[0] );
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> database already shadowed", c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s\n",
-			c->log, c->msg, 0);
+			c->log, c->cr_msg, 0);
 		return(1);
 	}
 
@@ -2642,9 +2940,6 @@
 
 	} else if ( SLAP_MONITOR(c->be) ) {
 		notallowed = "monitor";
-
-	} else if ( SLAP_CONFIG(c->be) ) {
-		notallowed = "config";
 	}
 
 	if ( notallowed != NULL ) {
@@ -2652,7 +2947,7 @@
 		return 1;
 	}
 
-	SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | flag);
+	SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SINGLE_SHADOW | flag);
 
 	return 0;
 }
@@ -2679,18 +2974,18 @@
 		}
 		return 0;
 	}
-	if(!SLAP_SHADOW(c->be)) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> must appear after syncrepl or updatedn",
+	if(!SLAP_SHADOW(c->be) && !c->be->be_syncinfo) {
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> must appear after syncrepl or updatedn",
 			c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s\n",
-			c->log, c->msg, 0);
+			c->log, c->cr_msg, 0);
 		return(1);
 	}
 
 	if(validate_global_referral(c->argv[1])) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> invalid URL", c->argv[0] );
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid URL", c->argv[0] );
 		Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
-			c->log, c->msg, c->argv[1]);
+			c->log, c->cr_msg, c->argv[1]);
 		return(1);
 	}
 	ber_str2bv(c->argv[1], 0, 0, &val);
@@ -2699,21 +2994,28 @@
 }
 
 static int
+config_obsolete(ConfigArgs *c) {
+	if (c->op == SLAP_CONFIG_EMIT)
+		return 1;
+
+	snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> keyword is obsolete (ignored)",
+		c->argv[0] );
+	Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->cr_msg, 0);
+	return(0);
+}
+
+static int
 config_include(ConfigArgs *c) {
 	int savelineno = c->lineno;
 	int rc;
 	ConfigFile *cf;
 	ConfigFile *cfsave = cfn;
 	ConfigFile *cf2 = NULL;
-	if (c->op == SLAP_CONFIG_EMIT) {
-		if (c->private) {
-			ConfigFile *cf = c->private;
-			value_add_one( &c->rvalue_vals, &cf->c_file );
-			return 0;
-		}
+
+	/* Leftover from RE23. No dynamic config for include files */
+	if ( c->op == SLAP_CONFIG_EMIT || c->op == LDAP_MOD_DELETE )
 		return 1;
-	} else if ( c->op == LDAP_MOD_DELETE ) {
-	}
+
 	cf = ch_calloc( 1, sizeof(ConfigFile));
 	if ( cfn->c_kids ) {
 		for (cf2=cfn->c_kids; cf2 && cf2->c_sibs; cf2=cf2->c_sibs) ;
@@ -2741,48 +3043,39 @@
 static int
 config_tls_option(ConfigArgs *c) {
 	int flag;
+	LDAP *ld = slap_tls_ld;
 	switch(c->type) {
-	case CFG_TLS_RAND:	flag = LDAP_OPT_X_TLS_RANDOM_FILE;	break;
+	case CFG_TLS_RAND:	flag = LDAP_OPT_X_TLS_RANDOM_FILE;	ld = NULL; break;
 	case CFG_TLS_CIPHER:	flag = LDAP_OPT_X_TLS_CIPHER_SUITE;	break;
 	case CFG_TLS_CERT_FILE:	flag = LDAP_OPT_X_TLS_CERTFILE;		break;	
 	case CFG_TLS_CERT_KEY:	flag = LDAP_OPT_X_TLS_KEYFILE;		break;
 	case CFG_TLS_CA_PATH:	flag = LDAP_OPT_X_TLS_CACERTDIR;	break;
 	case CFG_TLS_CA_FILE:	flag = LDAP_OPT_X_TLS_CACERTFILE;	break;
 	case CFG_TLS_DH_FILE:	flag = LDAP_OPT_X_TLS_DHFILE;	break;
+#ifdef HAVE_GNUTLS
+	case CFG_TLS_CRL_FILE:	flag = LDAP_OPT_X_TLS_CRLFILE;	break;
+#endif
 	default:		Debug(LDAP_DEBUG_ANY, "%s: "
 					"unknown tls_option <0x%x>\n",
 					c->log, c->type, 0);
 		return 1;
 	}
 	if (c->op == SLAP_CONFIG_EMIT) {
-		return ldap_pvt_tls_get_option( NULL, flag, &c->value_string );
+		return ldap_pvt_tls_get_option( ld, flag, &c->value_string );
 	} else if ( c->op == LDAP_MOD_DELETE ) {
-		return ldap_pvt_tls_set_option( NULL, flag, NULL );
+		return ldap_pvt_tls_set_option( ld, flag, NULL );
 	}
 	ch_free(c->value_string);
-	return(ldap_pvt_tls_set_option(NULL, flag, c->argv[1]));
+	return(ldap_pvt_tls_set_option(ld, flag, c->argv[1]));
 }
 
 /* FIXME: this ought to be provided by libldap */
 static int
 config_tls_config(ConfigArgs *c) {
 	int i, flag;
-	slap_verbmasks crlkeys[] = {
-		{ BER_BVC("none"),	LDAP_OPT_X_TLS_CRL_NONE },
-		{ BER_BVC("peer"),	LDAP_OPT_X_TLS_CRL_PEER },
-		{ BER_BVC("all"),	LDAP_OPT_X_TLS_CRL_ALL },
-		{ BER_BVNULL, 0 }
-	};
-	slap_verbmasks vfykeys[] = {
-		{ BER_BVC("never"),	LDAP_OPT_X_TLS_NEVER },
-		{ BER_BVC("demand"),	LDAP_OPT_X_TLS_DEMAND },
-		{ BER_BVC("try"),	LDAP_OPT_X_TLS_TRY },
-		{ BER_BVC("hard"),	LDAP_OPT_X_TLS_HARD },
-		{ BER_BVNULL, 0 }
-	}, *keys;
 	switch(c->type) {
-	case CFG_TLS_CRLCHECK:	flag = LDAP_OPT_X_TLS_CRLCHECK;		keys = crlkeys;	break;
-	case CFG_TLS_VERIFY:	flag = LDAP_OPT_X_TLS_REQUIRE_CERT;	keys = vfykeys;	break;
+	case CFG_TLS_CRLCHECK:	flag = LDAP_OPT_X_TLS_CRLCHECK; break;
+	case CFG_TLS_VERIFY:	flag = LDAP_OPT_X_TLS_REQUIRE_CERT; break;
 	default:
 		Debug(LDAP_DEBUG_ANY, "%s: "
 				"unknown tls_option <0x%x>\n",
@@ -2790,17 +3083,10 @@
 		return 1;
 	}
 	if (c->op == SLAP_CONFIG_EMIT) {
-		ldap_pvt_tls_get_option( NULL, flag, &c->value_int );
-		for (i=0; !BER_BVISNULL(&keys[i].word); i++) {
-			if (keys[i].mask == c->value_int) {
-				c->value_string = ch_strdup( keys[i].word.bv_val );
-				return 0;
-			}
-		}
-		return 1;
+		return slap_tls_get_config( slap_tls_ld, flag, &c->value_string );
 	} else if ( c->op == LDAP_MOD_DELETE ) {
 		int i = 0;
-		return ldap_pvt_tls_set_option( NULL, flag, &i );
+		return ldap_pvt_tls_set_option( slap_tls_ld, flag, &i );
 	}
 	ch_free( c->value_string );
 	if ( isdigit( (unsigned char)c->argv[1][0] ) ) {
@@ -2810,9 +3096,9 @@
 				c->log, c->argv[0], c->argv[1] );
 			return 1;
 		}
-		return(ldap_pvt_tls_set_option(NULL, flag, &i));
+		return(ldap_pvt_tls_set_option(slap_tls_ld, flag, &i));
 	} else {
-		return(ldap_int_tls_config(NULL, flag, c->argv[1]));
+		return(ldap_int_tls_config(slap_tls_ld, flag, c->argv[1]));
 	}
 }
 #endif
@@ -2859,6 +3145,10 @@
 typedef struct setup_cookie {
 	CfBackInfo *cfb;
 	ConfigArgs *ca;
+	Entry *frontend;
+	Entry *config;
+	int	got_frontend;
+	int got_config;
 } setup_cookie;
 
 static int
@@ -2868,10 +3158,64 @@
 		setup_cookie *sc = op->o_callback->sc_private;
 
 		sc->cfb->cb_got_ldif = 1;
-		rs->sr_err = config_add_internal( sc->cfb, rs->sr_entry, sc->ca, NULL, NULL );
+		/* Does the frontend exist? */
+		if ( !sc->got_frontend ) {
+			if ( !strncmp( rs->sr_entry->e_nname.bv_val,
+				"olcDatabase", STRLENOF( "olcDatabase" ))) {
+				if ( strncmp( rs->sr_entry->e_nname.bv_val +
+					STRLENOF( "olcDatabase" ), "={-1}frontend",
+					STRLENOF( "={-1}frontend" ))) {
+					struct berval rdn;
+					int i = op->o_noop;
+					sc->ca->be = frontendDB;
+					sc->ca->bi = frontendDB->bd_info;
+					frontendDB->be_cf_ocs = &CFOC_FRONTEND;
+					rdn.bv_val = sc->ca->log;
+					rdn.bv_len = snprintf(rdn.bv_val, sizeof( sc->ca->log ),
+						"%s=" SLAP_X_ORDERED_FMT "%s",
+						cfAd_database->ad_cname.bv_val, -1,
+						sc->ca->bi->bi_type);
+					op->o_noop = 1;
+					sc->frontend = config_build_entry( op, rs,
+						sc->cfb->cb_root, sc->ca, &rdn, &CFOC_DATABASE,
+						sc->ca->be->be_cf_ocs );
+					op->o_noop = i;
+					sc->got_frontend++;
+				} else {
+					sc->got_frontend++;
+					goto ok;
+				}
+			}
+		}
+		/* Does the configDB exist? */
+		if ( sc->got_frontend && !sc->got_config &&
+			!strncmp( rs->sr_entry->e_nname.bv_val,
+			"olcDatabase", STRLENOF( "olcDatabase" ))) {
+			if ( strncmp( rs->sr_entry->e_nname.bv_val +
+				STRLENOF( "olcDatabase" ), "={0}config",
+				STRLENOF( "={0}config" ))) {
+				struct berval rdn;
+				int i = op->o_noop;
+				sc->ca->be = LDAP_STAILQ_FIRST( &backendDB );
+				sc->ca->bi = sc->ca->be->bd_info;
+				rdn.bv_val = sc->ca->log;
+				rdn.bv_len = snprintf(rdn.bv_val, sizeof( sc->ca->log ),
+					"%s=" SLAP_X_ORDERED_FMT "%s",
+					cfAd_database->ad_cname.bv_val, 0,
+					sc->ca->bi->bi_type);
+				op->o_noop = 1;
+				sc->config = config_build_entry( op, rs, sc->cfb->cb_root,
+					sc->ca, &rdn, &CFOC_DATABASE, sc->ca->be->be_cf_ocs );
+				op->o_noop = i;
+			}
+			sc->got_config++;
+		}
+
+ok:
+		rs->sr_err = config_add_internal( sc->cfb, rs->sr_entry, sc->ca, NULL, NULL, NULL );
 		if ( rs->sr_err != LDAP_SUCCESS ) {
 			Debug( LDAP_DEBUG_ANY, "config error processing %s: %s\n",
-				rs->sr_entry->e_name.bv_val, sc->ca->msg, 0 );
+				rs->sr_entry->e_name.bv_val, sc->ca->cr_msg, 0 );
 		}
 	}
 	return rs->sr_err;
@@ -2907,7 +3251,7 @@
 	if ( !cfb->cb_db.bd_info )
 		return 0;	/* FIXME: eventually this will be a fatal error */
 
-	if ( backend_db_init( "ldif", &cfb->cb_db ) == NULL )
+	if ( backend_db_init( "ldif", &cfb->cb_db, -1, NULL ) == NULL )
 		return 1;
 
 	cfb->cb_db.be_suffix = be->be_suffix;
@@ -2928,6 +3272,8 @@
 	argv[1] = (char *)dir;
 	argv[2] = NULL;
 	c.argv = argv;
+	c.reply.err = 0;
+	c.reply.msg[0] = 0;
 	c.table = Cft_Database;
 
 	ct = config_find_keyword( c.be->be_cf_ocs->co_table, &c );
@@ -2937,14 +3283,15 @@
 	if ( config_add_vals( ct, &c ))
 		return 1;
 
-	if ( backend_startup_one( &cfb->cb_db ))
+	if ( backend_startup_one( &cfb->cb_db, &c.reply ))
 		return 1;
 
 	if ( readit ) {
 		void *thrctx = ldap_pvt_thread_pool_context();
+		int prev_DN_strict;
 
-		op = (Operation *) &opbuf;
-		connection_fake_init( &conn, op, thrctx );
+		connection_fake_init( &conn, &opbuf, thrctx );
+		op = &opbuf.ob_op;
 
 		filter.f_desc = slap_schema.si_ad_objectClass;
 
@@ -2970,10 +3317,31 @@
 		sc.cfb = cfb;
 		sc.ca = &c;
 		cb.sc_private = &sc;
+		sc.got_frontend = 0;
+		sc.got_config = 0;
+		sc.frontend = NULL;
+		sc.config = NULL;
 
 		op->o_bd = &cfb->cb_db;
+		
+		/* Allow unknown attrs in DNs */
+		prev_DN_strict = slap_DN_strict;
+		slap_DN_strict = 0;
+
 		rc = op->o_bd->be_search( op, &rs );
 
+		/* Restore normal DN validation */
+		slap_DN_strict = prev_DN_strict;
+
+		op->o_tag = LDAP_REQ_ADD;
+		if ( rc == LDAP_SUCCESS && sc.frontend ) {
+			op->ora_e = sc.frontend;
+			rc = op->o_bd->be_add( op, &rs );
+		}
+		if ( rc == LDAP_SUCCESS && sc.config ) {
+			op->ora_e = sc.config;
+			rc = op->o_bd->be_add( op, &rs );
+		}
 		ldap_pvt_thread_pool_context_reset( thrctx );
 	}
 
@@ -3022,11 +3390,12 @@
 	int rc;
 
 	/* Setup the config backend */
-	be = backend_db_init( "config", NULL );
+	be = backend_db_init( "config", NULL, 0, NULL );
 	if ( !be )
 		return 1;
 
 	cfb = be->be_private;
+	be->be_dfltaccess = ACL_NONE;
 
 	/* If no .conf, or a dir was specified, setup the dir */
 	if ( !fname || dir ) {
@@ -3102,7 +3471,7 @@
 static int
 config_back_bind( Operation *op, SlapReply *rs )
 {
-	if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
+	if ( be_isroot_pw( op ) ) {
 		ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
 		/* frontend sends result */
 		return LDAP_SUCCESS;
@@ -3222,7 +3591,7 @@
 	AttributeDescription *ad;
 	BerVarray vals;
 
-	int i, rc = 0, sort = 0;
+	int i, rc = 0;
 
 	if ( isAttr ) {
 		a = ptr;
@@ -3235,17 +3604,17 @@
 	}
 
 	if ( a && ( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL )) {
-		sort = 1;
 		rc = ordered_value_sort( a, 1 );
 		if ( rc ) {
-			snprintf(ca->msg, sizeof( ca->msg ), "ordered_value_sort failed on attr %s\n",
+			snprintf(ca->cr_msg, sizeof( ca->cr_msg ), "ordered_value_sort failed on attr %s\n",
 				ad->ad_cname.bv_val );
 			return rc;
 		}
 	}
 	for ( i=0; vals[i].bv_val; i++ ) {
 		ca->line = vals[i].bv_val;
-		if ( sort ) {
+		if (( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) &&
+			ca->line[0] == '{' ) {
 			char *idx = strchr( ca->line, '}' );
 			if ( idx ) ca->line = idx+1;
 		}
@@ -3258,12 +3627,180 @@
 }
 
 static int
+config_rename_attr( SlapReply *rs, Entry *e, struct berval *rdn,
+	Attribute **at )
+{
+	struct berval rtype, rval;
+	Attribute *a;
+	AttributeDescription *ad = NULL;
+
+	dnRdn( &e->e_name, rdn );
+	rval.bv_val = strchr(rdn->bv_val, '=' ) + 1;
+	rval.bv_len = rdn->bv_len - (rval.bv_val - rdn->bv_val);
+	rtype.bv_val = rdn->bv_val;
+	rtype.bv_len = rval.bv_val - rtype.bv_val - 1;
+
+	/* Find attr */
+	slap_bv2ad( &rtype, &ad, &rs->sr_text );
+	a = attr_find( e->e_attrs, ad );
+	if (!a ) return LDAP_NAMING_VIOLATION;
+	*at = a;
+
+	return 0;
+}
+
+static void
+config_rename_kids( CfEntryInfo *ce )
+{
+	CfEntryInfo *ce2;
+	struct berval rdn, nrdn;
+
+	for (ce2 = ce->ce_kids; ce2; ce2 = ce2->ce_sibs) {
+		dnRdn ( &ce2->ce_entry->e_name, &rdn );
+		dnRdn ( &ce2->ce_entry->e_nname, &nrdn );
+		free( ce2->ce_entry->e_name.bv_val );
+		free( ce2->ce_entry->e_nname.bv_val );
+		build_new_dn( &ce2->ce_entry->e_name, &ce->ce_entry->e_name,
+			&rdn, NULL );
+		build_new_dn( &ce2->ce_entry->e_nname, &ce->ce_entry->e_nname,
+			&nrdn, NULL );
+		config_rename_kids( ce2 );
+	}
+}
+
+static int
+config_rename_one( Operation *op, SlapReply *rs, Entry *e,
+	CfEntryInfo *parent, Attribute *a, struct berval *newrdn,
+	struct berval *nnewrdn, int use_ldif )
+{
+	char *ptr1;
+	int rc = 0;
+	struct berval odn, ondn;
+
+	odn = e->e_name;
+	ondn = e->e_nname;
+	build_new_dn( &e->e_name, &parent->ce_entry->e_name, newrdn, NULL );
+	build_new_dn( &e->e_nname, &parent->ce_entry->e_nname, nnewrdn, NULL );
+
+	/* Replace attr */
+	free( a->a_vals[0].bv_val );
+	ptr1 = strchr( newrdn->bv_val, '=' ) + 1;
+	a->a_vals[0].bv_len = newrdn->bv_len - (ptr1 - newrdn->bv_val);
+	a->a_vals[0].bv_val = ch_malloc( a->a_vals[0].bv_len + 1 );
+	strcpy( a->a_vals[0].bv_val, ptr1 );
+
+	if ( a->a_nvals != a->a_vals ) {
+		free( a->a_nvals[0].bv_val );
+		ptr1 = strchr( nnewrdn->bv_val, '=' ) + 1;
+		a->a_nvals[0].bv_len = nnewrdn->bv_len - (ptr1 - nnewrdn->bv_val);
+		a->a_nvals[0].bv_val = ch_malloc( a->a_nvals[0].bv_len + 1 );
+		strcpy( a->a_nvals[0].bv_val, ptr1 );
+	}
+	if ( use_ldif ) {
+		CfBackInfo *cfb = (CfBackInfo *)op->o_bd->be_private;
+		BackendDB *be = op->o_bd;
+		slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
+		struct berval dn, ndn, xdn, xndn;
+
+		op->o_bd = &cfb->cb_db;
+
+		/* Save current rootdn; use the underlying DB's rootdn */
+		dn = op->o_dn;
+		ndn = op->o_ndn;
+		xdn = op->o_req_dn;
+		xndn = op->o_req_ndn;
+		op->o_dn = op->o_bd->be_rootdn;
+		op->o_ndn = op->o_bd->be_rootndn;
+		op->o_req_dn = odn;
+		op->o_req_ndn = ondn;
+
+		scp = op->o_callback;
+		op->o_callback = &sc;
+		op->orr_newrdn = *newrdn;
+		op->orr_nnewrdn = *nnewrdn;
+		op->orr_newSup = NULL;
+		op->orr_nnewSup = NULL;
+		op->orr_deleteoldrdn = 1;
+		op->orr_modlist = NULL;
+		slap_modrdn2mods( op, rs );
+		slap_mods_opattrs( op, &op->orr_modlist, 1 );
+		rc = op->o_bd->be_modrdn( op, rs );
+		slap_mods_free( op->orr_modlist, 1 );
+
+		op->o_bd = be;
+		op->o_callback = scp;
+		op->o_dn = dn;
+		op->o_ndn = ndn;
+		op->o_req_dn = xdn;
+		op->o_req_ndn = xndn;
+	}
+	free( odn.bv_val );
+	free( ondn.bv_val );
+	if ( e->e_private )
+		config_rename_kids( e->e_private );
+	return rc;
+}
+
+static int
+config_renumber_one( Operation *op, SlapReply *rs, CfEntryInfo *parent, 
+	Entry *e, int idx, int tailindex, int use_ldif )
+{
+	struct berval ival, newrdn, nnewrdn;
+	struct berval rdn;
+	Attribute *a;
+	char ibuf[32], *ptr1, *ptr2 = NULL;
+	int rc = 0;
+
+	rc = config_rename_attr( rs, e, &rdn, &a );
+	if ( rc ) return rc;
+
+	ival.bv_val = ibuf;
+	ival.bv_len = snprintf( ibuf, sizeof( ibuf ), SLAP_X_ORDERED_FMT, idx );
+	if ( ival.bv_len >= sizeof( ibuf ) ) {
+		return LDAP_NAMING_VIOLATION;
+	}
+	
+	newrdn.bv_len = rdn.bv_len + ival.bv_len;
+	newrdn.bv_val = ch_malloc( newrdn.bv_len+1 );
+
+	if ( tailindex ) {
+		ptr1 = lutil_strncopy( newrdn.bv_val, rdn.bv_val, rdn.bv_len );
+		ptr1 = lutil_strcopy( ptr1, ival.bv_val );
+	} else {
+		int xlen;
+		ptr2 = ber_bvchr( &rdn, '}' );
+		if ( ptr2 ) {
+			ptr2++;
+		} else {
+			ptr2 = rdn.bv_val + a->a_desc->ad_cname.bv_len + 1;
+		}
+		xlen = rdn.bv_len - (ptr2 - rdn.bv_val);
+		ptr1 = lutil_strncopy( newrdn.bv_val, a->a_desc->ad_cname.bv_val,
+			a->a_desc->ad_cname.bv_len );
+		*ptr1++ = '=';
+		ptr1 = lutil_strcopy( ptr1, ival.bv_val );
+		ptr1 = lutil_strncopy( ptr1, ptr2, xlen );
+		*ptr1 = '\0';
+	}
+
+	/* Do the equivalent of ModRDN */
+	/* Replace DN / NDN */
+	newrdn.bv_len = ptr1 - newrdn.bv_val;
+	rdnNormalize( 0, NULL, NULL, &newrdn, &nnewrdn, NULL );
+	rc = config_rename_one( op, rs, e, parent, a, &newrdn, &nnewrdn, use_ldif );
+
+	free( nnewrdn.bv_val );
+	free( newrdn.bv_val );
+	return rc;
+}
+
+static int
 check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e,
-	SlapReply *rs, int *renum )
+	SlapReply *rs, int *renum, int *ibase )
 {
 	CfEntryInfo *ce;
-	int index = -1, gotindex = 0, nsibs;
-	int renumber = 0, tailindex = 0;
+	int index = -1, gotindex = 0, nsibs, rc = 0;
+	int renumber = 0, tailindex = 0, isfrontend = 0, isconfig = 0;
 	char *ptr1, *ptr2 = NULL;
 	struct berval rdn;
 
@@ -3273,11 +3810,19 @@
 	if ( ce_type == Cft_Global ) return 0;
 	if ( ce_type == Cft_Schema && parent->ce_type == Cft_Global ) return 0;
 
-	if ( ce_type == Cft_Include || ce_type == Cft_Module )
+	if ( ce_type == Cft_Module )
 		tailindex = 1;
 
 	/* See if the rdn has an index already */
 	dnRdn( &e->e_name, &rdn );
+	if ( ce_type == Cft_Database ) {
+		if ( !strncmp( rdn.bv_val + rdn.bv_len - STRLENOF("frontend"),
+				"frontend", STRLENOF("frontend") )) 
+			isfrontend = 1;
+		else if ( !strncmp( rdn.bv_val + rdn.bv_len - STRLENOF("config"),
+				"config", STRLENOF("config") )) 
+			isconfig = 1;
+	}
 	ptr1 = ber_bvchr( &e->e_name, '{' );
 	if ( ptr1 && ptr1 - e->e_name.bv_val < rdn.bv_len ) {
 		char	*next;
@@ -3293,11 +3838,12 @@
 		}
 		if ( index < 0 ) {
 			/* Special case, we allow -1 for the frontendDB */
-			if ( index != -1 || ce_type != Cft_Database ||
-				strncmp( ptr2+1, "frontend,", STRLENOF("frontend,") ))
-
+			if ( index != -1 || !isfrontend )
 				return LDAP_NAMING_VIOLATION;
 		}
+		if ( isconfig && index != 0 ){
+			return LDAP_NAMING_VIOLATION;
+		}
 	}
 
 	/* count related kids */
@@ -3305,135 +3851,104 @@
 		if ( ce->ce_type == ce_type ) nsibs++;
 	}
 
+	/* account for -1 frontend */
+	if ( ce_type == Cft_Database )
+		nsibs--;
+
 	if ( index != nsibs ) {
 		if ( gotindex ) {
 			if ( index < nsibs ) {
 				if ( tailindex ) return LDAP_NAMING_VIOLATION;
 				/* Siblings need to be renumbered */
-				renumber = 1;
+				if ( index != -1 || !isfrontend )
+					renumber = 1;
 			}
 		}
+		/* config DB is always "0" */
+		if ( isconfig && index == -1 ) {
+			index = 0;
+		}
+		if ( !isfrontend && index == -1 ) {
+			index = nsibs;
+		}
+
+		/* just make index = nsibs */
 		if ( !renumber ) {
-			struct berval ival, newrdn, nnewrdn;
-			struct berval rtype, rval;
-			Attribute *a;
-			AttributeDescription *ad = NULL;
-			char ibuf[32];
-			const char *text;
+			rc = config_renumber_one( NULL, rs, parent, e, index, tailindex, 0 );
+		}
+	}
+	if ( ibase ) *ibase = index;
+	if ( renum ) *renum = renumber;
+	return rc;
+}
 
-			rval.bv_val = strchr(rdn.bv_val, '=' ) + 1;
-			rval.bv_len = rdn.bv_len - (rval.bv_val - rdn.bv_val);
-			rtype.bv_val = rdn.bv_val;
-			rtype.bv_len = rval.bv_val - rtype.bv_val - 1;
+static int
+count_oc( ObjectClass *oc, ConfigOCs ***copp, int *nocs )
+{
+	ConfigOCs	co, *cop;
+	ObjectClass	**sups;
 
-			/* Find attr */
-			slap_bv2ad( &rtype, &ad, &text );
-			a = attr_find( e->e_attrs, ad );
-			if (!a ) return LDAP_NAMING_VIOLATION;
+	co.co_name = &oc->soc_cname;
+	cop = avl_find( CfOcTree, &co, CfOc_cmp );
+	if ( cop ) {
+		int	i;
 
-			ival.bv_val = ibuf;
-			ival.bv_len = snprintf( ibuf, sizeof( ibuf ), SLAP_X_ORDERED_FMT, nsibs );
-			if ( ival.bv_len >= sizeof( ibuf ) ) {
-				return LDAP_NAMING_VIOLATION;
+		/* check for duplicates */
+		for ( i = 0; i < *nocs; i++ ) {
+			if ( *copp && (*copp)[i] == cop ) {
+				break;
 			}
-			
-			newrdn.bv_len = rdn.bv_len + ival.bv_len;
-			newrdn.bv_val = ch_malloc( newrdn.bv_len+1 );
+		}
 
-			if ( tailindex ) {
-				ptr1 = lutil_strncopy( newrdn.bv_val, rdn.bv_val, rdn.bv_len );
-				ptr1 = lutil_strcopy( ptr1, ival.bv_val );
-			} else {
-				int xlen;
-				if ( !gotindex ) {
-					ptr2 = rval.bv_val;
-					xlen = rval.bv_len;
-				} else {
-					xlen = rdn.bv_len - (ptr2 - rdn.bv_val);
-				}
-				ptr1 = lutil_strncopy( newrdn.bv_val, rtype.bv_val,
-					rtype.bv_len );
-				*ptr1++ = '=';
-				ptr1 = lutil_strcopy( ptr1, ival.bv_val );
-				ptr1 = lutil_strncopy( ptr1, ptr2, xlen );
-				*ptr1 = '\0';
+		if ( i == *nocs ) {
+			ConfigOCs **tmp = ch_realloc( *copp, (*nocs + 1)*sizeof( ConfigOCs * ) );
+			if ( tmp == NULL ) {
+				return -1;
 			}
+			*copp = tmp;
+			(*copp)[*nocs] = cop;
+			(*nocs)++;
+		}
+	}
 
-			/* Do the equivalent of ModRDN */
-			/* Replace DN / NDN */
-			newrdn.bv_len = ptr1 - newrdn.bv_val;
-			rdnNormalize( 0, NULL, NULL, &newrdn, &nnewrdn, NULL );
-			free( e->e_name.bv_val );
-			build_new_dn( &e->e_name, &parent->ce_entry->e_name,
-				&newrdn, NULL );
-			free( e->e_nname.bv_val );
-			build_new_dn( &e->e_nname, &parent->ce_entry->e_nname,
-				&nnewrdn, NULL );
-
-			/* Replace attr */
-			free( a->a_vals[0].bv_val );
-			ptr1 = strchr( newrdn.bv_val, '=' ) + 1;
-			a->a_vals[0].bv_len = newrdn.bv_len - (ptr1 - newrdn.bv_val);
-			a->a_vals[0].bv_val = ch_malloc( a->a_vals[0].bv_len + 1 );
-			strcpy( a->a_vals[0].bv_val, ptr1 );
-
-			if ( a->a_nvals != a->a_vals ) {
-				free( a->a_nvals[0].bv_val );
-				ptr1 = strchr( nnewrdn.bv_val, '=' ) + 1;
-				a->a_nvals[0].bv_len = nnewrdn.bv_len - (ptr1 - nnewrdn.bv_val);
-				a->a_nvals[0].bv_val = ch_malloc( a->a_nvals[0].bv_len + 1 );
-				strcpy( a->a_nvals[0].bv_val, ptr1 );
-			}
-			free( nnewrdn.bv_val );
-			free( newrdn.bv_val );
+	for ( sups = oc->soc_sups; sups && *sups; sups++ ) {
+		if ( count_oc( *sups, copp, nocs ) ) {
+			return -1;
 		}
 	}
-	if ( renum ) *renum = renumber;
+
 	return 0;
 }
 
 static ConfigOCs **
 count_ocs( Attribute *oc_at, int *nocs )
 {
-	int i, j, n;
-	ConfigOCs co, *coptr, **colst;
+	int		i;
+	ConfigOCs	**colst = NULL;
 
-	/* count the objectclasses */
-	for ( i=0; oc_at->a_nvals[i].bv_val; i++ );
-	n = i;
-	colst = (ConfigOCs **)ch_malloc( n * sizeof(ConfigOCs *));
+	*nocs = 0;
 
-	for ( i=0, j=0; i<n; i++) {
-		co.co_name = &oc_at->a_nvals[i];
-		coptr = avl_find( CfOcTree, &co, CfOc_cmp );
-		
-		/* ignore non-config objectclasses. probably should be
-		 * an error, general data doesn't belong here.
-		 */
-		if ( !coptr ) continue;
+	for ( i = 0; !BER_BVISNULL( &oc_at->a_nvals[i] ); i++ )
+		/* count attrs */ ;
 
-		/* Ignore the root objectclass, it has no implementation.
-		 */
-		if ( coptr->co_type == Cft_Abstract ) continue;
-		colst[j++] = coptr;
+	for ( ; i--; ) {
+		ObjectClass	*oc = oc_bvfind( &oc_at->a_nvals[i] );
+
+		assert( oc != NULL );
+		if ( count_oc( oc, &colst, nocs ) ) {
+			ch_free( colst );
+			return NULL;
+		}
 	}
-	*nocs = j;
+
 	return colst;
 }
 
 static int
 cfAddInclude( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
 {
-	if ( p->ce_type != Cft_Global && p->ce_type != Cft_Include )
-		return LDAP_CONSTRAINT_VIOLATION;
-
-	/* If we're reading from a configdir, don't parse this entry */
-	if ( ca->lineno )
-		return LDAP_COMPARE_TRUE;
-
-	cfn = p->ce_private;
-	ca->private = cfn;
-	return LDAP_SUCCESS;
+	/* Leftover from RE23. Never parse this entry */
+	return LDAP_COMPARE_TRUE;
 }
 
 static int
@@ -3461,8 +3976,9 @@
 static int
 cfAddDatabase( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
 {
-	if ( p->ce_type != Cft_Global )
+	if ( p->ce_type != Cft_Global ) {
 		return LDAP_CONSTRAINT_VIOLATION;
+	}
 	ca->be = frontendDB;	/* just to get past check_vals */
 	return LDAP_SUCCESS;
 }
@@ -3470,61 +3986,211 @@
 static int
 cfAddBackend( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
 {
-	if ( p->ce_type != Cft_Global )
+	if ( p->ce_type != Cft_Global ) {
 		return LDAP_CONSTRAINT_VIOLATION;
+	}
 	return LDAP_SUCCESS;
 }
 
 static int
 cfAddModule( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
 {
-	if ( p->ce_type != Cft_Global )
+	if ( p->ce_type != Cft_Global ) {
 		return LDAP_CONSTRAINT_VIOLATION;
+	}
 	return LDAP_SUCCESS;
 }
 
 static int
 cfAddOverlay( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
 {
-	if ( p->ce_type != Cft_Database )
+	if ( p->ce_type != Cft_Database ) {
 		return LDAP_CONSTRAINT_VIOLATION;
+	}
 	ca->be = p->ce_be;
 	return LDAP_SUCCESS;
 }
 
+static void
+schema_destroy_one( ConfigArgs *ca, ConfigOCs **colst, int nocs,
+	CfEntryInfo *p )
+{
+	ConfigTable *ct;
+	ConfigFile *cfo;
+	AttributeDescription *ad;
+	const char *text;
+
+	ca->valx = -1;
+	ca->line = NULL;
+	if ( cfn->c_cr_head ) {
+		struct berval bv = BER_BVC("olcDitContentRules");
+		ad = NULL;
+		slap_bv2ad( &bv, &ad, &text );
+		ct = config_find_table( colst, nocs, ad, ca );
+		config_del_vals( ct, ca );
+	}
+	if ( cfn->c_oc_head ) {
+		struct berval bv = BER_BVC("olcObjectClasses");
+		ad = NULL;
+		slap_bv2ad( &bv, &ad, &text );
+		ct = config_find_table( colst, nocs, ad, ca );
+		config_del_vals( ct, ca );
+	}
+	if ( cfn->c_at_head ) {
+		struct berval bv = BER_BVC("olcAttributeTypes");
+		ad = NULL;
+		slap_bv2ad( &bv, &ad, &text );
+		ct = config_find_table( colst, nocs, ad, ca );
+		config_del_vals( ct, ca );
+	}
+	if ( cfn->c_om_head ) {
+		struct berval bv = BER_BVC("olcObjectIdentifier");
+		ad = NULL;
+		slap_bv2ad( &bv, &ad, &text );
+		ct = config_find_table( colst, nocs, ad, ca );
+		config_del_vals( ct, ca );
+	}
+	cfo = p->ce_private;
+	cfo->c_kids = cfn->c_sibs;
+	ch_free( cfn );
+}
+
+static int
+config_add_oc( ConfigOCs **cop, CfEntryInfo *last, Entry *e, ConfigArgs *ca )
+{
+	int		rc = LDAP_CONSTRAINT_VIOLATION;
+	ObjectClass	**ocp;
+
+	if ( (*cop)->co_ldadd ) {
+		rc = (*cop)->co_ldadd( last, e, ca );
+		if ( rc != LDAP_CONSTRAINT_VIOLATION ) {
+			return rc;
+		}
+	}
+
+	for ( ocp = (*cop)->co_oc->soc_sups; ocp && *ocp; ocp++ ) {
+		ConfigOCs	co = { 0 };
+
+		co.co_name = &(*ocp)->soc_cname;
+		*cop = avl_find( CfOcTree, &co, CfOc_cmp );
+		if ( *cop == NULL ) {
+			return rc;
+		}
+
+		rc = config_add_oc( cop, last, e, ca );
+		if ( rc != LDAP_CONSTRAINT_VIOLATION ) {
+			return rc;
+		}
+	}
+
+	return rc;
+}
+
 /* Parse an LDAP entry into config directives */
 static int
-config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs, int *renum )
+config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
+	int *renum, Operation *op )
 {
-	CfEntryInfo *ce, *last;
-	ConfigOCs **colst;
-	Attribute *a, *oc_at;
-	int i, nocs, rc = 0;
-	struct berval pdn;
-	ConfigTable *ct;
-	char *ptr;
+	CfEntryInfo	*ce, *last = NULL;
+	ConfigOCs	co, *coptr, **colst;
+	Attribute	*a, *oc_at, *soc_at;
+	int		i, ibase = -1, nocs, rc = 0;
+	struct berval	pdn;
+	ConfigTable	*ct;
+	char		*ptr, *log_prefix = op ? op->o_log_prefix : "";
 
-	/* Make sure parent exists and entry does not */
+	memset( ca, 0, sizeof(ConfigArgs));
+
+	/* Make sure parent exists and entry does not. But allow
+	 * Databases and Overlays to be inserted. Don't do any
+	 * auto-renumbering if manageDSAit control is present.
+	 */
 	ce = config_find_base( cfb->cb_root, &e->e_nname, &last );
-	if ( ce )
-		return LDAP_ALREADY_EXISTS;
+	if ( ce ) {
+		if ( ( op && op->o_managedsait ) ||
+			( ce->ce_type != Cft_Database && ce->ce_type != Cft_Overlay &&
+			  ce->ce_type != Cft_Module ) )
+		{
+			Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+				"DN=\"%s\" already exists\n",
+				log_prefix, e->e_name.bv_val, 0 );
+			return LDAP_ALREADY_EXISTS;
+		}
+	}
 
 	dnParent( &e->e_nname, &pdn );
 
 	/* If last is NULL, the new entry is the root/suffix entry, 
 	 * otherwise last should be the parent.
 	 */
-	if ( last && !dn_match( &last->ce_entry->e_nname, &pdn )) {
-		if ( rs )
+	if ( last && !dn_match( &last->ce_entry->e_nname, &pdn ) ) {
+		if ( rs ) {
 			rs->sr_matched = last->ce_entry->e_name.bv_val;
+		}
+		Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+			"DN=\"%s\" not child of DN=\"%s\"\n",
+			log_prefix, e->e_name.bv_val,
+			last->ce_entry->e_name.bv_val );
 		return LDAP_NO_SUCH_OBJECT;
 	}
 
+	if ( op ) {
+		/* No parent, must be root. This will never happen... */
+		if ( !last && !be_isroot( op ) && !be_shadow_update( op ) ) {
+			return LDAP_NO_SUCH_OBJECT;
+		}
+
+		if ( last && !access_allowed( op, last->ce_entry,
+			slap_schema.si_ad_children, NULL, ACL_WADD, NULL ) )
+		{
+			Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+				"DN=\"%s\" no write access to \"children\" of parent\n",
+				log_prefix, e->e_name.bv_val, 0 );
+			return LDAP_INSUFFICIENT_ACCESS;
+		}
+	}
+
 	oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
-	if ( !oc_at ) return LDAP_OBJECT_CLASS_VIOLATION;
+	if ( !oc_at ) {
+		Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+			"DN=\"%s\" no objectClass\n",
+			log_prefix, e->e_name.bv_val, 0 );
+		return LDAP_OBJECT_CLASS_VIOLATION;
+	}
 
-	memset( ca, 0, sizeof(ConfigArgs));
+	soc_at = attr_find( e->e_attrs, slap_schema.si_ad_structuralObjectClass );
+	if ( !soc_at ) {
+		ObjectClass	*soc = NULL;
+		char		textbuf[ SLAP_TEXT_BUFLEN ];
+		const char	*text = textbuf;
 
+		/* FIXME: check result */
+		rc = structural_class( oc_at->a_nvals, &soc, NULL,
+			&text, textbuf, sizeof(textbuf), NULL );
+		if ( rc != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+				"DN=\"%s\" no structural objectClass (%s)\n",
+				log_prefix, e->e_name.bv_val, text );
+			return rc;
+		}
+		attr_merge_one( e, slap_schema.si_ad_structuralObjectClass, &soc->soc_cname, NULL );
+		soc_at = attr_find( e->e_attrs, slap_schema.si_ad_structuralObjectClass );
+		if ( soc_at == NULL ) {
+			Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+				"DN=\"%s\" no structural objectClass; "
+				"unable to merge computed class %s\n",
+				log_prefix, e->e_name.bv_val,
+				soc->soc_cname.bv_val );
+			return LDAP_OBJECT_CLASS_VIOLATION;
+		}
+
+		Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+			"DN=\"%s\" no structural objectClass; "
+			"computed objectClass %s merged\n",
+			log_prefix, e->e_name.bv_val,
+			soc->soc_cname.bv_val );
+	}
+
 	/* Fake the coordinates based on whether we're part of an
 	 * LDAP Add or if reading the config dir
 	 */
@@ -3535,31 +4201,54 @@
 		ca->fname = cfdir.bv_val;
 		ca->lineno = 1;
 	}
+	ca->ca_op = op;
 
-	colst = count_ocs( oc_at, &nocs );
+	co.co_name = &soc_at->a_nvals[0];
+	coptr = avl_find( CfOcTree, &co, CfOc_cmp );
+	if ( coptr == NULL ) {
+		Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+			"DN=\"%s\" no structural objectClass in configuration table\n",
+			log_prefix, e->e_name.bv_val, 0 );
+		return LDAP_OBJECT_CLASS_VIOLATION;
+	}
 
 	/* Only the root can be Cft_Global, everything else must
 	 * have a parent. Only limited nesting arrangements are allowed.
 	 */
 	rc = LDAP_CONSTRAINT_VIOLATION;
-	if ( colst[0]->co_type == Cft_Global && !last ) {
+	if ( coptr->co_type == Cft_Global && !last ) {
 		cfn = cfb->cb_config;
 		ca->private = cfn;
 		ca->be = frontendDB;	/* just to get past check_vals */
 		rc = LDAP_SUCCESS;
 	}
 
+	colst = count_ocs( oc_at, &nocs );
+
 	/* Check whether the Add is allowed by its parent, and do
 	 * any necessary arg setup
 	 */
 	if ( last ) {
-		for ( i=0; i<nocs; i++ ) {
-			if ( colst[i]->co_ldadd &&
-				( rc = colst[i]->co_ldadd( last, e, ca ))
-					!= LDAP_CONSTRAINT_VIOLATION ) {
-				break;
+		rc = config_add_oc( &coptr, last, e, ca );
+		if ( rc == LDAP_CONSTRAINT_VIOLATION ) {
+			for ( i = 0; i<nocs; i++ ) {
+				/* Already checked these */
+				if ( colst[i]->co_oc->soc_kind == LDAP_SCHEMA_STRUCTURAL )
+					continue;
+				if ( colst[i]->co_ldadd &&
+					( rc = colst[i]->co_ldadd( last, e, ca ))
+						!= LDAP_CONSTRAINT_VIOLATION ) {
+					coptr = colst[i];
+					break;
+				}
 			}
 		}
+		if ( rc == LDAP_CONSTRAINT_VIOLATION ) {
+			Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+				"DN=\"%s\" no structural objectClass add function\n",
+				log_prefix, e->e_name.bv_val, 0 );
+			return LDAP_OBJECT_CLASS_VIOLATION;
+		}
 	}
 
 	/* Add the entry but don't parse it, we already have its contents */
@@ -3569,7 +4258,7 @@
 	}
 
 	if ( rc != LDAP_SUCCESS )
-		goto done;
+		goto done_noop;
 
 	/* Parse all the values and check for simple syntax errors before
 	 * performing any set actions.
@@ -3587,21 +4276,33 @@
 	 * These entries can have auto-assigned indexes (appended to the end)
 	 * but only the other types support auto-renumbering of siblings.
 	 */
-	rc = check_name_index( last, colst[0]->co_type, e, rs, renum );
-	if ( rc )
-		goto done;
+	{
+		rc = check_name_index( last, coptr->co_type, e, rs, renum,
+			&ibase );
+		if ( rc ) {
+			goto done_noop;
+		}
+		if ( renum && *renum && coptr->co_type != Cft_Database &&
+			coptr->co_type != Cft_Overlay )
+		{
+			snprintf( ca->cr_msg, sizeof( ca->cr_msg ),
+				"operation requires sibling renumbering" );
+			rc = LDAP_UNWILLING_TO_PERFORM;
+			goto done_noop;
+		}
+	}
 
 	init_config_argv( ca );
 
 	/* Make sure we process attrs in the required order */
 	sort_attrs( e, colst, nocs );
 
-	for ( a=e->e_attrs; a; a=a->a_next ) {
+	for ( a = e->e_attrs; a; a = a->a_next ) {
 		if ( a == oc_at ) continue;
 		ct = config_find_table( colst, nocs, a->a_desc, ca );
 		if ( !ct ) continue;	/* user data? */
 		rc = check_vals( ct, ca, a, 1 );
-		if ( rc ) goto done;
+		if ( rc ) goto done_noop;
 	}
 
 	/* Basic syntax checks are OK. Do the actual settings. */
@@ -3610,13 +4311,25 @@
 		ct = config_find_table( colst, nocs, a->a_desc, ca );
 		if ( !ct ) continue;	/* user data? */
 		for (i=0; a->a_vals[i].bv_val; i++) {
+			char *iptr = NULL;
 			ca->line = a->a_vals[i].bv_val;
 			if ( a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED ) {
 				ptr = strchr( ca->line, '}' );
-				if ( ptr ) ca->line = ptr+1;
+				if ( ptr ) {
+					iptr = strchr( ca->line, '{' );
+					ca->line = ptr+1;
+				}
 			}
-			ca->valx = i;
-			rc = config_parse_add( ct, ca );
+			if ( a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED_SIB ) {
+				if ( iptr ) {
+					ca->valx = strtol( iptr+1, NULL, 0 );
+				} else {
+					ca->valx = -1;
+				}
+			} else {
+				ca->valx = i;
+			}
+			rc = config_parse_add( ct, ca, i );
 			if ( rc ) {
 				rc = LDAP_OTHER;
 				goto done;
@@ -3627,25 +4340,30 @@
 	/* Newly added databases and overlays need to be started up */
 	if ( CONFIG_ONLINE_ADD( ca )) {
 		if ( colst[0]->co_type == Cft_Database ) {
-			rc = backend_startup_one( ca->be );
+			rc = backend_startup_one( ca->be, &ca->reply );
 
 		} else if ( colst[0]->co_type == Cft_Overlay ) {
 			if ( ca->bi->bi_db_open ) {
 				BackendInfo *bi_orig = ca->be->bd_info;
 				ca->be->bd_info = ca->bi;
-				rc = ca->bi->bi_db_open( ca->be );
+				rc = ca->bi->bi_db_open( ca->be, &ca->reply );
 				ca->be->bd_info = bi_orig;
 			}
+		} else if ( ca->cleanup ) {
+			rc = ca->cleanup( ca );
 		}
 		if ( rc ) {
-			snprintf( ca->msg, sizeof( ca->msg ), "<%s> failed startup", ca->argv[0] );
+			if (ca->cr_msg[0] == '\0')
+				snprintf( ca->cr_msg, sizeof( ca->cr_msg ), "<%s> failed startup", ca->argv[0] );
+
 			Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
-				ca->log, ca->msg, ca->argv[1] );
+				ca->log, ca->cr_msg, ca->argv[1] );
 			rc = LDAP_OTHER;
 			goto done;
 		}
 	}
 
+	ca->valx = ibase;
 	ce = ch_calloc( 1, sizeof(CfEntryInfo) );
 	ce->ce_parent = last;
 	ce->ce_entry = entry_dup( e );
@@ -3654,14 +4372,41 @@
 	ce->ce_be = ca->be;
 	ce->ce_bi = ca->bi;
 	ce->ce_private = ca->private;
+	ca->ca_entry = ce->ce_entry;
 	if ( !last ) {
 		cfb->cb_root = ce;
 	} else if ( last->ce_kids ) {
-		CfEntryInfo *c2;
+		CfEntryInfo *c2, **cprev;
 
-		for (c2=last->ce_kids; c2 && c2->ce_sibs; c2 = c2->ce_sibs);
-
-		c2->ce_sibs = ce;
+		/* Advance to first of this type */
+		cprev = &last->ce_kids;
+		for ( c2 = *cprev; c2 && c2->ce_type < ce->ce_type; ) {
+			cprev = &c2->ce_sibs;
+			c2 = c2->ce_sibs;
+		}
+		/* Account for the (-1) frontendDB entry */
+		if ( ce->ce_type == Cft_Database ) {
+			if ( ca->be == frontendDB )
+				ibase = 0;
+			else if ( ibase != -1 )
+				ibase++;
+		}
+		/* Append */
+		if ( ibase < 0 ) {
+			for (c2 = *cprev; c2 && c2->ce_type == ce->ce_type;) {
+				cprev = &c2->ce_sibs;
+				c2 = c2->ce_sibs;
+			}
+		} else {
+		/* Insert */
+			int i;
+			for ( i=0; i<ibase; i++ ) {
+				c2 = *cprev;
+				cprev = &c2->ce_sibs;
+			}
+		}
+		ce->ce_sibs = *cprev;
+		*cprev = ce;
 	} else {
 		last->ce_kids = ce;
 	}
@@ -3673,14 +4418,87 @@
 				backend_destroy_one( ca->be, 1 );
 		} else if ( (colst[0]->co_type == Cft_Overlay) && ca->bi ) {
 			overlay_destroy_one( ca->be, (slap_overinst *)ca->bi );
+		} else if ( colst[0]->co_type == Cft_Schema ) {
+			schema_destroy_one( ca, colst, nocs, last );
 		}
 	}
+done_noop:
 
 	ch_free( ca->argv );
 	if ( colst ) ch_free( colst );
 	return rc;
 }
 
+#define	BIGTMP	10000
+static int
+config_rename_add( Operation *op, SlapReply *rs, CfEntryInfo *ce,
+	int base, int rebase, int max, int use_ldif )
+{
+	CfEntryInfo *ce2, *ce3, *cetmp = NULL, *cerem = NULL;
+	ConfigType etype = ce->ce_type;
+	int count = 0, rc = 0;
+
+	/* Reverse ce list */
+	for (ce2 = ce->ce_sibs;ce2;ce2 = ce3) {
+		if (ce2->ce_type != etype) {
+			cerem = ce2;
+			break;
+		}
+		ce3 = ce2->ce_sibs;
+		ce2->ce_sibs = cetmp;
+		cetmp = ce2;
+		count++;
+		if ( max && count >= max ) {
+			cerem = ce3;
+			break;
+		}
+	}
+
+	/* Move original to a temp name until increments are done */
+	if ( rebase ) {
+		ce->ce_entry->e_private = NULL;
+		rc = config_renumber_one( op, rs, ce->ce_parent, ce->ce_entry,
+			base+BIGTMP, 0, use_ldif );
+		ce->ce_entry->e_private = ce;
+	}
+	/* start incrementing */
+	for (ce2=cetmp; ce2; ce2=ce3) {
+		ce3 = ce2->ce_sibs;
+		ce2->ce_sibs = cerem;
+		cerem = ce2;
+		if ( rc == 0 ) 
+			rc = config_renumber_one( op, rs, ce2->ce_parent, ce2->ce_entry,
+				count+base, 0, use_ldif );
+		count--;
+	}
+	if ( rebase )
+		rc = config_renumber_one( op, rs, ce->ce_parent, ce->ce_entry,
+			base, 0, use_ldif );
+	return rc;
+}
+
+static int
+config_rename_del( Operation *op, SlapReply *rs, CfEntryInfo *ce,
+	CfEntryInfo *ce2, int old, int use_ldif )
+{
+	int count = 0;
+
+	/* Renumber original to a temp value */
+	ce->ce_entry->e_private = NULL;
+	config_renumber_one( op, rs, ce->ce_parent, ce->ce_entry,
+		old+BIGTMP, 0, use_ldif );
+	ce->ce_entry->e_private = ce;
+
+	/* start decrementing */
+	for (; ce2 != ce; ce2=ce2->ce_sibs) {
+		config_renumber_one( op, rs, ce2->ce_parent, ce2->ce_entry,
+			count+old, 0, use_ldif );
+		count++;
+	}
+	return config_renumber_one( op, rs, ce->ce_parent, ce->ce_entry,
+		count+old, 0, use_ldif );
+}
+
 /* Parse an LDAP entry into config directives, then store in underlying
  * database.
  */
@@ -3691,28 +4509,61 @@
 	int renumber;
 	ConfigArgs ca;
 
-	if ( !be_isroot( op ) ) {
+	if ( !access_allowed( op, op->ora_e, slap_schema.si_ad_entry,
+		NULL, ACL_WADD, NULL )) {
 		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
 		goto out;
 	}
 
 	cfb = (CfBackInfo *)op->o_bd->be_private;
 
+	/* add opattrs for syncprov */
+	{
+		char textbuf[SLAP_TEXT_BUFLEN];
+		size_t textlen = sizeof textbuf;
+		rs->sr_err = entry_schema_check(op, op->ora_e, NULL, 0, 1,
+			&rs->sr_text, textbuf, sizeof( textbuf ) );
+		if ( rs->sr_err != LDAP_SUCCESS )
+			goto out;
+		rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+		if ( rs->sr_err != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_TRACE,
+				LDAP_XSTRING(config_back_add) ": entry failed op attrs add: "
+				"%s (%d)\n", rs->sr_text, rs->sr_err, 0 );
+			goto out;
+		}
+	}
+
 	ldap_pvt_thread_pool_pause( &connection_pool );
 
 	/* Strategy:
 	 * 1) check for existence of entry
 	 * 2) check for sibling renumbering
 	 * 3) perform internal add
-	 * 4) store entry in underlying database
-	 * 5) perform any necessary renumbering
+	 * 4) perform any necessary renumbering
+	 * 5) store entry in underlying database
 	 */
-	rs->sr_err = config_add_internal( cfb, op->ora_e, &ca, rs, &renumber );
+	rs->sr_err = config_add_internal( cfb, op->ora_e, &ca, rs, &renumber, op );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
-		rs->sr_text = ca.msg;
-	} else if ( cfb->cb_use_ldif ) {
+		rs->sr_text = ca.cr_msg;
+		goto out2;
+	}
+
+	if ( renumber ) {
+		CfEntryInfo *ce = ca.ca_entry->e_private;
+		req_add_s addr = op->oq_add;
+		op->o_tag = LDAP_REQ_MODRDN;
+		rs->sr_err = config_rename_add( op, rs, ce, ca.valx, 0, 0, cfb->cb_use_ldif );
+		op->o_tag = LDAP_REQ_ADD;
+		op->oq_add = addr;
+		if ( rs->sr_err != LDAP_SUCCESS ) {
+			goto out2;
+		}
+	}
+
+	if ( cfb->cb_use_ldif ) {
 		BackendDB *be = op->o_bd;
-		slap_callback sc = { NULL, slap_null_cb, NULL, NULL };
+		slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
 		struct berval dn, ndn;
 
 		op->o_bd = &cfb->cb_db;
@@ -3723,21 +4574,21 @@
 		op->o_dn = op->o_bd->be_rootdn;
 		op->o_ndn = op->o_bd->be_rootndn;
 
-		sc.sc_next = op->o_callback;
+		scp = op->o_callback;
 		op->o_callback = &sc;
 		op->o_bd->be_add( op, rs );
 		op->o_bd = be;
-		op->o_callback = sc.sc_next;
+		op->o_callback = scp;
 		op->o_dn = dn;
 		op->o_ndn = ndn;
 	}
-	if ( renumber ) {
-	}
 
+out2:;
 	ldap_pvt_thread_pool_resume( &connection_pool );
 
-out:
+out:;
 	send_ldap_result( op, rs );
+	slap_graduate_commit_csn( op );
 	return rs->sr_err;
 }
 
@@ -3748,13 +4599,40 @@
 } delrec;
 
 static int
+config_modify_add( ConfigTable *ct, ConfigArgs *ca, AttributeDescription *ad,
+	int i )
+{
+	int rc;
+
+	if (ad->ad_type->sat_flags & SLAP_AT_ORDERED &&
+		ca->line[0] == '{' )
+	{
+		char *ptr = strchr( ca->line + 1, '}' );
+		if ( ptr ) {
+			char	*next;
+
+			ca->valx = strtol( ca->line + 1, &next, 0 );
+			if ( next == ca->line + 1 || next[ 0 ] != '}' ) {
+				return LDAP_OTHER;
+			}
+			ca->line = ptr+1;
+		}
+	}
+	rc = config_parse_add( ct, ca, i );
+	if ( rc ) {
+		rc = LDAP_OTHER;
+	}
+	return rc;
+}
+
+static int
 config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
 	ConfigArgs *ca )
 {
 	int rc = LDAP_UNWILLING_TO_PERFORM;
 	Modifications *ml;
 	Entry *e = ce->ce_entry;
-	Attribute *save_attrs = e->e_attrs, *oc_at;
+	Attribute *save_attrs = e->e_attrs, *oc_at, *s, *a;
 	ConfigTable *ct;
 	ConfigOCs **colst;
 	int i, nocs;
@@ -3766,6 +4644,11 @@
 
 	colst = count_ocs( oc_at, &nocs );
 
+	/* make sure add/del flags are clear; should always be true */
+	for ( s = save_attrs; s; s = s->a_next ) {
+		s->a_flags &= ~(SLAP_ATTR_IXADD|SLAP_ATTR_IXDEL);
+	}
+
 	e->e_attrs = attrs_dup( e->e_attrs );
 
 	init_config_argv( ca );
@@ -3774,6 +4657,7 @@
 	ca->private = ce->ce_private;
 	ca->ca_entry = e;
 	ca->fname = "slapd";
+	ca->ca_op = op;
 	strcpy( ca->log, "back-config" );
 
 	for (ml = op->orm_modlist; ml; ml=ml->sml_next) {
@@ -3785,9 +4669,9 @@
 			int *idx = NULL;
 			if ( ct && ( ct->arg_type & ARG_NO_DELETE )) {
 				rc = LDAP_OTHER;
-				snprintf(ca->msg, sizeof(ca->msg), "cannot delete %s",
+				snprintf(ca->cr_msg, sizeof(ca->cr_msg), "cannot delete %s",
 					ml->sml_desc->ad_cname.bv_val );
-				goto out;
+				goto out_noop;
 			}
 			if ( ml->sml_op == LDAP_MOD_REPLACE ) {
 				vals = ml->sml_values;
@@ -3800,7 +4684,7 @@
 			 */
 			if ( ct && ml->sml_values ) {
 				delrec *d;
-				for (i=0; ml->sml_values[i].bv_val; i++);
+				i = ml->sml_numvals;
 				d = ch_malloc( sizeof(delrec) + (i - 1)* sizeof(int));
 				d->nidx = i;
 				d->next = NULL;
@@ -3814,7 +4698,7 @@
 			}
 			rc = modify_delete_vindex(e, &ml->sml_mod,
 				get_permissiveModify(op),
-				&rs->sr_text, ca->msg, sizeof(ca->msg), idx );
+				&rs->sr_text, ca->cr_msg, sizeof(ca->cr_msg), idx );
 			if ( ml->sml_op == LDAP_MOD_REPLACE ) {
 				ml->sml_values = vals;
 				ml->sml_nvalues = nvals;
@@ -3833,8 +4717,7 @@
 				if ( ct->arg_type & ARG_NO_INSERT ) {
 					Attribute *a = attr_find( e->e_attrs, ml->sml_desc );
 					if ( a ) {
-						for (i = 0; a->a_vals[i].bv_val; i++ );
-						navals = i;
+						navals = a->a_numvals;
 					}
 				}
 				for ( i=0; !BER_BVISNULL( &ml->sml_values[i] ); i++ ) {
@@ -3847,18 +4730,18 @@
 						j = strtol( val, &next, 0 );
 						if ( next == val || next[ 0 ] != '}' || j < navals ) {
 							rc = LDAP_OTHER;
-							snprintf(ca->msg, sizeof(ca->msg), "cannot insert %s",
+							snprintf(ca->cr_msg, sizeof(ca->cr_msg), "cannot insert %s",
 								ml->sml_desc->ad_cname.bv_val );
-							goto out;
+							goto out_noop;
 						}
 					}
 					rc = check_vals( ct, ca, ml, 0 );
-					if ( rc ) goto out;
+					if ( rc ) goto out_noop;
 				}
 			}
 			rc = modify_add_values(e, &ml->sml_mod,
 				   get_permissiveModify(op),
-				   &rs->sr_text, ca->msg, sizeof(ca->msg) );
+				   &rs->sr_text, ca->cr_msg, sizeof(ca->cr_msg) );
 
 			/* If value already exists, show success here
 			 * and ignore this operation down below.
@@ -3882,116 +4765,146 @@
 		if(rc != LDAP_SUCCESS) break;
 	}
 	
-	if(rc == LDAP_SUCCESS) {
+	if ( rc == LDAP_SUCCESS) {
 		/* check that the entry still obeys the schema */
-		rc = entry_schema_check(op, e, NULL, 0,
-			&rs->sr_text, ca->msg, sizeof(ca->msg) );
+		rc = entry_schema_check(op, e, NULL, 0, 0,
+			&rs->sr_text, ca->cr_msg, sizeof(ca->cr_msg) );
+		if ( rc ) goto out_noop;
 	}
-	if ( rc == LDAP_SUCCESS ) {
-		/* Basic syntax checks are OK. Do the actual settings. */
-		for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
-			ct = config_find_table( colst, nocs, ml->sml_desc, ca );
-			if ( !ct ) continue;
+	/* Basic syntax checks are OK. Do the actual settings. */
+	for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
+		ct = config_find_table( colst, nocs, ml->sml_desc, ca );
+		if ( !ct ) continue;
 
-			switch (ml->sml_op) {
-			case LDAP_MOD_DELETE:
-			case LDAP_MOD_REPLACE: {
-				BerVarray vals = NULL, nvals = NULL;
-				Attribute *a;
-				delrec *d = NULL;
+		s = attr_find( save_attrs, ml->sml_desc );
+		a = attr_find( e->e_attrs, ml->sml_desc );
 
-				a = attr_find( e->e_attrs, ml->sml_desc );
+		switch (ml->sml_op) {
+		case LDAP_MOD_DELETE:
+		case LDAP_MOD_REPLACE: {
+			BerVarray vals = NULL, nvals = NULL;
+			delrec *d = NULL;
 
-				if ( ml->sml_op == LDAP_MOD_REPLACE ) {
-					vals = ml->sml_values;
-					nvals = ml->sml_nvalues;
-					ml->sml_values = NULL;
-					ml->sml_nvalues = NULL;
-				}
+			if ( ml->sml_op == LDAP_MOD_REPLACE ) {
+				vals = ml->sml_values;
+				nvals = ml->sml_nvalues;
+				ml->sml_values = NULL;
+				ml->sml_nvalues = NULL;
+			}
 
-				if ( ml->sml_values )
-					d = dels;
+			if ( ml->sml_values )
+				d = dels;
 
-				/* If we didn't delete the whole attribute */
-				if ( ml->sml_values && a ) {
-					struct berval *mvals;
-					int j;
+			/* If we didn't delete the whole attribute */
+			if ( ml->sml_values && a ) {
+				struct berval *mvals;
+				int j;
 
-					if ( ml->sml_nvalues )
-						mvals = ml->sml_nvalues;
-					else
-						mvals = ml->sml_values;
+				if ( ml->sml_nvalues )
+					mvals = ml->sml_nvalues;
+				else
+					mvals = ml->sml_values;
 
-					/* use the indexes we saved up above */
-					for (i=0; i < d->nidx; i++) {
-						struct berval bv = *mvals++;
-						if ( a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED &&
-							bv.bv_val[0] == '{' ) {
-							ptr = strchr( bv.bv_val, '}' ) + 1;
-							bv.bv_len -= ptr - bv.bv_val;
-							bv.bv_val = ptr;
-						}
-						ca->line = bv.bv_val;
-						ca->valx = d->idx[i];
-						rc = config_del_vals( ct, ca );
-						if ( rc != LDAP_SUCCESS ) break;
-						for (j=i+1; j < d->nidx; j++)
-							if ( d->idx[j] >d->idx[i] )
-								d->idx[j]--;
+				/* use the indexes we saved up above */
+				for (i=0; i < d->nidx; i++) {
+					struct berval bv = *mvals++;
+					if ( a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED &&
+						bv.bv_val[0] == '{' ) {
+						ptr = strchr( bv.bv_val, '}' ) + 1;
+						bv.bv_len -= ptr - bv.bv_val;
+						bv.bv_val = ptr;
 					}
-				} else {
+					ca->line = bv.bv_val;
+					ca->valx = d->idx[i];
+					rc = config_del_vals( ct, ca );
+					if ( rc != LDAP_SUCCESS ) break;
+					if ( s )
+						s->a_flags |= SLAP_ATTR_IXDEL;
+					for (j=i+1; j < d->nidx; j++)
+						if ( d->idx[j] >d->idx[i] )
+							d->idx[j]--;
+				}
+			} else {
+				ca->valx = -1;
+				ca->line = NULL;
+				rc = config_del_vals( ct, ca );
+				if ( rc ) rc = LDAP_OTHER;
+				if ( s )
+					s->a_flags |= SLAP_ATTR_IXDEL;
+			}
+			if ( ml->sml_values ) {
+				d = d->next;
+				ch_free( dels );
+				dels = d;
+			}
+			if ( ml->sml_op == LDAP_MOD_REPLACE ) {
+				ml->sml_values = vals;
+				ml->sml_nvalues = nvals;
+			}
+			if ( !vals || rc != LDAP_SUCCESS )
+				break;
+			}
+			/* FALLTHRU: LDAP_MOD_REPLACE && vals */
+
+		case LDAP_MOD_ADD:
+			for (i=0; ml->sml_values[i].bv_val; i++) {
+				ca->line = ml->sml_values[i].bv_val;
+				ca->valx = -1;
+				rc = config_modify_add( ct, ca, ml->sml_desc, i );
+				if ( rc )
+					goto out;
+				a->a_flags |= SLAP_ATTR_IXADD;
+			}
+			break;
+		}
+	}
+
+out:
+	/* Undo for a failed operation */
+	if ( rc != LDAP_SUCCESS ) {
+		ConfigReply msg = ca->reply;
+		for ( s = save_attrs; s; s = s->a_next ) {
+			if ( s->a_flags & SLAP_ATTR_IXDEL ) {
+				s->a_flags &= ~(SLAP_ATTR_IXDEL|SLAP_ATTR_IXADD);
+				ct = config_find_table( colst, nocs, s->a_desc, ca );
+				a = attr_find( e->e_attrs, s->a_desc );
+				if ( a ) {
+					/* clear the flag so the add check below will skip it */
+					a->a_flags &= ~(SLAP_ATTR_IXDEL|SLAP_ATTR_IXADD);
 					ca->valx = -1;
 					ca->line = NULL;
-					rc = config_del_vals( ct, ca );
-					if ( rc ) rc = LDAP_OTHER;
+					config_del_vals( ct, ca );
 				}
-				if ( ml->sml_values ) {
-					ch_free( dels );
-					dels = d->next;
+				for ( i=0; !BER_BVISNULL( &s->a_vals[i] ); i++ ) {
+					ca->line = s->a_vals[i].bv_val;
+					ca->valx = -1;
+					config_modify_add( ct, ca, s->a_desc, i );
 				}
-				if ( ml->sml_op == LDAP_MOD_REPLACE ) {
-					ml->sml_values = vals;
-					ml->sml_nvalues = nvals;
-				}
-				if ( !vals || rc != LDAP_SUCCESS )
-					break;
-				}
-				/* FALLTHRU: LDAP_MOD_REPLACE && vals */
-
-			case LDAP_MOD_ADD:
-				for (i=0; ml->sml_values[i].bv_val; i++) {
-					ca->line = ml->sml_values[i].bv_val;
-					ca->valx = -1;
-					if ( ml->sml_desc->ad_type->sat_flags & SLAP_AT_ORDERED &&
-						ca->line[0] == '{' )
-					{
-						ptr = strchr( ca->line + 1, '}' );
-						if ( ptr ) {
-							char	*next;
-
-							ca->valx = strtol( ca->line + 1, &next, 0 );
-							if ( next == ca->line + 1 || next[ 0 ] != '}' ) {
-								rc = LDAP_OTHER;
-								goto out;
-							}
-							ca->line = ptr+1;
-						}
+			}
+		}
+		for ( a = e->e_attrs; a; a = a->a_next ) {
+			if ( a->a_flags & SLAP_ATTR_IXADD ) {
+				ct = config_find_table( colst, nocs, a->a_desc, ca );
+				ca->valx = -1;
+				ca->line = NULL;
+				config_del_vals( ct, ca );
+				s = attr_find( save_attrs, a->a_desc );
+				if ( s ) {
+					s->a_flags &= ~(SLAP_ATTR_IXDEL|SLAP_ATTR_IXADD);
+					for ( i=0; !BER_BVISNULL( &s->a_vals[i] ); i++ ) {
+						ca->line = s->a_vals[i].bv_val;
+						ca->valx = -1;
+						config_modify_add( ct, ca, s->a_desc, i );
 					}
-					rc = config_parse_add( ct, ca );
-					if ( rc ) {
-						rc = LDAP_OTHER;
-						goto out;
-					}
 				}
-
-				break;
 			}
 		}
+		ca->reply = msg;
 	}
 
-out:
 	if ( ca->cleanup )
 		ca->cleanup( ca );
+out_noop:
 	if ( rc == LDAP_SUCCESS ) {
 		attrs_free( save_attrs );
 	} else {
@@ -4000,6 +4913,11 @@
 	}
 	ch_free( ca->argv );
 	if ( colst ) ch_free( colst );
+	while( dels ) {
+		deltail = dels->next;
+		ch_free( dels );
+		dels = deltail;
+	}
 
 	return rc;
 }
@@ -4014,12 +4932,8 @@
 	struct berval rdn;
 	char *ptr;
 	AttributeDescription *rad = NULL;
+	int do_pause = 1;
 
-	if ( !be_isroot( op ) ) {
-		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-		goto out;
-	}
-
 	cfb = (CfBackInfo *)op->o_bd->be_private;
 
 	ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
@@ -4030,6 +4944,11 @@
 		goto out;
 	}
 
+	if ( !acl_check_modlist( op, ce->ce_entry, op->orm_modlist )) {
+		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+		goto out;
+	}
+
 	/* Get type of RDN */
 	rdn = ce->ce_entry->e_nname;
 	ptr = strchr( rdn.bv_val, '=' );
@@ -4044,10 +4963,18 @@
 			rs->sr_text = "Use modrdn to change the entry name";
 			goto out;
 		}
+		/* Internal update of contextCSN? */
+		if ( ml->sml_desc == slap_schema.si_ad_contextCSN && op->o_conn->c_conn_idx == -1 ) {
+			do_pause = 0;
+			break;
+		}
 	}
 
-	ldap_pvt_thread_pool_pause( &connection_pool );
+	slap_mods_opattrs( op, &op->orm_modlist, 1 );
 
+	if ( do_pause )
+		ldap_pvt_thread_pool_pause( &connection_pool );
+
 	/* Strategy:
 	 * 1) perform the Modify on the cached Entry.
 	 * 2) verify that the Entry still satisfies the schema.
@@ -4056,10 +4983,10 @@
 	 */
 	rs->sr_err = config_modify_internal( ce, op, rs, &ca );
 	if ( rs->sr_err ) {
-		rs->sr_text = ca.msg;
+		rs->sr_text = ca.cr_msg;
 	} else if ( cfb->cb_use_ldif ) {
 		BackendDB *be = op->o_bd;
-		slap_callback sc = { NULL, slap_null_cb, NULL, NULL };
+		slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
 		struct berval dn, ndn;
 
 		op->o_bd = &cfb->cb_db;
@@ -4069,18 +4996,20 @@
 		op->o_dn = op->o_bd->be_rootdn;
 		op->o_ndn = op->o_bd->be_rootndn;
 
-		sc.sc_next = op->o_callback;
+		scp = op->o_callback;
 		op->o_callback = &sc;
 		op->o_bd->be_modify( op, rs );
 		op->o_bd = be;
-		op->o_callback = sc.sc_next;
+		op->o_callback = scp;
 		op->o_dn = dn;
 		op->o_ndn = ndn;
 	}
 
-	ldap_pvt_thread_pool_resume( &connection_pool );
+	if ( do_pause )
+		ldap_pvt_thread_pool_resume( &connection_pool );
 out:
 	send_ldap_result( op, rs );
+	slap_graduate_commit_csn( op );
 	return rs->sr_err;
 }
 
@@ -4089,12 +5018,9 @@
 {
 	CfBackInfo *cfb;
 	CfEntryInfo *ce, *last;
+	struct berval rdn;
+	int ixold, ixnew;
 
-	if ( !be_isroot( op ) ) {
-		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-		goto out;
-	}
-
 	cfb = (CfBackInfo *)op->o_bd->be_private;
 
 	ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
@@ -4104,6 +5030,22 @@
 		rs->sr_err = LDAP_NO_SUCH_OBJECT;
 		goto out;
 	}
+	if ( !access_allowed( op, ce->ce_entry, slap_schema.si_ad_entry,
+		NULL, ACL_WRITE, NULL )) {
+		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+		goto out;
+	}
+	{ Entry *parent;
+		if ( ce->ce_parent )
+			parent = ce->ce_parent->ce_entry;
+		else
+			parent = (Entry *)&slap_entry_root;
+		if ( !access_allowed( op, parent, slap_schema.si_ad_children,
+			NULL, ACL_WRITE, NULL )) {
+			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+			goto out;
+		}
+	}
 
 	/* We don't allow moving objects to new parents.
 	 * Generally we only allow reordering a set of ordered entries.
@@ -4112,8 +5054,156 @@
 		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
 		goto out;
 	}
+
+	/* If newRDN == oldRDN, quietly succeed */
+	dnRdn( &op->o_req_ndn, &rdn );
+	if ( dn_match( &rdn, &op->orr_nnewrdn )) {
+		rs->sr_err = LDAP_SUCCESS;
+		goto out;
+	}
+
+	/* Current behavior, subject to change as needed:
+	 *
+	 * For backends and overlays, we only allow renumbering.
+	 * For schema, we allow renaming with the same number.
+	 * Otherwise, the op is not allowed.
+	 */
+
+	if ( ce->ce_type == Cft_Schema ) {
+		char *ptr1, *ptr2;
+		int len;
+
+		/* Can't alter the main cn=schema entry */
+		if ( ce->ce_parent->ce_type == Cft_Global ) {
+			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+			rs->sr_text = "renaming not allowed for this entry";
+			goto out;
+		}
+
+		/* We could support this later if desired */
+		ptr1 = ber_bvchr( &rdn, '}' );
+		ptr2 = ber_bvchr( &op->orr_newrdn, '}' );
+		len = ptr1 - rdn.bv_val;
+		if ( len != ptr2 - op->orr_newrdn.bv_val ||
+			strncmp( rdn.bv_val, op->orr_newrdn.bv_val, len )) {
+			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+			rs->sr_text = "schema reordering not supported";
+			goto out;
+		}
+	} else if ( ce->ce_type == Cft_Database ||
+		ce->ce_type == Cft_Overlay ) {
+		char *ptr1, *ptr2, *iptr1, *iptr2;
+		int len1, len2;
+
+		iptr2 = ber_bvchr( &op->orr_newrdn, '=' ) + 1;
+		if ( *iptr2 != '{' ) {
+			rs->sr_err = LDAP_NAMING_VIOLATION;
+			rs->sr_text = "new ordering index is required";
+			goto out;
+		}
+		iptr2++;
+		iptr1 = ber_bvchr( &rdn, '{' ) + 1;
+		ptr1 = ber_bvchr( &rdn, '}' );
+		ptr2 = ber_bvchr( &op->orr_newrdn, '}' );
+		if ( !ptr2 ) {
+			rs->sr_err = LDAP_NAMING_VIOLATION;
+			rs->sr_text = "new ordering index is required";
+			goto out;
+		}
+
+		len1 = ptr1 - rdn.bv_val;
+		len2 = ptr2 - op->orr_newrdn.bv_val;
+
+		if ( rdn.bv_len - len1 != op->orr_newrdn.bv_len - len2 ||
+			strncmp( ptr1, ptr2, rdn.bv_len - len1 )) {
+			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+			rs->sr_text = "changing database/overlay type not allowed";
+			goto out;
+		}
+		ixold = strtol( iptr1, NULL, 0 );
+		ixnew = strtol( iptr2, &ptr1, 0 );
+		if ( ptr1 != ptr2 || ixold < 0 || ixnew < 0 ) {
+			rs->sr_err = LDAP_NAMING_VIOLATION;
+			goto out;
+		}
+		/* config DB is always 0, cannot be changed */
+		if ( ce->ce_type == Cft_Database && ( ixold == 0 || ixnew == 0 )) {
+			rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
+			goto out;
+		}
+	} else {
+		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+		rs->sr_text = "renaming not supported for this entry";
+		goto out;
+	}
+
 	ldap_pvt_thread_pool_pause( &connection_pool );
 
+	if ( ce->ce_type == Cft_Schema ) {
+		req_modrdn_s modr = op->oq_modrdn;
+		struct berval rdn;
+		Attribute *a;
+		rs->sr_err = config_rename_attr( rs, ce->ce_entry, &rdn, &a );
+		if ( rs->sr_err == LDAP_SUCCESS ) {
+			rs->sr_err = config_rename_one( op, rs, ce->ce_entry,
+				ce->ce_parent, a, &op->orr_newrdn, &op->orr_nnewrdn,
+				cfb->cb_use_ldif );
+		}
+		op->oq_modrdn = modr;
+	} else {
+		CfEntryInfo *ce2, *cebase, **cprev, **cbprev, *ceold;
+		req_modrdn_s modr = op->oq_modrdn;
+		int i;
+
+		/* Advance to first of this type */
+		cprev = &ce->ce_parent->ce_kids;
+		for ( ce2 = *cprev; ce2 && ce2->ce_type != ce->ce_type; ) {
+			cprev = &ce2->ce_sibs;
+			ce2 = ce2->ce_sibs;
+		}
+		/* Skip the -1 entry */
+		if ( ce->ce_type == Cft_Database ) {
+			cprev = &ce2->ce_sibs;
+			ce2 = ce2->ce_sibs;
+		}
+		cebase = ce2;
+		cbprev = cprev;
+
+		/* Remove from old slot */
+		for ( ce2 = *cprev; ce2 && ce2 != ce; ce2 = ce2->ce_sibs )
+			cprev = &ce2->ce_sibs;
+		*cprev = ce->ce_sibs;
+		ceold = ce->ce_sibs;
+
+		/* Insert into new slot */
+		cprev = cbprev;
+		for ( i=0; i<ixnew; i++ ) {
+			ce2 = *cprev;
+			if ( !ce2 )
+				break;
+			cprev = &ce2->ce_sibs;
+		}
+		ce->ce_sibs = *cprev;
+		*cprev = ce;
+
+		ixnew = i;
+
+		/* NOTE: These should be encoded in the OC tables, not inline here */
+		if ( ce->ce_type == Cft_Database )
+			backend_db_move( ce->ce_be, ixnew );
+		else if ( ce->ce_type == Cft_Overlay )
+			overlay_move( ce->ce_be, (slap_overinst *)ce->ce_bi, ixnew );
+			
+		if ( ixold < ixnew ) {
+			rs->sr_err = config_rename_del( op, rs, ce, ceold, ixold,
+				cfb->cb_use_ldif );
+		} else {
+			rs->sr_err = config_rename_add( op, rs, ce, ixnew, 1,
+				ixold - ixnew, cfb->cb_use_ldif );
+		}
+		op->oq_modrdn = modr;
+	}
+
 	ldap_pvt_thread_pool_resume( &connection_pool );
 out:
 	send_ldap_result( op, rs );
@@ -4121,16 +5211,19 @@
 }
 
 static int
+config_back_delete( Operation *op, SlapReply *rs )
+{
+	send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, NULL );
+	return rs->sr_err;
+}
+
+static int
 config_back_search( Operation *op, SlapReply *rs )
 {
 	CfBackInfo *cfb;
 	CfEntryInfo *ce, *last;
+	slap_mask_t mask;
 
-	if ( !be_isroot( op ) ) {
-		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-		goto out;
-	}
-
 	cfb = (CfBackInfo *)op->o_bd->be_private;
 
 	ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
@@ -4140,6 +5233,16 @@
 		rs->sr_err = LDAP_NO_SUCH_OBJECT;
 		goto out;
 	}
+	if ( !access_allowed_mask( op, ce->ce_entry, slap_schema.si_ad_entry, NULL,
+		ACL_SEARCH, NULL, &mask ))
+	{
+		if ( !ACL_GRANT( mask, ACL_DISCLOSE )) {
+			rs->sr_err = LDAP_NO_SUCH_OBJECT;
+		} else {
+			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+		}
+		goto out;
+	}
 	switch ( op->ors_scope ) {
 	case LDAP_SCOPE_BASE:
 	case LDAP_SCOPE_SUBTREE:
@@ -4159,6 +5262,44 @@
 	return 0;
 }
 
+/* no-op, we never free entries */
+int config_entry_release(
+	Operation *op,
+	Entry *e,
+	int rw )
+{
+	if ( !e->e_private ) {
+		entry_free( e );
+	}
+	return LDAP_SUCCESS;
+}
+
+/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
+ */
+int config_back_entry_get(
+	Operation *op,
+	struct berval *ndn,
+	ObjectClass *oc,
+	AttributeDescription *at,
+	int rw,
+	Entry **ent )
+{
+	CfBackInfo *cfb;
+	CfEntryInfo *ce, *last;
+
+	cfb = (CfBackInfo *)op->o_bd->be_private;
+
+	ce = config_find_base( cfb->cb_root, ndn, &last );
+	if ( ce ) {
+		*ent = ce->ce_entry;
+		if ( *ent && oc && !is_entry_objectclass_or_sub( *ent, oc ) ) {
+			*ent = NULL;
+		}
+	}
+
+	return ( *ent == NULL ? 1 : 0 );
+}
+
 static void
 config_build_attrs( Entry *e, AttributeType **at, AttributeDescription *ad,
 	ConfigTable *ct, ConfigArgs *c )
@@ -4194,7 +5335,7 @@
 config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
 	ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra )
 {
-	Entry *e = ch_calloc( 1, sizeof(Entry) );
+	Entry *e = entry_alloc();
 	CfEntryInfo *ce = ch_calloc( 1, sizeof(CfEntryInfo) );
 	struct berval val;
 	struct berval ad_name;
@@ -4210,17 +5351,18 @@
 	Debug( LDAP_DEBUG_TRACE, "config_build_entry: \"%s\"\n", rdn->bv_val, 0, 0);
 	e->e_private = ce;
 	ce->ce_entry = e;
+	ce->ce_type = main->co_type;
 	ce->ce_parent = parent;
 	if ( parent ) {
 		pdn = parent->ce_entry->e_nname;
 		if ( parent->ce_kids )
-			for ( ceprev = parent->ce_kids; ceprev->ce_sibs;
+			for ( ceprev = parent->ce_kids; ceprev->ce_sibs &&
+				ceprev->ce_type <= ce->ce_type;
 				ceprev = ceprev->ce_sibs );
 	} else {
 		BER_BVZERO( &pdn );
 	}
 
-	ce->ce_type = main->co_type;
 	ce->ce_private = c->private;
 	ce->ce_be = c->be;
 	ce->ce_bi = c->bi;
@@ -4263,11 +5405,12 @@
 	}
 
 	oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
-	rc = structural_class(oc_at->a_vals, &val, NULL, &text, c->msg,
-		sizeof(c->msg));
-	attr_merge_normalize_one(e, slap_schema.si_ad_structuralObjectClass, &val, NULL );
-	if ( op ) {
+	rc = structural_class(oc_at->a_vals, &oc, NULL, &text, c->cr_msg,
+		sizeof(c->cr_msg), op ? op->o_tmpmemctx : NULL );
+	attr_merge_normalize_one(e, slap_schema.si_ad_structuralObjectClass, &oc->soc_cname, NULL );
+	if ( op && !op->o_noop ) {
 		op->ora_e = e;
+		op->ora_modlist = NULL;
 		op->o_bd->be_add( op, rs );
 		if ( ( rs->sr_err != LDAP_SUCCESS ) 
 				&& (rs->sr_err != LDAP_ALREADY_EXISTS) ) {
@@ -4275,8 +5418,10 @@
 		}
 	}
 	if ( ceprev ) {
+		ce->ce_sibs = ceprev->ce_sibs;
 		ceprev->ce_sibs = ce;
 	} else if ( parent ) {
+		ce->ce_sibs = parent->ce_kids;
 		parent->ce_kids = ce;
 	}
 
@@ -4330,34 +5475,6 @@
 	return 0;
 }
 
-static int
-config_build_includes( ConfigArgs *c, CfEntryInfo *ceparent,
-	Operation *op, SlapReply *rs )
-{
-	Entry *e;
-	int i;
-	ConfigFile *cf = c->private;
-
-	for (i=0; cf; cf=cf->c_sibs, i++) {
-		c->value_dn.bv_val = c->log;
-		c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=include" SLAP_X_ORDERED_FMT, i);
-		if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
-			/* FIXME: how can indicate error? */
-			return -1;
-		}
-		c->private = cf;
-		e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
-			&CFOC_INCLUDE, NULL );
-		if ( ! e ) {
-			return -1;
-		} else if ( e && cf->c_kids ) {
-			c->private = cf->c_kids;
-			config_build_includes( c, e->e_private, op, rs );
-		}
-	}
-	return 0;
-}
-
 #ifdef SLAPD_MODULES
 
 static int
@@ -4386,8 +5503,95 @@
 #endif
 
 static int
-config_back_db_open( BackendDB *be )
+config_check_schema(Operation *op, CfBackInfo *cfb)
 {
+	struct berval schema_dn = BER_BVC(SCHEMA_RDN "," CONFIG_RDN);
+	ConfigArgs c = {0};
+	CfEntryInfo *ce, *last;
+	Entry *e;
+
+	/* If there's no root entry, we must be in the midst of converting */
+	if ( !cfb->cb_root )
+		return 0;
+
+	/* Make sure the main schema entry exists */
+	ce = config_find_base( cfb->cb_root, &schema_dn, &last );
+	if ( ce ) {
+		Attribute *a;
+		struct berval *bv;
+
+		e = ce->ce_entry;
+
+		/* Make sure it's up to date */
+		if ( cf_om_tail != om_sys_tail ) {
+			a = attr_find( e->e_attrs, cfAd_om );
+			if ( a ) {
+				if ( a->a_nvals != a->a_vals )
+					ber_bvarray_free( a->a_nvals );
+				ber_bvarray_free( a->a_vals );
+				a->a_vals = NULL;
+				a->a_nvals = NULL;
+				a->a_numvals = 0;
+			}
+			oidm_unparse( &bv, NULL, NULL, 1 );
+			attr_merge_normalize( e, cfAd_om, bv, NULL );
+			ber_bvarray_free( bv );
+			cf_om_tail = om_sys_tail;
+		}
+		if ( cf_at_tail != at_sys_tail ) {
+			a = attr_find( e->e_attrs, cfAd_attr );
+			if ( a ) {
+				if ( a->a_nvals != a->a_vals )
+					ber_bvarray_free( a->a_nvals );
+				ber_bvarray_free( a->a_vals );
+				a->a_vals = NULL;
+				a->a_nvals = NULL;
+				a->a_numvals = 0;
+			}
+			at_unparse( &bv, NULL, NULL, 1 );
+			attr_merge_normalize( e, cfAd_attr, bv, NULL );
+			ber_bvarray_free( bv );
+			cf_at_tail = at_sys_tail;
+		}
+		if ( cf_oc_tail != oc_sys_tail ) {
+			a = attr_find( e->e_attrs, cfAd_oc );
+			if ( a ) {
+				if ( a->a_nvals != a->a_vals )
+					ber_bvarray_free( a->a_nvals );
+				ber_bvarray_free( a->a_vals );
+				a->a_vals = NULL;
+				a->a_nvals = NULL;
+				a->a_numvals = 0;
+			}
+			oc_unparse( &bv, NULL, NULL, 1 );
+			attr_merge_normalize( e, cfAd_oc, bv, NULL );
+			ber_bvarray_free( bv );
+			cf_oc_tail = oc_sys_tail;
+		}
+	} else {
+		SlapReply rs = {REP_RESULT};
+		c.private = NULL;
+		e = config_build_entry( op, &rs, cfb->cb_root, &c, &schema_rdn,
+			&CFOC_SCHEMA, NULL );
+		if ( !e ) {
+			return -1;
+		}
+		ce = e->e_private;
+		ce->ce_private = cfb->cb_config;
+		cf_at_tail = at_sys_tail;
+		cf_oc_tail = oc_sys_tail;
+		cf_om_tail = om_sys_tail;
+	}
+	return 0;
+}
+
+static const char *defacl[] = {
+	NULL, "to", "*", "by", "*", "none", NULL
+};
+
+static int
+config_back_db_open( BackendDB *be, ConfigReply *cr )
+{
 	CfBackInfo *cfb = be->be_private;
 	struct berval rdn;
 	Entry *e, *parent;
@@ -4403,24 +5607,33 @@
 	void *thrctx = NULL;
 
 	Debug( LDAP_DEBUG_TRACE, "config_back_db_open\n", 0, 0, 0);
-	/* If we read the config from back-ldif, nothing to do here */
-	if ( cfb->cb_got_ldif )
-		return 0;
 
-	if ( cfb->cb_use_ldif ) {
-		thrctx = ldap_pvt_thread_pool_context();
-		op = (Operation *) &opbuf;
-		connection_fake_init( &conn, op, thrctx );
+	/* If we have no explicitly configured ACLs, don't just use
+	 * the global ACLs. Explicitly deny access to everything.
+	 */
+	if ( frontendDB->be_acl && be->be_acl == frontendDB->be_acl ) {
+		parse_acl(be, "config_back_db_open", 0, 6, (char **)defacl, 0 );
+	}
 
-		op->o_tag = LDAP_REQ_ADD;
-		op->o_callback = &cb;
-		op->o_bd = &cfb->cb_db;
-		op->o_dn = op->o_bd->be_rootdn;
-		op->o_ndn = op->o_bd->be_rootndn;
-	} else {
-		op = NULL;
+	thrctx = ldap_pvt_thread_pool_context();
+	connection_fake_init( &conn, &opbuf, thrctx );
+	op = &opbuf.ob_op;
+
+	op->o_tag = LDAP_REQ_ADD;
+	op->o_callback = &cb;
+	op->o_bd = &cfb->cb_db;
+	op->o_dn = op->o_bd->be_rootdn;
+	op->o_ndn = op->o_bd->be_rootndn;
+
+	if ( !cfb->cb_use_ldif ) {
+		op->o_noop = 1;
 	}
 
+	/* If we read the config from back-ldif, do some quick sanity checks */
+	if ( cfb->cb_got_ldif ) {
+		return config_check_schema( op, cfb );
+	}
+
 	/* create root of tree */
 	rdn = config_rdn;
 	c.private = cfb->cb_config;
@@ -4435,15 +5648,6 @@
 	parent = e;
 	ceparent = ce;
 
-	/* Create includeFile nodes */
-	if ( cfb->cb_config->c_kids ) {
-		c.depth = 0;
-		c.private = cfb->cb_config->c_kids;
-		if ( config_build_includes( &c, ceparent, op, &rs ) ) {
-			return -1;
-		}
-	}
-
 #ifdef SLAPD_MODULES
 	/* Create Module nodes... */
 	if ( modpaths.mp_loads ) {
@@ -4465,6 +5669,9 @@
 	}
 	ce = e->e_private;
 	ce->ce_private = cfb->cb_config;
+	cf_at_tail = at_sys_tail;
+	cf_oc_tail = oc_sys_tail;
+	cf_om_tail = om_sys_tail;
 
 	/* Create schema nodes for included schema... */
 	if ( cfb->cb_config->c_kids ) {
@@ -4621,7 +5828,7 @@
 }
 
 static int
-config_back_db_close( BackendDB *be )
+config_back_db_close( BackendDB *be, ConfigReply *cr )
 {
 	CfBackInfo *cfb = be->be_private;
 
@@ -4636,7 +5843,7 @@
 }
 
 static int
-config_back_db_destroy( BackendDB *be )
+config_back_db_destroy( BackendDB *be, ConfigReply *cr )
 {
 	CfBackInfo *cfb = be->be_private;
 
@@ -4655,20 +5862,18 @@
 		backend_destroy_one( &cfb->cb_db, 0 );
 	}
 
-	free( be->be_private );
-
 	loglevel_destroy();
 
 	return 0;
 }
 
 static int
-config_back_db_init( BackendDB *be )
+config_back_db_init( BackendDB *be, ConfigReply* cr )
 {
 	struct berval dn;
 	CfBackInfo *cfb;
 
-	cfb = ch_calloc( 1, sizeof(CfBackInfo));
+	cfb = &cfBackInfo;
 	cfb->cb_config = ch_calloc( 1, sizeof(ConfigFile));
 	cfn = cfb->cb_config;
 	be->be_private = cfb;
@@ -4754,15 +5959,128 @@
 		return NULL;
 }
 
+static int entry_put_got_frontend=0;
+static int entry_put_got_config=0;
 static ID
 config_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
 {
 	CfBackInfo *cfb = be->be_private;
 	BackendInfo *bi = cfb->cb_db.bd_info;
+	int rc;
+	struct berval rdn, vals[ 2 ];
 	ConfigArgs ca;
+	OperationBuffer opbuf;
+	Entry *ce;
+	Connection conn = {0};
+	Operation *op = NULL;
+	void *thrctx;
+	int isFrontend = 0;
 
+	/* Create entry for frontend database if it does not exist already */
+	if ( !entry_put_got_frontend ) {
+		if ( !strncmp( e->e_nname.bv_val, "olcDatabase", 
+				STRLENOF( "olcDatabase" ))) {
+			if ( strncmp( e->e_nname.bv_val + 
+					STRLENOF( "olcDatabase" ), "={-1}frontend",
+					STRLENOF( "={-1}frontend" )) && 
+					strncmp( e->e_nname.bv_val + 
+					STRLENOF( "olcDatabase" ), "=frontend",
+					STRLENOF( "=frontend" ))) {
+				vals[1].bv_len = 0;
+				vals[1].bv_val = NULL;
+				memset( &ca, 0, sizeof(ConfigArgs));
+				ca.be = frontendDB;
+				ca.bi = frontendDB->bd_info;
+				ca.be->be_cf_ocs = &CFOC_FRONTEND;
+				rdn.bv_val = ca.log;
+				rdn.bv_len = snprintf(rdn.bv_val, sizeof( ca.log ),
+					"%s=" SLAP_X_ORDERED_FMT "%s",
+					cfAd_database->ad_cname.bv_val, -1,
+					ca.bi->bi_type);
+				ce = config_build_entry( NULL, NULL, cfb->cb_root, &ca, &rdn,
+						&CFOC_DATABASE, ca.be->be_cf_ocs );
+				thrctx = ldap_pvt_thread_pool_context();
+				connection_fake_init2( &conn, &opbuf, thrctx,0 );
+				op = &opbuf.ob_op;
+				op->o_bd = &cfb->cb_db;
+				op->o_tag = LDAP_REQ_ADD;
+				op->ora_e = ce;
+				op->o_dn = be->be_rootdn;
+				op->o_ndn = be->be_rootndn;
+				rc = slap_add_opattrs(op, NULL, NULL, 0, 0);
+				if ( rc != LDAP_SUCCESS ) {
+					text->bv_val = "autocreation of \"olcDatabase={-1}frontend\" failed";
+					text->bv_len = STRLENOF("autocreation of \"olcDatabase={-1}frontend\" failed");
+					return NOID;
+				}
+
+				if ( ce && bi && bi->bi_tool_entry_put && 
+						bi->bi_tool_entry_put( &cfb->cb_db, ce, text ) != NOID ) {
+					entry_put_got_frontend++;
+				} else {
+					text->bv_val = "autocreation of \"olcDatabase={-1}frontend\" failed";
+					text->bv_len = STRLENOF("autocreation of \"olcDatabase={-1}frontend\" failed");
+					return NOID;
+				}
+			} else {
+				entry_put_got_frontend++;
+				isFrontend = 1;
+			}
+		}
+	}
+	/* Create entry for config database if it does not exist already */
+	if ( !entry_put_got_config && !isFrontend ) {
+		if ( !strncmp( e->e_nname.bv_val, "olcDatabase",
+				STRLENOF( "olcDatabase" ))) {
+			if ( strncmp( e->e_nname.bv_val +
+					STRLENOF( "olcDatabase" ), "={0}config",
+					STRLENOF( "={0}config" )) &&
+					strncmp( e->e_nname.bv_val +
+					STRLENOF( "olcDatabase" ), "=config",
+					STRLENOF( "=config" )) ) {
+				vals[1].bv_len = 0;
+				vals[1].bv_val = NULL;
+				memset( &ca, 0, sizeof(ConfigArgs));
+				ca.be = LDAP_STAILQ_FIRST( &backendDB );
+				ca.bi = ca.be->bd_info;
+				rdn.bv_val = ca.log;
+				rdn.bv_len = snprintf(rdn.bv_val, sizeof( ca.log ),
+					"%s=" SLAP_X_ORDERED_FMT "%s",
+					cfAd_database->ad_cname.bv_val, 0,
+					ca.bi->bi_type);
+				ce = config_build_entry( NULL, NULL, cfb->cb_root, &ca, &rdn, &CFOC_DATABASE,
+						ca.be->be_cf_ocs );
+				if ( ! op ) {
+					thrctx = ldap_pvt_thread_pool_context();
+					connection_fake_init2( &conn, &opbuf, thrctx,0 );
+					op = &opbuf.ob_op;
+					op->o_bd = &cfb->cb_db;
+					op->o_tag = LDAP_REQ_ADD;
+					op->o_dn = be->be_rootdn;
+					op->o_ndn = be->be_rootndn;
+				}
+				op->ora_e = ce;
+				rc = slap_add_opattrs(op, NULL, NULL, 0, 0);
+				if ( rc != LDAP_SUCCESS ) {
+					text->bv_val = "autocreation of \"olcDatabase={0}config\" failed";
+					text->bv_len = STRLENOF("autocreation of \"olcDatabase={0}config\" failed");
+					return NOID;
+				}
+				if (ce && bi && bi->bi_tool_entry_put &&
+						bi->bi_tool_entry_put( &cfb->cb_db, ce, text ) != NOID ) {
+					entry_put_got_config++;
+				} else {
+					text->bv_val = "autocreation of \"olcDatabase={0}config\" failed";
+					text->bv_len = STRLENOF("autocreation of \"olcDatabase={0}config\" failed");
+					return NOID;
+				}
+			} else {
+				entry_put_got_config++;
+			}
+		}
+	}
 	if ( bi && bi->bi_tool_entry_put &&
-		config_add_internal( cfb, e, &ca, NULL, NULL ) == 0 )
+		config_add_internal( cfb, e, &ca, NULL, NULL, NULL ) == 0 )
 		return bi->bi_tool_entry_put( &cfb->cb_db, e, text );
 	else
 		return NOID;
@@ -4772,9 +6090,12 @@
 	char *name;
 	AttributeDescription **desc;
 } ads[] = {
+	{ "attribute", &cfAd_attr },
 	{ "backend", &cfAd_backend },
 	{ "database", &cfAd_database },
 	{ "include", &cfAd_include },
+	{ "objectclass", &cfAd_oc },
+	{ "objectidentifier", &cfAd_om },
 	{ "overlay", &cfAd_overlay },
 	{ NULL, NULL }
 };
@@ -4806,6 +6127,7 @@
 config_back_initialize( BackendInfo *bi )
 {
 	ConfigTable		*ct = config_back_cf_table;
+	ConfigArgs ca;
 	char			*argv[4];
 	int			i;
 	AttributeDescription	*ad = NULL;
@@ -4815,6 +6137,9 @@
 		NULL
 	};
 
+	/* Make sure we don't exceed the bits reserved for userland */
+	config_check_userland( CFG_LAST );
+
 	bi->bi_controls = controls;
 
 	bi->bi_open = 0;
@@ -4835,20 +6160,21 @@
 	bi->bi_op_modify = config_back_modify;
 	bi->bi_op_modrdn = config_back_modrdn;
 	bi->bi_op_add = config_back_add;
-	bi->bi_op_delete = 0;
+	bi->bi_op_delete = config_back_delete;
 	bi->bi_op_abandon = 0;
 
 	bi->bi_extended = 0;
 
 	bi->bi_chk_referrals = 0;
 
-#ifdef SLAP_OVERLAY_ACCESS
-	bi->bi_access_allowed = slap_access_always_allowed;
-#endif /* SLAP_OVERLAY_ACCESS */
+	bi->bi_access_allowed = slap_access_allowed;
 
 	bi->bi_connection_init = 0;
 	bi->bi_connection_destroy = 0;
 
+	bi->bi_entry_release_rw = config_entry_release;
+	bi->bi_entry_get_rw = config_back_entry_get;
+
 	bi->bi_tool_entry_open = config_tool_entry_open;
 	bi->bi_tool_entry_close = config_tool_entry_close;
 	bi->bi_tool_entry_first = config_tool_entry_first;
@@ -4856,14 +6182,17 @@
 	bi->bi_tool_entry_get = config_tool_entry_get;
 	bi->bi_tool_entry_put = config_tool_entry_put;
 
-	/* Make sure we don't exceed the bits reserved for userland */
-	assert( ( ( CFG_LAST - 1 ) & ARGS_USERLAND ) == ( CFG_LAST - 1 ) );
+	ca.argv = argv;
+	argv[ 0 ] = "slapd";
+	ca.argv = argv;
+	ca.argc = 3;
+	ca.fname = argv[0];
 
 	argv[3] = NULL;
 	for (i=0; OidMacros[i].name; i++ ) {
 		argv[1] = OidMacros[i].name;
 		argv[2] = OidMacros[i].oid;
-		parse_oidm( "slapd", i, 3, argv, 0, NULL );
+		parse_oidm( &ca, 0, NULL );
 	}
 
 	bi->bi_cf_ocs = cf_ocs;

Modified: openldap/trunk/servers/slapd/bind.c
===================================================================
--- openldap/trunk/servers/slapd/bind.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/bind.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* bind.c - decode an ldap bind operation and pass it to a backend db */
-/* $OpenLDAP: pkg/ldap/servers/slapd/bind.c,v 1.189.2.11 2007/01/02 21:43:54 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/bind.c,v 1.201.2.3 2007/08/31 23:13:58 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -46,10 +46,11 @@
 	ber_tag_t tag;
 	Backend *be = NULL;
 
-	Debug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE, "%s do_bind\n",
+		op->o_log_prefix, 0, 0 );
 
 	/*
-	 * Force to connection to "anonymous" until bind succeeds.
+	 * Force the connection to "anonymous" until bind succeeds.
 	 */
 	ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
 	if ( op->o_conn->c_sasl_bind_in_progress ) {
@@ -86,8 +87,8 @@
 	 *		name		DistinguishedName,	 -- dn
 	 *		authentication	CHOICE {
 	 *			simple		[0] OCTET STRING -- passwd
-	 *			krbv42ldap	[1] OCTET STRING
-	 *			krbv42dsa	[2] OCTET STRING
+	 *			krbv42ldap	[1] OCTET STRING -- OBSOLETE
+	 *			krbv42dsa	[2] OCTET STRING -- OBSOLETE
 	 *			SASL		[3] SaslCredentials
 	 *		}
 	 *	}
@@ -101,7 +102,8 @@
 	tag = ber_scanf( ber, "{imt" /*}*/, &version, &dn, &method );
 
 	if ( tag == LBER_ERROR ) {
-		Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_bind: ber_scanf failed\n",
+			op->o_log_prefix, 0, 0 );
 		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
 		rs->sr_err = SLAPD_DISCONNECT;
 		goto cleanup;
@@ -134,13 +136,16 @@
 	}
 
 	if ( tag == LBER_ERROR ) {
+		Debug( LDAP_DEBUG_ANY, "%s do_bind: ber_scanf failed\n",
+			op->o_log_prefix, 0, 0 );
 		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
 		rs->sr_err = SLAPD_DISCONNECT;
 		goto cleanup;
 	}
 
 	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
-		Debug( LDAP_DEBUG_ANY, "do_bind: get_ctrls failed\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_bind: get_ctrls failed\n",
+			op->o_log_prefix, 0, 0 );
 		goto cleanup;
 	} 
 
@@ -151,14 +156,18 @@
 	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
 		op->o_tmpmemctx );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
-		Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n",
-			dn.bv_val, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_bind: invalid dn (%s)\n",
+			op->o_log_prefix, dn.bv_val, 0 );
 		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
 		goto cleanup;
 	}
 
+	Statslog( LDAP_DEBUG_STATS, "%s BIND dn=\"%s\" method=%ld\n",
+	    op->o_log_prefix, op->o_req_dn.bv_val,
+		(unsigned long) op->orb_method, 0, 0 );
+
 	if( op->orb_method == LDAP_AUTH_SASL ) {
-		Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n",
+		Debug( LDAP_DEBUG_TRACE, "do_bind: dn (%s) SASL mech %s\n",
 			op->o_req_dn.bv_val, mech.bv_val, NULL );
 
 	} else {
@@ -168,13 +177,9 @@
 			(unsigned long) op->orb_method );
 	}
 
-	Statslog( LDAP_DEBUG_STATS, "%s BIND dn=\"%s\" method=%ld\n",
-	    op->o_log_prefix, op->o_req_dn.bv_val,
-		(unsigned long) op->orb_method, 0, 0 );
-
 	if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
-		Debug( LDAP_DEBUG_ANY, "do_bind: unknown version=%ld\n",
-			(unsigned long) version, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_bind: unknown version=%ld\n",
+			op->o_log_prefix, (unsigned long) version, 0 );
 		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
 			"requested protocol version not supported" );
 		goto cleanup;
@@ -194,7 +199,7 @@
 	op->o_conn->c_protocol = version;
 	ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
-	op->orb_tmp_mech = mech;
+	op->orb_mech = mech;
 
 	op->o_bd = frontendDB;
 	rs->sr_err = frontendDB->be_bind( op, rs );
@@ -222,7 +227,6 @@
 int
 fe_op_bind( Operation *op, SlapReply *rs )
 {
-	struct berval	mech = op->orb_tmp_mech;
 	BackendDB	*bd = op->o_bd;
 
 	/* check for inappropriate controls */
@@ -243,7 +247,7 @@
 			goto cleanup;
 		}
 
-		if( BER_BVISNULL( &mech ) || BER_BVISEMPTY( &mech ) ) {
+		if( BER_BVISNULL( &op->orb_mech ) || BER_BVISEMPTY( &op->orb_mech ) ) {
 			Debug( LDAP_DEBUG_ANY,
 				"do_bind: no sasl mechanism provided\n",
 				0, 0, 0 );
@@ -253,21 +257,21 @@
 		}
 
 		/* check restrictions */
-		if( backend_check_restrictions( op, rs, &mech ) != LDAP_SUCCESS ) {
+		if( backend_check_restrictions( op, rs, &op->orb_mech ) != LDAP_SUCCESS ) {
 			send_ldap_result( op, rs );
 			goto cleanup;
 		}
 
 		ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
 		if ( op->o_conn->c_sasl_bind_in_progress ) {
-			if( !bvmatch( &op->o_conn->c_sasl_bind_mech, &mech ) ) {
+			if( !bvmatch( &op->o_conn->c_sasl_bind_mech, &op->orb_mech ) ) {
 				/* mechanism changed between bind steps */
 				slap_sasl_reset(op->o_conn);
 			}
 		} else {
-			ber_dupbv(&op->o_conn->c_sasl_bind_mech, &mech);
+			ber_dupbv(&op->o_conn->c_sasl_bind_mech, &op->orb_mech);
 		}
-	
+
 		/* Set the bindop for the benefit of in-directory SASL lookups */
 		op->o_conn->c_sasl_bindop = op;
 
@@ -292,7 +296,7 @@
 	}
 
 	if ( op->orb_method == LDAP_AUTH_SIMPLE ) {
-		BER_BVSTR( &mech, "SIMPLE" );
+		BER_BVSTR( &op->orb_mech, "SIMPLE" );
 		/* accept "anonymous" binds */
 		if ( BER_BVISEMPTY( &op->orb_cred ) || BER_BVISEMPTY( &op->o_req_ndn ) ) {
 			rs->sr_err = LDAP_SUCCESS;
@@ -317,7 +321,7 @@
 				rs->sr_text = "anonymous bind disallowed";
 
 			} else {
-				backend_check_restrictions( op, rs, &mech );
+				backend_check_restrictions( op, rs, &op->orb_mech );
 			}
 
 			/*
@@ -341,33 +345,6 @@
 			goto cleanup;
 		}
 
-#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
-	} else if ( op->orb_method == LDAP_AUTH_KRBV41 ) {
-		if ( global_disallows & SLAP_DISALLOW_BIND_KRBV4 ) {
-			/* disallow krbv4 authentication */
-			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-			rs->sr_text = "unwilling to perform Kerberos V4 bind";
-
-			send_ldap_result( op, rs );
-
-			Debug( LDAP_DEBUG_TRACE,
-				"do_bind: v%d Kerberos V4 (step 1) bind refused\n",
-				op->o_protocol, 0, 0 );
-			goto cleanup;
-		}
-		BER_BVSTR( &mech, "KRBV4" );
-
-	} else if ( op->orb_method == LDAP_AUTH_KRBV42 ) {
-		rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED;
-		rs->sr_text = "Kerberos V4 (step 2) bind not supported";
-		send_ldap_result( op, rs );
-
-		Debug( LDAP_DEBUG_TRACE,
-			"do_bind: v%d Kerberos V4 (step 2) bind refused\n",
-			op->o_protocol, 0, 0 );
-		goto cleanup;
-#endif
-
 	} else {
 		rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED;
 		rs->sr_text = "unknown authentication method";
@@ -381,10 +358,11 @@
 
 	/*
 	 * We could be serving multiple database backends.  Select the
-	 * appropriate one.  If none, return invalid cred, not a referral.
+	 * appropriate one, or send a referral to our "referral server"
+	 * if we don't hold it.
 	 */
 
-	if ( (op->o_bd = select_backend( &op->o_req_ndn, 0, 0 )) == NULL ) {
+	if ( (op->o_bd = select_backend( &op->o_req_ndn, 0 )) == NULL ) {
 		/* don't return referral for bind requests */
 		/* noSuchObject is not allowed to be returned by bind */
 		rs->sr_err = LDAP_INVALID_CREDENTIALS;
@@ -405,42 +383,8 @@
 		rs->sr_err = (op->o_bd->be_bind)( op, rs );
 
 		if ( rs->sr_err == 0 ) {
-			ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
+			(void)fe_op_bind_success( op, rs );
 
-			if( op->o_conn->c_authz_backend == NULL ) {
-				op->o_conn->c_authz_backend = op->o_bd;
-			}
-
-			/* be_bind returns regular/global edn */
-			if( !BER_BVISEMPTY( &op->orb_edn ) ) {
-				op->o_conn->c_dn = op->orb_edn;
-			} else {
-				ber_dupbv(&op->o_conn->c_dn, &op->o_req_dn);
-			}
-
-			ber_dupbv( &op->o_conn->c_ndn, &op->o_req_ndn );
-
-			if( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
-				ber_len_t max = sockbuf_max_incoming_auth;
-				ber_sockbuf_ctrl( op->o_conn->c_sb,
-					LBER_SB_OPT_SET_MAX_INCOMING, &max );
-			}
-
-			/* log authorization identity */
-			Statslog( LDAP_DEBUG_STATS,
-				"%s BIND dn=\"%s\" mech=%s ssf=0\n",
-				op->o_log_prefix,
-				op->o_conn->c_dn.bv_val, mech.bv_val, 0, 0 );
-
-			Debug( LDAP_DEBUG_TRACE,
-				"do_bind: v%d bind: \"%s\" to \"%s\"\n",
-				op->o_protocol, op->o_req_dn.bv_val, op->o_conn->c_dn.bv_val );
-
-			ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
-
-			/* send this here to avoid a race condition */
-			send_ldap_result( op, rs );
-
 		} else if ( !BER_BVISNULL( &op->orb_edn ) ) {
 			free( op->orb_edn.bv_val );
 			BER_BVZERO( &op->orb_edn );
@@ -456,3 +400,44 @@
 	return rs->sr_err;
 }
 
+int
+fe_op_bind_success( Operation *op, SlapReply *rs )
+{
+	ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
+
+	if( op->o_conn->c_authz_backend == NULL ) {
+		op->o_conn->c_authz_backend = op->o_bd;
+	}
+
+	/* be_bind returns regular/global edn */
+	if( !BER_BVISEMPTY( &op->orb_edn ) ) {
+		op->o_conn->c_dn = op->orb_edn;
+	} else {
+		ber_dupbv(&op->o_conn->c_dn, &op->o_req_dn);
+	}
+
+	ber_dupbv( &op->o_conn->c_ndn, &op->o_req_ndn );
+
+	if( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
+		ber_len_t max = sockbuf_max_incoming_auth;
+		ber_sockbuf_ctrl( op->o_conn->c_sb,
+			LBER_SB_OPT_SET_MAX_INCOMING, &max );
+	}
+
+	/* log authorization identity */
+	Statslog( LDAP_DEBUG_STATS,
+		"%s BIND dn=\"%s\" mech=%s ssf=0\n",
+		op->o_log_prefix,
+		op->o_conn->c_dn.bv_val, op->orb_mech.bv_val, 0, 0 );
+
+	Debug( LDAP_DEBUG_TRACE,
+		"do_bind: v%d bind: \"%s\" to \"%s\"\n",
+		op->o_protocol, op->o_req_dn.bv_val, op->o_conn->c_dn.bv_val );
+
+	ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
+
+	/* send this here to avoid a race condition */
+	send_ldap_result( op, rs );
+
+	return LDAP_SUCCESS;
+}

Modified: openldap/trunk/servers/slapd/cancel.c
===================================================================
--- openldap/trunk/servers/slapd/cancel.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/cancel.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* cancel.c - LDAP cancel extended operation */
-/* $OpenLDAP: pkg/ldap/servers/slapd/cancel.c,v 1.16.2.7 2007/01/02 21:43:54 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/cancel.c,v 1.23.2.3 2007/11/07 20:58:38 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -18,7 +18,6 @@
 
 #include <stdio.h>
 
-#include <ac/krb.h>
 #include <ac/socket.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
@@ -28,6 +27,8 @@
 #include <lber_pvt.h>
 #include <lutil.h>
 
+const struct berval slap_EXOP_CANCEL = BER_BVC(LDAP_EXOP_CANCEL);
+
 int cancel_extop( Operation *op, SlapReply *rs )
 {
 	Operation *o;
@@ -55,21 +56,21 @@
 
 	(void) ber_free( ber, 1 );
 
+	Statslog( LDAP_DEBUG_STATS, "%s CANCEL msg=%d\n",
+		op->o_log_prefix, opid, 0, 0, 0 );
+
 	if ( opid < 0 ) {
 		rs->sr_text = "message ID invalid";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	Statslog( LDAP_DEBUG_STATS, "%s CANCEL msg=%d\n",
-		op->o_log_prefix, opid, 0, 0, 0 );
-
 	ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
 	LDAP_STAILQ_FOREACH( o, &op->o_conn->c_pending_ops, o_next ) {
 		if ( o->o_msgid == opid ) {
-			LDAP_STAILQ_REMOVE( &op->o_conn->c_pending_ops, o, slap_op, o_next );
+			LDAP_STAILQ_REMOVE( &op->o_conn->c_pending_ops, o, Operation, o_next );
 			LDAP_STAILQ_NEXT(o, o_next) = NULL;
 			op->o_conn->c_n_ops_pending--;
-			slap_op_free( o );
+			slap_op_free( o, NULL );
 			ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 			return LDAP_SUCCESS;
 		}

Modified: openldap/trunk/servers/slapd/ch_malloc.c
===================================================================
--- openldap/trunk/servers/slapd/ch_malloc.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/ch_malloc.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ch_malloc.c - malloc routines that test returns from malloc and friends */
-/* $OpenLDAP: pkg/ldap/servers/slapd/ch_malloc.c,v 1.25.2.4 2007/01/02 21:43:54 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/ch_malloc.c,v 1.28.2.2 2007/08/31 23:13:58 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/compare.c
===================================================================
--- openldap/trunk/servers/slapd/compare.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/compare.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/compare.c,v 1.124.2.11 2007/01/02 21:43:54 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/compare.c,v 1.136.2.7 2007/09/29 09:55:21 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -44,15 +44,10 @@
 	struct berval dn = BER_BVNULL;
 	struct berval desc = BER_BVNULL;
 	struct berval value = BER_BVNULL;
-#ifdef LDAP_COMP_MATCH
-	AttributeAssertion ava = { NULL, BER_BVNULL, NULL };
-#else
-	AttributeAssertion ava = { NULL, BER_BVNULL };
-#endif
+	AttributeAssertion ava = ATTRIBUTEASSERTION_INIT;
 
-	ava.aa_desc = NULL;
-
-	Debug( LDAP_DEBUG_TRACE, "do_compare\n", 0, 0, 0 );
+	Debug( LDAP_DEBUG_TRACE, "%s do_compare\n",
+		op->o_log_prefix, 0, 0 );
 	/*
 	 * Parse the compare request.  It looks like this:
 	 *
@@ -66,37 +61,46 @@
 	 */
 
 	if ( ber_scanf( op->o_ber, "{m" /*}*/, &dn ) == LBER_ERROR ) {
-		Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_compare: ber_scanf failed\n",
+			op->o_log_prefix, 0, 0 );
 		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
 		return SLAPD_DISCONNECT;
 	}
 
 	if ( ber_scanf( op->o_ber, "{mm}", &desc, &value ) == LBER_ERROR ) {
-		Debug( LDAP_DEBUG_ANY, "do_compare: get ava failed\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_compare: get ava failed\n",
+			op->o_log_prefix, 0, 0 );
 		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
 		return SLAPD_DISCONNECT;
 	}
 
 	if ( ber_scanf( op->o_ber, /*{*/ "}" ) == LBER_ERROR ) {
-		Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_compare: ber_scanf failed\n",
+			op->o_log_prefix, 0, 0 );
 		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
 		return SLAPD_DISCONNECT;
 	}
 
 	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
-		Debug( LDAP_DEBUG_ANY, "do_compare: get_ctrls failed\n", 0, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_compare: get_ctrls failed\n",
+			op->o_log_prefix, 0, 0 );
 		goto cleanup;
 	} 
 
 	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
 		op->o_tmpmemctx );
 	if( rs->sr_err != LDAP_SUCCESS ) {
-		Debug( LDAP_DEBUG_ANY,
-			"do_compare: invalid dn (%s)\n", dn.bv_val, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "%s do_compare: invalid dn (%s)\n",
+			op->o_log_prefix, dn.bv_val, 0 );
 		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
 		goto cleanup;
 	}
 
+	Statslog( LDAP_DEBUG_STATS,
+		"%s CMP dn=\"%s\" attr=\"%s\"\n",
+		op->o_log_prefix, op->o_req_dn.bv_val,
+		desc.bv_val, 0, 0 );
+
 	rs->sr_err = slap_bv2ad( &desc, &ava.aa_desc, &rs->sr_text );
 	if( rs->sr_err != LDAP_SUCCESS ) {
 		rs->sr_err = slap_bv2undef_ad( &desc, &ava.aa_desc,
@@ -119,6 +123,11 @@
 
 	op->orc_ava = &ava;
 
+	Debug( LDAP_DEBUG_ARGS,
+		"do_compare: dn (%s) attr (%s) value (%s)\n",
+		op->o_req_dn.bv_val,
+		ava.aa_desc->ad_cname.bv_val, ava.aa_value.bv_val );
+
 	op->o_bd = frontendDB;
 	rs->sr_err = frontendDB->be_compare( op, rs );
 
@@ -135,22 +144,11 @@
 int
 fe_op_compare( Operation *op, SlapReply *rs )
 {
-	Entry *entry = NULL;
-	int manageDSAit;
-	AttributeAssertion ava = *op->orc_ava;
-	BackendDB	*bd = op->o_bd;
+	Entry			*entry = NULL;
+	AttributeAssertion	*ava = op->orc_ava;
+	BackendDB		*bd = op->o_bd;
 
 	if( strcasecmp( op->o_req_ndn.bv_val, LDAP_ROOT_DSE ) == 0 ) {
-		Debug( LDAP_DEBUG_ARGS,
-			"do_compare: dn (%s) attr (%s) value (%s)\n",
-			op->o_req_dn.bv_val,
-			ava.aa_desc->ad_cname.bv_val, ava.aa_value.bv_val );
-
-		Statslog( LDAP_DEBUG_STATS,
-			"%s CMP dn=\"%s\" attr=\"%s\"\n",
-			op->o_log_prefix, op->o_req_dn.bv_val,
-			ava.aa_desc->ad_cname.bv_val, 0, 0 );
-
 		if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
 			send_ldap_result( op, rs );
 			goto cleanup;
@@ -163,15 +161,6 @@
 		}
 
 	} else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) {
-		Debug( LDAP_DEBUG_ARGS, "do_compare: dn (%s) attr (%s) value (%s)\n",
-			op->o_req_dn.bv_val,
-			ava.aa_desc->ad_cname.bv_val, ava.aa_value.bv_val );
-
-		Statslog( LDAP_DEBUG_STATS,
-			"%s CMP dn=\"%s\" attr=\"%s\"\n",
-			op->o_log_prefix, op->o_req_dn.bv_val,
-			ava.aa_desc->ad_cname.bv_val, 0, 0 );
-
 		if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
 			send_ldap_result( op, rs );
 			rs->sr_err = 0;
@@ -187,7 +176,7 @@
 	}
 
 	if( entry ) {
-		rs->sr_err = compare_entry( op, entry, &ava );
+		rs->sr_err = compare_entry( op, entry, ava );
 		entry_free( entry );
 
 		send_ldap_result( op, rs );
@@ -201,14 +190,12 @@
 		goto cleanup;
 	}
 
-	manageDSAit = get_manageDSAit( op );
-
 	/*
 	 * We could be serving multiple database backends.  Select the
 	 * appropriate one, or send a referral to our "referral server"
 	 * if we don't hold it.
 	 */
-	op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 );
+	op->o_bd = select_backend( &op->o_req_ndn, 0 );
 	if ( op->o_bd == NULL ) {
 		rs->sr_ref = referral_rewrite( default_referral,
 			NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
@@ -234,25 +221,21 @@
 		goto cleanup;
 	}
 
-	Debug( LDAP_DEBUG_ARGS, "do_compare: dn (%s) attr (%s) value (%s)\n",
-	    op->o_req_dn.bv_val,
-		ava.aa_desc->ad_cname.bv_val, ava.aa_value.bv_val );
+	if ( SLAP_SHADOW(op->o_bd) && get_dontUseCopy(op) ) {
+		/* don't use shadow copy */
+		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
+			"copy not used" );
 
-	Statslog( LDAP_DEBUG_STATS, "%s CMP dn=\"%s\" attr=\"%s\"\n",
-		op->o_log_prefix, op->o_req_dn.bv_val,
-		ava.aa_desc->ad_cname.bv_val, 0, 0 );
-
-	op->orc_ava = &ava;
-	if ( ava.aa_desc == slap_schema.si_ad_entryDN ) {
+	} else if ( ava->aa_desc == slap_schema.si_ad_entryDN ) {
 		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
 			"entryDN compare not supported" );
 
-	} else if ( ava.aa_desc == slap_schema.si_ad_subschemaSubentry ) {
+	} else if ( ava->aa_desc == slap_schema.si_ad_subschemaSubentry ) {
 		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
 			"subschemaSubentry compare not supported" );
 
 #ifndef SLAP_COMPARE_IN_FRONTEND
-	} else if ( ava.aa_desc == slap_schema.si_ad_hasSubordinates
+	} else if ( ava->aa_desc == slap_schema.si_ad_hasSubordinates
 		&& op->o_bd->be_has_subordinates )
 	{
 		int	rc, hasSubordinates = LDAP_SUCCESS;
@@ -260,7 +243,7 @@
 		rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &entry );
 		if ( rc == 0 && entry ) {
 			if ( ! access_allowed( op, entry,
-				ava.aa_desc, &ava.aa_value, ACL_COMPARE, NULL ) )
+				ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
 			{	
 				rc = rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
 				
@@ -274,7 +257,7 @@
 		if ( rc == 0 ) {
 			int	asserted;
 
-			asserted = bvmatch( &ava.aa_value, &slap_true_bv )
+			asserted = bvmatch( &ava->aa_value, &slap_true_bv )
 				? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
 			if ( hasSubordinates == asserted ) {
 				rs->sr_err = LDAP_COMPARE_TRUE;
@@ -284,7 +267,6 @@
 			}
 
 		} else {
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 			/* return error only if "disclose"
 			 * is granted on the object */
 			if ( backend_access( op, NULL, &op->o_req_ndn,
@@ -293,7 +275,6 @@
 			{
 				rs->sr_err = LDAP_NO_SUCH_OBJECT;
 			}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 		}
 
 		send_ldap_result( op, rs );
@@ -325,10 +306,9 @@
 		int		rc = LDAP_OTHER;
 
 		rs->sr_err = backend_attribute( op, NULL, &op->o_req_ndn,
-				ava.aa_desc, &vals, ACL_COMPARE );
+				ava->aa_desc, &vals, ACL_COMPARE );
 		switch ( rs->sr_err ) {
 		default:
-#ifdef SLAP_ACL_HONOR_DISCLOSE
 			/* return error only if "disclose"
 			 * is granted on the object */
 			if ( backend_access( op, NULL, &op->o_req_ndn,
@@ -338,14 +318,13 @@
 			{
 				rs->sr_err = LDAP_NO_SUCH_OBJECT;
 			}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
 			break;
 
 		case LDAP_SUCCESS:
 			if ( value_find_ex( op->oq_compare.rs_ava->aa_desc,
 				SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
 					SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-				vals, &ava.aa_value, op->o_tmpmemctx ) == 0 )
+				vals, &ava->aa_value, op->o_tmpmemctx ) == 0 )
 			{
 				rs->sr_err = LDAP_COMPARE_TRUE;
 				break;
@@ -405,10 +384,10 @@
 			break;
 		}
 
-		if ( value_find_ex( ava->aa_desc,
+		if ( attr_valfind( a, 
 			SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
 				SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-			a->a_nvals, &ava->aa_value, op->o_tmpmemctx ) == 0 )
+			&ava->aa_value, NULL, op->o_tmpmemctx ) == 0 )
 		{
 			rc = LDAP_COMPARE_TRUE;
 			break;
@@ -416,7 +395,6 @@
 	}
 
 done:
-#ifdef LDAP_ACL_HONOR_DISCLOSE
 	if( rc != LDAP_COMPARE_TRUE && rc != LDAP_COMPARE_FALSE ) {
 		if ( ! access_allowed( op, e,
 			slap_schema.si_ad_entry, NULL, ACL_DISCLOSE, NULL ) )
@@ -424,7 +402,6 @@
 			rc = LDAP_NO_SUCH_OBJECT;
 		}
 	}
-#endif
 
 	return rc;
 }

Modified: openldap/trunk/servers/slapd/component.c
===================================================================
--- openldap/trunk/servers/slapd/component.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/component.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* component.c -- Component Filter Match Routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/component.c,v 1.13.2.7 2007/01/02 21:43:55 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/component.c,v 1.31.2.2 2007/08/31 23:13:58 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -179,7 +179,7 @@
 		ci_curr = ci_curr->ci_next, ci_temp = &(*ci_temp)->ci_next )
 	{
 		*ci_temp = op->o_tmpalloc( sizeof( ComponentId ), op->o_tmpmemctx );
-		if ( !ci_temp ) return NULL;
+		if ( !*ci_temp ) return NULL;
 		**ci_temp = *ci_curr;
 	}
 
@@ -580,6 +580,11 @@
 			cr_list = &(*cr_list)->ci_next;
 
 		} else if ( rc == LDAP_COMPREF_UNDEFINED ) {
+			if ( op ) {
+				op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
+			} else {
+				free( ca_comp_ref );
+			}
 			return rc;
 		}
 	}
@@ -594,17 +599,9 @@
 		return rc;
 	}
 
-	if ( rc == LDAP_SUCCESS ) {	
-		*cr = ca_comp_ref;
-		**cr = *ca_comp_ref;	
+	*cr = ca_comp_ref;
+	**cr = *ca_comp_ref;	
 
-	} else if ( op ) {
-		 op->o_tmpfree( ca_comp_ref , op->o_tmpmemctx );
-
-	} else {
-		 free( ca_comp_ref ) ;
-	}
-
 	(*cr)->cr_string.bv_val = start;
 	(*cr)->cr_string.bv_len = end - start + 1;
 	
@@ -1076,7 +1073,7 @@
 	ber_tag_t	tag;
 	int		err;
 	ComponentFilter	f;
-	/* TAG : item, and, or, not in RFC 2254 */
+	/* TAG : item, and, or, not in RFC 4515 */
 	tag = strip_cav_tag( cav );
 
 	if ( tag == LBER_ERROR ) {

Modified: openldap/trunk/servers/slapd/component.h
===================================================================
--- openldap/trunk/servers/slapd/component.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/component.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* component.h */
-/* $OpenLDAP: pkg/ldap/servers/slapd/component.h,v 1.1.2.4 2007/01/02 21:43:55 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/component.h,v 1.4.2.2 2007/08/31 23:13:58 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2004-2007 The OpenLDAP Foundation.

Modified: openldap/trunk/servers/slapd/config.c
===================================================================
--- openldap/trunk/servers/slapd/config.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/config.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* config.c - configuration file handling routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/config.c,v 1.341.2.26 2007/09/02 11:51:09 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/config.c,v 1.441.2.10 2007/11/08 19:30:04 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -36,13 +36,21 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+
+#ifndef S_ISREG
+#define	S_ISREG(m)	(((m) & _S_IFMT) == _S_IFREG)
+#endif
+
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 
 #include "slap.h"
 #ifdef LDAP_SLAPI
 #include "slapi/slapi.h"
 #endif
 #include "lutil.h"
+#include "lutil_ldap.h"
 #include "config.h"
 
 #define ARGS_STEP	512
@@ -56,7 +64,7 @@
 int		global_idletimeout = 0;
 char	*global_host = NULL;
 char	*global_realm = NULL;
-char		*ldap_srvtab = "";
+char	*sasl_host = NULL;
 char		**default_passwd_hash = NULL;
 struct berval default_search_base = BER_BVNULL;
 struct berval default_search_nbase = BER_BVNULL;
@@ -116,109 +124,139 @@
 }
 
 int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
-	int rc, arg_user, arg_type, iarg;
+	int rc, arg_user, arg_type, arg_syn, iarg;
+	unsigned uiarg;
 	long larg;
 	ber_len_t barg;
 	
-	arg_type = Conf->arg_type;
-	if(arg_type == ARG_IGNORED) {
+	if(Conf->arg_type == ARG_IGNORED) {
 		Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> ignored\n",
 			c->log, Conf->name, 0);
 		return(0);
 	}
-	if((arg_type & ARG_DN) && c->argc == 1) {
+	arg_type = Conf->arg_type & ARGS_TYPES;
+	arg_user = Conf->arg_type & ARGS_USERLAND;
+	arg_syn = Conf->arg_type & ARGS_SYNTAX;
+
+	if((arg_type == ARG_DN) && c->argc == 1) {
 		c->argc = 2;
 		c->argv[1] = "";
 	}
 	if(Conf->min_args && (c->argc < Conf->min_args)) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> missing <%s> argument",
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> missing <%s> argument",
 			c->argv[0], Conf->what );
-		Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n", c->log, c->msg, 0 );
+		Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: keyword %s\n", c->log, c->cr_msg, 0 );
 		return(ARG_BAD_CONF);
 	}
 	if(Conf->max_args && (c->argc > Conf->max_args)) {
 		char	*ignored = " ignored";
 
-		snprintf( c->msg, sizeof( c->msg ), "<%s> extra cruft after <%s>",
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> extra cruft after <%s>",
 			c->argv[0], Conf->what );
 
-#ifdef LDAP_DEVEL
 		ignored = "";
-#endif /* LDAP_DEVEL */
-		Debug(LDAP_DEBUG_CONFIG, "%s: %s%s.\n",
-				c->log, c->msg, ignored );
-#ifdef LDAP_DEVEL
+		Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s%s.\n",
+				c->log, c->cr_msg, ignored );
 		return(ARG_BAD_CONF);
-#endif /* LDAP_DEVEL */
 	}
-	if((arg_type & ARG_DB) && !c->be) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> only allowed within database declaration",
+	if((arg_syn & ARG_DB) && !c->be) {
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> only allowed within database declaration",
 			c->argv[0] );
-		Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n",
-			c->log, c->msg, 0);
+		Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: keyword %s\n",
+			c->log, c->cr_msg, 0);
 		return(ARG_BAD_CONF);
 	}
-	if((arg_type & ARG_PRE_BI) && c->bi) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> must occur before any backend %sdeclaration",
-			c->argv[0], (arg_type & ARG_PRE_DB) ? "or database " : "" );
-		Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n",
-			c->log, c->msg, 0 );
+	if((arg_syn & ARG_PRE_BI) && c->bi) {
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> must occur before any backend %sdeclaration",
+			c->argv[0], (arg_syn & ARG_PRE_DB) ? "or database " : "" );
+		Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: keyword %s\n",
+			c->log, c->cr_msg, 0 );
 		return(ARG_BAD_CONF);
 	}
-	if((arg_type & ARG_PRE_DB) && c->be && c->be != frontendDB) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> must occur before any database declaration",
+	if((arg_syn & ARG_PRE_DB) && c->be && c->be != frontendDB) {
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> must occur before any database declaration",
 			c->argv[0] );
-		Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n",
-			c->log, c->msg, 0);
+		Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: keyword %s\n",
+			c->log, c->cr_msg, 0);
 		return(ARG_BAD_CONF);
 	}
-	if((arg_type & ARG_PAREN) && *c->argv[1] != '(' /*')'*/) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> old format not supported", c->argv[0] );
-		Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
-			c->log, c->msg, 0);
+	if((arg_syn & ARG_PAREN) && *c->argv[1] != '(' /*')'*/) {
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> old format not supported", c->argv[0] );
+		Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n",
+			c->log, c->cr_msg, 0);
 		return(ARG_BAD_CONF);
 	}
-	if((arg_type & ARGS_POINTER) && !Conf->arg_item && !(arg_type & ARG_OFFSET)) {
-		snprintf( c->msg, sizeof( c->msg ), "<%s> invalid config_table, arg_item is NULL",
+	if(arg_type && !Conf->arg_item && !(arg_syn & ARG_OFFSET)) {
+		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid config_table, arg_item is NULL",
 			c->argv[0] );
-		Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
-			c->log, c->msg, 0);
+		Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n",
+			c->log, c->cr_msg, 0);
 		return(ARG_BAD_CONF);
 	}
-	c->type = arg_user = (arg_type & ARGS_USERLAND);
+	c->type = arg_user;
 	memset(&c->values, 0, sizeof(c->values));
-	if(arg_type & ARGS_NUMERIC) {
+	if(arg_type == ARG_STRING) {
+		if ( !check_only )
+			c->value_string = ch_strdup(c->argv[1]);
+	} else if(arg_type == ARG_BERVAL) {
+		if ( !check_only )
+			ber_str2bv( c->argv[1], 0, 1, &c->value_bv );
+	} else if(arg_type == ARG_DN) {
+		struct berval bv;
+		ber_str2bv( c->argv[1], 0, 0, &bv );
+		rc = dnPrettyNormal( NULL, &bv, &c->value_dn, &c->value_ndn, NULL );
+		if ( rc != LDAP_SUCCESS ) {
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid DN %d (%s)",
+				c->argv[0], rc, ldap_err2string( rc ));
+			Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n" , c->log, c->cr_msg, 0);
+			return(ARG_BAD_CONF);
+		}
+		if ( check_only ) {
+			ch_free( c->value_ndn.bv_val );
+			ch_free( c->value_dn.bv_val );
+		}
+	} else {	/* all numeric */
 		int j;
 		iarg = 0; larg = 0; barg = 0;
-		switch(arg_type & ARGS_NUMERIC) {
+		switch(arg_type) {
 			case ARG_INT:
 				if ( lutil_atoix( &iarg, c->argv[1], 0 ) != 0 ) {
-					snprintf( c->msg, sizeof( c->msg ),
+					snprintf( c->cr_msg, sizeof( c->cr_msg ),
 						"<%s> unable to parse \"%s\" as int",
 						c->argv[0], c->argv[1] );
-					Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
-						c->log, c->msg, 0);
+					Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n",
+						c->log, c->cr_msg, 0);
 					return(ARG_BAD_CONF);
 				}
 				break;
+			case ARG_UINT:
+				if ( lutil_atoux( &uiarg, c->argv[1], 0 ) != 0 ) {
+					snprintf( c->cr_msg, sizeof( c->cr_msg ),
+						"<%s> unable to parse \"%s\" as unsigned int",
+						c->argv[0], c->argv[1] );
+					Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n",
+						c->log, c->cr_msg, 0);
+					return(ARG_BAD_CONF);
+				}
+				break;
 			case ARG_LONG:
 				if ( lutil_atolx( &larg, c->argv[1], 0 ) != 0 ) {
-					snprintf( c->msg, sizeof( c->msg ),
+					snprintf( c->cr_msg, sizeof( c->cr_msg ),
 						"<%s> unable to parse \"%s\" as long",
 						c->argv[0], c->argv[1] );
-					Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
-						c->log, c->msg, 0);
+					Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n",
+						c->log, c->cr_msg, 0);
 					return(ARG_BAD_CONF);
 				}
 				break;
 			case ARG_BER_LEN_T: {
 				unsigned long	l;
 				if ( lutil_atoulx( &l, c->argv[1], 0 ) != 0 ) {
-					snprintf( c->msg, sizeof( c->msg ),
+					snprintf( c->cr_msg, sizeof( c->cr_msg ),
 						"<%s> unable to parse \"%s\" as ber_len_t",
 						c->argv[0], c->argv[1] );
-					Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
-						c->log, c->msg, 0);
+					Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n",
+						c->log, c->cr_msg, 0);
 					return(ARG_BAD_CONF);
 				}
 				barg = (ber_len_t)l;
@@ -237,49 +275,30 @@
 				{
 					iarg = 0;
 				} else {
-					snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value, ignored",
+					snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value",
 						c->argv[0] );
-					Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
-						c->log, c->msg, 0 );
-					return(0);
+					Debug(LDAP_DEBUG_ANY|LDAP_DEBUG_NONE, "%s: %s\n",
+						c->log, c->cr_msg, 0 );
+					return(ARG_BAD_CONF);
 				}
 				break;
 		}
 		j = (arg_type & ARG_NONZERO) ? 1 : 0;
 		if(iarg < j && larg < j && barg < j ) {
 			larg = larg ? larg : (barg ? barg : iarg);
-			snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value, ignored",
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value",
 				c->argv[0] );
-			Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
-				c->log, c->msg, 0 );
+			Debug(LDAP_DEBUG_ANY|LDAP_DEBUG_NONE, "%s: %s\n",
+				c->log, c->cr_msg, 0 );
 			return(ARG_BAD_CONF);
 		}
-		switch(arg_type & ARGS_NUMERIC) {
+		switch(arg_type) {
 			case ARG_ON_OFF:
 			case ARG_INT:		c->value_int = iarg;		break;
+			case ARG_UINT:		c->value_uint = uiarg;		break;
 			case ARG_LONG:		c->value_long = larg;		break;
 			case ARG_BER_LEN_T:	c->value_ber_t = barg;		break;
 		}
-	} else if(arg_type & ARG_STRING) {
-		if ( !check_only )
-			c->value_string = ch_strdup(c->argv[1]);
-	} else if(arg_type & ARG_BERVAL) {
-		if ( !check_only )
-			ber_str2bv( c->argv[1], 0, 1, &c->value_bv );
-	} else if(arg_type & ARG_DN) {
-		struct berval bv;
-		ber_str2bv( c->argv[1], 0, 0, &bv );
-		rc = dnPrettyNormal( NULL, &bv, &c->value_dn, &c->value_ndn, NULL );
-		if ( rc != LDAP_SUCCESS ) {
-			snprintf( c->msg, sizeof( c->msg ), "<%s> invalid DN %d (%s)",
-				c->argv[0], rc, ldap_err2string( rc ));
-			Debug(LDAP_DEBUG_CONFIG, "%s: %s\n" , c->log, c->msg, 0);
-			return(ARG_BAD_CONF);
-		}
-		if ( check_only ) {
-			ch_free( c->value_ndn.bv_val );
-			ch_free( c->value_dn.bv_val );
-		}
 	}
 	return 0;
 }
@@ -291,17 +310,17 @@
 	arg_type = Conf->arg_type;
 	if(arg_type & ARG_MAGIC) {
 		if(!c->be) c->be = frontendDB;
-		c->msg[0] = '\0';
+		c->cr_msg[0] = '\0';
 		rc = (*((ConfigDriver*)Conf->arg_item))(c);
 #if 0
 		if(c->be == frontendDB) c->be = NULL;
 #endif
 		if(rc) {
-			if ( !c->msg[0] ) {
-				snprintf( c->msg, sizeof( c->msg ), "<%s> handler exited with %d",
+			if ( !c->cr_msg[0] ) {
+				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> handler exited with %d",
 					c->argv[0], rc );
 				Debug(LDAP_DEBUG_CONFIG, "%s: %s!\n",
-					c->log, c->msg, 0 );
+					c->log, c->cr_msg, 0 );
 			}
 			return(ARG_BAD_CONF);
 		}
@@ -313,20 +332,21 @@
 		else if (c->bi)
 			ptr = c->bi->bi_private;
 		else {
-			snprintf( c->msg, sizeof( c->msg ), "<%s> offset is missing base pointer",
+			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> offset is missing base pointer",
 				c->argv[0] );
 			Debug(LDAP_DEBUG_CONFIG, "%s: %s!\n",
-				c->log, c->msg, 0);
+				c->log, c->cr_msg, 0);
 			return(ARG_BAD_CONF);
 		}
 		ptr = (void *)((char *)ptr + (long)Conf->arg_item);
-	} else if (arg_type & ARGS_POINTER) {
+	} else if (arg_type & ARGS_TYPES) {
 		ptr = Conf->arg_item;
 	}
-	if(arg_type & ARGS_POINTER)
-		switch(arg_type & ARGS_POINTER) {
+	if(arg_type & ARGS_TYPES)
+		switch(arg_type & ARGS_TYPES) {
 			case ARG_ON_OFF:
 			case ARG_INT: 		*(int*)ptr = c->value_int;			break;
+			case ARG_UINT: 		*(unsigned*)ptr = c->value_uint;			break;
 			case ARG_LONG:  	*(long*)ptr = c->value_long;			break;
 			case ARG_BER_LEN_T: 	*(ber_len_t*)ptr = c->value_ber_t;			break;
 			case ARG_STRING: {
@@ -410,9 +430,10 @@
 			ptr = cf->arg_item;
 		}
 		
-		switch(cf->arg_type & ARGS_POINTER) {
+		switch(cf->arg_type & ARGS_TYPES) {
 		case ARG_ON_OFF:
 		case ARG_INT:	c->value_int = *(int *)ptr; break;
+		case ARG_UINT:	c->value_uint = *(unsigned *)ptr; break;
 		case ARG_LONG:	c->value_long = *(long *)ptr; break;
 		case ARG_BER_LEN_T:	c->value_ber_t = *(ber_len_t *)ptr; break;
 		case ARG_STRING:
@@ -423,10 +444,12 @@
 			ber_dupbv( &c->value_bv, (struct berval *)ptr ); break;
 		}
 	}
-	if ( cf->arg_type & ARGS_POINTER) {
+	if ( cf->arg_type & ARGS_TYPES) {
+		bv.bv_len = 0;
 		bv.bv_val = c->log;
-		switch(cf->arg_type & ARGS_POINTER) {
+		switch(cf->arg_type & ARGS_TYPES) {
 		case ARG_INT: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%d", c->value_int); break;
+		case ARG_UINT: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%u", c->value_uint); break;
 		case ARG_LONG: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_long); break;
 		case ARG_BER_LEN_T: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_ber_t); break;
 		case ARG_ON_OFF: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%s",
@@ -445,59 +468,37 @@
 				return 1;
 			}
 			break;
+		default:
+			bv.bv_val = NULL;
+			break;
 		}
 		if (bv.bv_val == c->log && bv.bv_len >= sizeof( c->log ) ) {
 			return 1;
 		}
-		if (( cf->arg_type & ARGS_POINTER ) == ARG_STRING )
+		if (( cf->arg_type & ARGS_TYPES ) == ARG_STRING ) {
 			ber_bvarray_add(&c->rvalue_vals, &bv);
-		else
+		} else if ( !BER_BVISNULL( &bv ) ) {
 			value_add_one(&c->rvalue_vals, &bv);
+		}
+		/* else: maybe c->rvalue_vals already set? */
 	}
 	return rc;
 }
 
 int
 init_config_attrs(ConfigTable *ct) {
-	LDAPAttributeType *at;
 	int i, code;
-	const char *err;
 
 	for (i=0; ct[i].name; i++ ) {
-		int		freeit = 0;
-
 		if ( !ct[i].attribute ) continue;
-		at = ldap_str2attributetype( ct[i].attribute,
-			&code, &err, LDAP_SCHEMA_ALLOW_ALL );
-		if ( !at ) {
-			fprintf( stderr, "init_config_attrs: AttributeType \"%s\": %s, %s\n",
-				ct[i].attribute, ldap_scherr2str(code), err );
-			return code;
-		}
-
-		code = at_add( at, 0, NULL, &err );
+		code = register_at( ct[i].attribute, &ct[i].ad, 1 );
 		if ( code ) {
-			if ( code == SLAP_SCHERR_ATTR_DUP ) {
-				freeit = 1;
-
-			} else {
-				ldap_attributetype_free( at );
-				fprintf( stderr, "init_config_attrs: AttributeType \"%s\": %s, %s\n",
-					ct[i].attribute, scherr2str(code), err );
-				return code;
-			}
-		}
-		code = slap_str2ad( at->at_names[0], &ct[i].ad, &err );
-		if ( freeit ) {
-			ldap_attributetype_free( at );
-		} else {
-			ldap_memfree( at );
-		}
-		if ( code ) {
-			fprintf( stderr, "init_config_attrs: AttributeType \"%s\": %s\n",
-				ct[i].attribute, err );
+			fprintf( stderr, "init_config_attrs: register_at failed\n" );
 			return code;
 		}
+#ifndef LDAP_DEVEL
+		ct[i].ad->ad_type->sat_flags |= SLAP_AT_HIDE;
+#endif
 	}
 
 	return 0;
@@ -505,28 +506,17 @@
 
 int
 init_config_ocs( ConfigOCs *ocs ) {
-	int i;
+	int i, code;
 
 	for (i=0;ocs[i].co_def;i++) {
-		LDAPObjectClass *oc;
-		int code;
-		const char *err;
-
-		oc = ldap_str2objectclass( ocs[i].co_def, &code, &err,
-			LDAP_SCHEMA_ALLOW_ALL );
-		if ( !oc ) {
-			fprintf( stderr, "init_config_ocs: objectclass \"%s\": %s, %s\n",
-				ocs[i].co_def, ldap_scherr2str(code), err );
+		code = register_oc( ocs[i].co_def, &ocs[i].co_oc, 1 );
+		if ( code ) {
+			fprintf( stderr, "init_config_ocs: register_oc failed\n" );
 			return code;
 		}
-		code = oc_add(oc,0,NULL,&err);
-		if ( code && code != SLAP_SCHERR_CLASS_DUP ) {
-			fprintf( stderr, "init_config_ocs: objectclass \"%s\": %s, %s\n",
-				ocs[i].co_def, scherr2str(code), err );
-			return code;
-		}
-		ocs[i].co_oc = oc_find(oc->oc_names[0]);
-		ldap_memfree(oc);
+#ifndef LDAP_DEVEL
+		ocs[i].co_oc->soc_flags |= SLAP_OC_HIDE;
+#endif
 	}
 	return 0;
 }
@@ -548,7 +538,7 @@
 	if ( !ptr || !*ptr )
 		return NULL;
 
-	while( isspace( *ptr )) ptr++;
+	while( isspace( (unsigned char) *ptr )) ptr++;
 
 	if ( *ptr == '"' ) {
 		inquote = 1;
@@ -559,7 +549,7 @@
 
 	for (;*ptr;ptr++) {
 		if ( *ptr == '"' ) {
-			if ( inquote && ( !ptr[1] || isspace(ptr[1]))) {
+			if ( inquote && ( !ptr[1] || isspace((unsigned char) ptr[1]))) {
 				*ptr++ = '\0';
 				break;
 			}
@@ -569,7 +559,7 @@
 		}
 		if ( inquote )
 			continue;
-		if ( isspace( *ptr )) {
+		if ( isspace( (unsigned char) *ptr )) {
 			*ptr++ = '\0';
 			break;
 		}
@@ -583,7 +573,7 @@
 	if ( !*ptr ) {
 		*line = NULL;
 	} else {
-		while ( isspace( *ptr )) ptr++;
+		while ( isspace( (unsigned char) *ptr )) ptr++;
 		*line = ptr;
 	}
 	return beg;
@@ -637,12 +627,12 @@
 }
 
 int
-config_parse_add(ConfigTable *ct, ConfigArgs *c)
+config_parse_add(ConfigTable *ct, ConfigArgs *c, int valx)
 {
 	int	rc = 0;
 
 	snprintf( c->log, sizeof( c->log ), "%s: value #%d",
-		ct->ad->ad_cname.bv_val, c->valx );
+		ct->ad->ad_cname.bv_val, valx );
 	c->argc = 1;
 	c->argv[0] = ct->ad->ad_cname.bv_val;
 
@@ -692,6 +682,7 @@
 		Debug(LDAP_DEBUG_ANY,
 		    "could not stat config file \"%s\": %s (%d)\n",
 		    fname, strerror(errno), errno);
+		ch_free( c );
 		return(1);
 	}
 
@@ -700,6 +691,7 @@
 		Debug(LDAP_DEBUG_ANY,
 		    "regular file expected, got \"%s\"\n",
 		    fname, 0, 0 );
+		ch_free( c );
 		return(1);
 	}
 
@@ -709,6 +701,7 @@
 		Debug(LDAP_DEBUG_ANY,
 		    "could not open config file \"%s\": %s (%d)\n",
 		    fname, strerror(errno), errno);
+		ch_free( c );
 		return(1);
 	}
 
@@ -735,15 +728,10 @@
 		}
 
 		if ( c->argc < 1 ) {
-			Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: bad config line" 
-				SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+			Debug( LDAP_DEBUG_ANY, "%s: bad config line.\n",
 				c->log, 0, 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
 			rc = 1;
 			goto done;
-#else /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
-			continue;
-#endif /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
 		}
 
 		c->op = SLAP_CONFIG_ADD;
@@ -782,20 +770,16 @@
 			if ( rc ) {
 				switch(rc) {
 				case SLAP_CONF_UNKNOWN:
-					Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
-						"unknown directive <%s> inside backend info definition"
-						SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+					Debug( LDAP_DEBUG_ANY, "%s: unknown directive "
+						"<%s> inside backend info definition.\n",
 						c->log, *c->argv, 0);
-#ifndef SLAPD_CONF_UNKNOWN_BAILOUT
-					continue;
-#endif /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
 				default:
 					rc = 1;
 					goto done;
 				}
 			}
 
-		} else if ( c->be ) {
+		} else if ( c->be && c->be != frontendDB ) {
 			rc = SLAP_CONF_UNKNOWN;
 			if ( c->be->be_cf_ocs ) {
 				ct = config_find_keyword( c->be->be_cf_ocs->co_table, c );
@@ -808,34 +792,39 @@
 				rc = (*c->be->be_config)(c->be, c->fname, c->lineno,
 					c->argc, c->argv);
 			}
-			if ( rc ) {
-				switch(rc) {
-				case SLAP_CONF_UNKNOWN:
-					Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
-						"unknown directive <%s> inside backend database "
-						"definition" SLAPD_CONF_UNKNOWN_IGNORED ".\n",
-						c->log, *c->argv, 0);
-#ifndef SLAPD_CONF_UNKNOWN_BAILOUT
-					continue;
-#endif /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
-				default:
-					rc = 1;
-					goto done;
-				}
+			if ( rc == SLAP_CONF_UNKNOWN && SLAP_ISGLOBALOVERLAY( frontendDB ) )
+			{
+				/* global overlays may need 
+				 * definitions inside other databases...
+				 */
+				rc = (*frontendDB->be_config)( frontendDB,
+					c->fname, (int)c->lineno, c->argc, c->argv );
 			}
 
+			switch ( rc ) {
+			case 0:
+				break;
+
+			case SLAP_CONF_UNKNOWN:
+				Debug( LDAP_DEBUG_ANY, "%s: unknown directive "
+					"<%s> inside backend database definition.\n",
+					c->log, *c->argv, 0);
+				
+			default:
+				rc = 1;
+				goto done;
+			}
+
 		} else if ( frontendDB->be_config ) {
-			rc = (*frontendDB->be_config)(frontendDB, c->fname, (int)c->lineno, c->argc, c->argv);
+			rc = (*frontendDB->be_config)( frontendDB,
+				c->fname, (int)c->lineno, c->argc, c->argv);
 			if ( rc ) {
 				switch(rc) {
 				case SLAP_CONF_UNKNOWN:
-					Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
-						"unknown directive <%s> inside global database definition"
-						SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+					Debug( LDAP_DEBUG_ANY, "%s: unknown directive "
+						"<%s> inside global database definition.\n",
 						c->log, *c->argv, 0);
-#ifndef SLAPD_CONF_UNKNOWN_BAILOUT
-					continue;
-#endif /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
+
 				default:
 					rc = 1;
 					goto done;
@@ -843,16 +832,11 @@
 			}
 			
 		} else {
-			Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
-				"unknown directive <%s> outside backend info and database definitions"
-				SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+			Debug( LDAP_DEBUG_ANY, "%s: unknown directive "
+				"<%s> outside backend info and database definitions.\n",
 				c->log, *c->argv, 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
 			rc = 1;
 			goto done;
-#else /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
-			continue;
-#endif /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
 		}
 	}
 
@@ -869,15 +853,22 @@
 /* restrictops, allows, disallows, requires, loglevel */
 
 int
-verb_to_mask(const char *word, slap_verbmasks *v) {
+bverb_to_mask(struct berval *bword, slap_verbmasks *v) {
 	int i;
-	for(i = 0; !BER_BVISNULL(&v[i].word); i++)
-		if(!strcasecmp(word, v[i].word.bv_val))
-			break;
+	for(i = 0; !BER_BVISNULL(&v[i].word); i++) {
+		if(!ber_bvstrcasecmp(bword, &v[i].word)) break;
+	}
 	return(i);
 }
 
 int
+verb_to_mask(const char *word, slap_verbmasks *v) {
+	struct berval	bword;
+	ber_str2bv( word, 0, 0, &bword );
+	return bverb_to_mask( &bword, v );
+}
+
+int
 verbs_to_mask(int argc, char *argv[], slap_verbmasks *v, slap_mask_t *m) {
 	int i, j;
 	for(i = 1; i < argc; i++) {
@@ -917,8 +908,7 @@
 
 	assert( *vp == NULL );
 
-	for ( i = 0; !BER_BVISNULL( &v[ i ].word ); i++ )
-		;
+	for ( i = 0; !BER_BVISNULL( &v[ i ].word ); i++ ) /* EMPTY */;
 
 	*vp = ch_calloc( i + 1, sizeof( slap_verbmasks ) );
 
@@ -1013,6 +1003,7 @@
 	return -1;
 }
 
+#ifdef HAVE_TLS
 static slap_verbmasks tlskey[] = {
 	{ BER_BVC("no"),	SB_TLS_OFF },
 	{ BER_BVC("yes"),	SB_TLS_ON },
@@ -1020,6 +1011,22 @@
 	{ BER_BVNULL, 0 }
 };
 
+static slap_verbmasks crlkeys[] = {
+		{ BER_BVC("none"),	LDAP_OPT_X_TLS_CRL_NONE },
+		{ BER_BVC("peer"),	LDAP_OPT_X_TLS_CRL_PEER },
+		{ BER_BVC("all"),	LDAP_OPT_X_TLS_CRL_ALL },
+		{ BER_BVNULL, 0 }
+	};
+
+static slap_verbmasks vfykeys[] = {
+		{ BER_BVC("never"),	LDAP_OPT_X_TLS_NEVER },
+		{ BER_BVC("demand"),	LDAP_OPT_X_TLS_DEMAND },
+		{ BER_BVC("try"),	LDAP_OPT_X_TLS_TRY },
+		{ BER_BVC("hard"),	LDAP_OPT_X_TLS_HARD },
+		{ BER_BVNULL, 0 }
+	};
+#endif
+
 static slap_verbmasks methkey[] = {
 	{ BER_BVC("none"),	LDAP_AUTH_NONE },
 	{ BER_BVC("simple"),	LDAP_AUTH_SIMPLE },
@@ -1029,34 +1036,62 @@
 	{ BER_BVNULL, 0 }
 };
 
+static slap_verbmasks versionkey[] = {
+	{ BER_BVC("2"),		LDAP_VERSION2 },
+	{ BER_BVC("3"),		LDAP_VERSION3 },
+	{ BER_BVNULL, 0 }
+};
+
 static slap_cf_aux_table bindkey[] = {
 	{ BER_BVC("uri="), offsetof(slap_bindconf, sb_uri), 'b', 1, NULL },
-	{ BER_BVC("starttls="), offsetof(slap_bindconf, sb_tls), 'i', 0, tlskey },
+	{ BER_BVC("version="), offsetof(slap_bindconf, sb_version), 'i', 0, versionkey },
 	{ BER_BVC("bindmethod="), offsetof(slap_bindconf, sb_method), 'i', 0, methkey },
-	{ BER_BVC("binddn="), offsetof(slap_bindconf, sb_binddn), 'b', 1, dnNormalize },
+	{ BER_BVC("timeout="), offsetof(slap_bindconf, sb_timeout_api), 'i', 0, NULL },
+	{ BER_BVC("network-timeout="), offsetof(slap_bindconf, sb_timeout_net), 'i', 0, NULL },
+	{ BER_BVC("binddn="), offsetof(slap_bindconf, sb_binddn), 'b', 1, (slap_verbmasks *)dnNormalize },
 	{ BER_BVC("credentials="), offsetof(slap_bindconf, sb_cred), 'b', 1, NULL },
 	{ BER_BVC("saslmech="), offsetof(slap_bindconf, sb_saslmech), 'b', 0, NULL },
 	{ BER_BVC("secprops="), offsetof(slap_bindconf, sb_secprops), 's', 0, NULL },
 	{ BER_BVC("realm="), offsetof(slap_bindconf, sb_realm), 'b', 0, NULL },
-#ifndef SLAP_AUTHZ_SYNTAX
-	{ BER_BVC("authcID="), offsetof(slap_bindconf, sb_authcId), 'b', 0, NULL },
-	{ BER_BVC("authzID="), offsetof(slap_bindconf, sb_authzId), 'b', 1, NULL },
-#else /* SLAP_AUTHZ_SYNTAX */
-	{ BER_BVC("authcID="), offsetof(slap_bindconf, sb_authcId), 'b', 0, authzNormalize },
-	{ BER_BVC("authzID="), offsetof(slap_bindconf, sb_authzId), 'b', 1, authzNormalize },
-#endif /* SLAP_AUTHZ_SYNTAX */
+	{ BER_BVC("authcID="), offsetof(slap_bindconf, sb_authcId), 'b', 1, NULL },
+	{ BER_BVC("authzID="), offsetof(slap_bindconf, sb_authzId), 'b', 1, (slap_verbmasks *)authzNormalize },
+#ifdef HAVE_TLS
+	{ BER_BVC("starttls="), offsetof(slap_bindconf, sb_tls), 'i', 0, tlskey },
 
+	/* NOTE: replace "13" with the actual index
+	 * of the first TLS-related line */
+#define aux_TLS (bindkey+13)	/* beginning of TLS keywords */
+
+	{ BER_BVC("tls_cert="), offsetof(slap_bindconf, sb_tls_cert), 's', 1, NULL },
+	{ BER_BVC("tls_key="), offsetof(slap_bindconf, sb_tls_key), 's', 1, NULL },
+	{ BER_BVC("tls_cacert="), offsetof(slap_bindconf, sb_tls_cacert), 's', 1, NULL },
+	{ BER_BVC("tls_cacertdir="), offsetof(slap_bindconf, sb_tls_cacertdir), 's', 1, NULL },
+	{ BER_BVC("tls_reqcert="), offsetof(slap_bindconf, sb_tls_reqcert), 's', 1, NULL },
+	{ BER_BVC("tls_cipher_suite="), offsetof(slap_bindconf, sb_tls_cipher_suite), 's', 1, NULL },
+#ifdef HAVE_OPENSSL_CRL
+	{ BER_BVC("tls_crlcheck="), offsetof(slap_bindconf, sb_tls_crlcheck), 's', 1, NULL },
+#endif
+#endif
 	{ BER_BVNULL, 0, 0, 0, NULL }
 };
 
+/*
+ * 's':	char *
+ * 'b':	struct berval; if !NULL, normalize using ((slap_mr_normalize_func *)aux)
+ * 'i':	int; if !NULL, compute using ((slap_verbmasks *)aux)
+ * 'u':	unsigned
+ * 'I':	long
+ * 'U':	unsigned long
+ */
+
 int
 slap_cf_aux_table_parse( const char *word, void *dst, slap_cf_aux_table *tab0, LDAP_CONST char *tabmsg )
 {
-	int rc = 0;
+	int rc = SLAP_CONF_UNKNOWN;
 	slap_cf_aux_table *tab;
 
-	for (tab = tab0; !BER_BVISNULL(&tab->key); tab++ ) {
-		if ( !strncasecmp( word, tab->key.bv_val, tab->key.bv_len )) {
+	for ( tab = tab0; !BER_BVISNULL( &tab->key ); tab++ ) {
+		if ( !strncasecmp( word, tab->key.bv_val, tab->key.bv_len ) ) {
 			char **cptr;
 			int *iptr, j;
 			unsigned *uptr;
@@ -1069,6 +1104,7 @@
 			case 's':
 				cptr = (char **)((char *)dst + tab->off);
 				*cptr = ch_strdup( val );
+				rc = 0;
 				break;
 
 			case 'b':
@@ -1226,8 +1262,64 @@
 }
 
 int
+slap_tls_get_config( LDAP *ld, int opt, char **val )
+{
+	slap_verbmasks *keys;
+	int i, ival;
+
+	*val = NULL;
+	switch( opt ) {
+#ifdef HAVE_TLS
+	case LDAP_OPT_X_TLS_CRLCHECK:
+		keys = crlkeys;
+		break;
+	case LDAP_OPT_X_TLS_REQUIRE_CERT:
+		keys = vfykeys;
+		break;
+#endif
+	default:
+		return -1;
+	}
+	ldap_pvt_tls_get_option( ld, opt, &ival );
+	for (i=0; !BER_BVISNULL(&keys[i].word); i++) {
+		if (keys[i].mask == ival) {
+			*val = ch_strdup( keys[i].word.bv_val );
+			return 0;
+		}
+	}
+	return -1;
+}
+
+int
+bindconf_tls_parse( const char *word, slap_bindconf *bc )
+{
+#ifdef HAVE_TLS
+	if ( slap_cf_aux_table_parse( word, bc, aux_TLS, "tls config" ) == 0 ) {
+		bc->sb_tls_do_init = 1;
+		return 0;
+	}
+#endif
+	return -1;
+}
+
+int
+bindconf_tls_unparse( slap_bindconf *bc, struct berval *bv )
+{
+#ifdef HAVE_TLS
+	return slap_cf_aux_table_unparse( bc, bv, aux_TLS );
+#endif
+	return -1;
+}
+
+int
 bindconf_parse( const char *word, slap_bindconf *bc )
 {
+#ifdef HAVE_TLS
+	/* Detect TLS config changes explicitly */
+	if ( bindconf_tls_parse( word, bc ) == 0 ) {
+		return 0;
+	}
+#endif
 	return slap_cf_aux_table_parse( word, bc, bindkey, "bind config" );
 }
 
@@ -1270,9 +1362,315 @@
 		ch_free( bc->sb_authzId.bv_val );
 		BER_BVZERO( &bc->sb_authzId );
 	}
+#ifdef HAVE_TLS
+	if ( bc->sb_tls_cert ) {
+		ch_free( bc->sb_tls_cert );
+		bc->sb_tls_cert = NULL;
+	}
+	if ( bc->sb_tls_key ) {
+		ch_free( bc->sb_tls_key );
+		bc->sb_tls_key = NULL;
+	}
+	if ( bc->sb_tls_cacert ) {
+		ch_free( bc->sb_tls_cacert );
+		bc->sb_tls_cacert = NULL;
+	}
+	if ( bc->sb_tls_cacertdir ) {
+		ch_free( bc->sb_tls_cacertdir );
+		bc->sb_tls_cacertdir = NULL;
+	}
+	if ( bc->sb_tls_reqcert ) {
+		ch_free( bc->sb_tls_reqcert );
+		bc->sb_tls_reqcert = NULL;
+	}
+	if ( bc->sb_tls_cipher_suite ) {
+		ch_free( bc->sb_tls_cipher_suite );
+		bc->sb_tls_cipher_suite = NULL;
+	}
+#ifdef HAVE_OPENSSL_CRL
+	if ( bc->sb_tls_crlcheck ) {
+		ch_free( bc->sb_tls_crlcheck );
+		bc->sb_tls_crlcheck = NULL;
+	}
+#endif
+#endif
 }
 
+void
+bindconf_tls_defaults( slap_bindconf *bc )
+{
+#ifdef HAVE_TLS
+	if ( bc->sb_tls_do_init ) {
+		if ( !bc->sb_tls_cacert )
+			ldap_pvt_tls_get_option( slap_tls_ld, LDAP_OPT_X_TLS_CACERTFILE,
+				&bc->sb_tls_cacert );
+		if ( !bc->sb_tls_cacertdir )
+			ldap_pvt_tls_get_option( slap_tls_ld, LDAP_OPT_X_TLS_CACERTDIR,
+				&bc->sb_tls_cacertdir );
+		if ( !bc->sb_tls_cert )
+			ldap_pvt_tls_get_option( slap_tls_ld, LDAP_OPT_X_TLS_CERTFILE,
+				&bc->sb_tls_cert );
+		if ( !bc->sb_tls_key )
+			ldap_pvt_tls_get_option( slap_tls_ld, LDAP_OPT_X_TLS_KEYFILE,
+				&bc->sb_tls_key );
+		if ( !bc->sb_tls_cipher_suite )
+			ldap_pvt_tls_get_option( slap_tls_ld, LDAP_OPT_X_TLS_CIPHER_SUITE,
+				&bc->sb_tls_cipher_suite );
+		if ( !bc->sb_tls_reqcert )
+			bc->sb_tls_reqcert = ch_strdup("demand");
+#ifdef HAVE_OPENSSL_CRL
+		if ( !bc->sb_tls_crlcheck )
+			slap_tls_get_config( slap_tls_ld, LDAP_OPT_X_TLS_CRLCHECK,
+				&bc->sb_tls_crlcheck );
+#endif
+	}
+#endif
+}
 
+#ifdef HAVE_TLS
+static struct {
+	const char *key;
+	size_t offset;
+	int opt;
+} bindtlsopts[] = {
+	{ "tls_cert", offsetof(slap_bindconf, sb_tls_cert), LDAP_OPT_X_TLS_CERTFILE },
+	{ "tls_key", offsetof(slap_bindconf, sb_tls_key), LDAP_OPT_X_TLS_KEYFILE },
+	{ "tls_cacert", offsetof(slap_bindconf, sb_tls_cacert), LDAP_OPT_X_TLS_CACERTFILE },
+	{ "tls_cacertdir", offsetof(slap_bindconf, sb_tls_cacertdir), LDAP_OPT_X_TLS_CACERTDIR },
+	{ "tls_cipher_suite", offsetof(slap_bindconf, sb_tls_cipher_suite), LDAP_OPT_X_TLS_CIPHER_SUITE },
+	{0, 0}
+};
+
+int bindconf_tls_set( slap_bindconf *bc, LDAP *ld )
+{
+	int i, rc, newctx = 0, res = 0;
+	char *ptr = (char *)bc, **word;
+
+	bc->sb_tls_do_init = 0;
+
+	for (i=0; bindtlsopts[i].opt; i++) {
+		word = (char **)(ptr + bindtlsopts[i].offset);
+		if ( *word ) {
+			rc = ldap_set_option( ld, bindtlsopts[i].opt, *word );
+			if ( rc ) {
+				Debug( LDAP_DEBUG_ANY,
+					"bindconf_tls_set: failed to set %s to %s\n",
+						bindtlsopts[i].key, *word, 0 );
+				res = -1;
+			} else
+				newctx = 1;
+		}
+	}
+	if ( bc->sb_tls_reqcert ) {
+		rc = ldap_int_tls_config( ld, LDAP_OPT_X_TLS_REQUIRE_CERT,
+			bc->sb_tls_reqcert );
+		if ( rc ) {
+			Debug( LDAP_DEBUG_ANY,
+				"bindconf_tls_set: failed to set tls_reqcert to %s\n",
+					bc->sb_tls_reqcert, 0, 0 );
+			res = -1;
+		} else
+			newctx = 1;
+	}
+#ifdef HAVE_OPENSSL_CRL
+	if ( bc->sb_tls_crlcheck ) {
+		rc = ldap_int_tls_config( ld, LDAP_OPT_X_TLS_CRLCHECK,
+			bc->sb_tls_crlcheck );
+		if ( rc ) {
+			Debug( LDAP_DEBUG_ANY,
+				"bindconf_tls_set: failed to set tls_crlcheck to %s\n",
+					bc->sb_tls_crlcheck, 0, 0 );
+			res = -1;
+		} else
+			newctx = 1;
+	}
+#endif
+	if ( newctx ) {
+		int opt = 0;
+
+		if ( bc->sb_tls_ctx ) {
+			ldap_pvt_tls_ctx_free( bc->sb_tls_ctx );
+			bc->sb_tls_ctx = NULL;
+		}
+		rc = ldap_set_option( ld, LDAP_OPT_X_TLS_NEWCTX, &opt );
+		if ( rc )
+			res = rc;
+		else
+			ldap_get_option( ld, LDAP_OPT_X_TLS_CTX, &bc->sb_tls_ctx );
+	}
+	
+	return res;
+}
+#endif
+
+/*
+ * connect to a client using the bindconf data
+ * note: should move "version" into bindconf...
+ */
+int
+slap_client_connect( LDAP **ldp, slap_bindconf *sb )
+{
+	LDAP		*ld = NULL;
+	int		rc;
+	struct timeval tv;
+
+	/* Init connection to master */
+	rc = ldap_initialize( &ld, sb->sb_uri.bv_val );
+	if ( rc != LDAP_SUCCESS ) {
+		Debug( LDAP_DEBUG_ANY,
+			"slap_client_connect: "
+			"ldap_initialize(%s) failed (%d)\n",
+			sb->sb_uri.bv_val, rc, 0 );
+		return rc;
+	}
+
+	if ( sb->sb_version != 0 ) {
+		ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
+			(const void *)&sb->sb_version );
+	}
+
+	if ( sb->sb_timeout_api ) {
+		tv.tv_sec = sb->sb_timeout_api;
+		tv.tv_usec = 0;
+		ldap_set_option( ld, LDAP_OPT_TIMEOUT, &tv );
+	}
+
+	if ( sb->sb_timeout_net ) {
+		tv.tv_sec = sb->sb_timeout_net;
+		tv.tv_usec = 0;
+		ldap_set_option( ld, LDAP_OPT_NETWORK_TIMEOUT, &tv );
+	}
+
+#ifdef HAVE_TLS
+	if ( sb->sb_tls_do_init ) {
+		rc = bindconf_tls_set( sb, ld );
+
+	} else if ( sb->sb_tls_ctx ) {
+		rc = ldap_set_option( ld, LDAP_OPT_X_TLS_CTX,
+			sb->sb_tls_ctx );
+	}
+
+	if ( rc ) {
+		Debug( LDAP_DEBUG_ANY,
+			"slap_client_connect: "
+			"URI=%s TLS context initialization failed (%d)\n",
+			sb->sb_uri.bv_val, rc, 0 );
+		return rc;
+	}
+#endif
+
+	/* Bind */
+	if ( sb->sb_tls ) {
+		rc = ldap_start_tls_s( ld, NULL, NULL );
+		if ( rc != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_ANY,
+				"slap_client_connect: URI=%s "
+				"%s, ldap_start_tls failed (%d)\n",
+				sb->sb_uri.bv_val,
+				sb->sb_tls == SB_TLS_CRITICAL ?
+					"Error" : "Warning",
+				rc );
+			if ( sb->sb_tls == SB_TLS_CRITICAL ) {
+				goto done;
+			}
+		}
+	}
+
+	if ( sb->sb_method == LDAP_AUTH_SASL ) {
+#ifdef HAVE_CYRUS_SASL
+		void *defaults;
+
+		if ( sb->sb_secprops != NULL ) {
+			rc = ldap_set_option( ld,
+				LDAP_OPT_X_SASL_SECPROPS, sb->sb_secprops);
+
+			if( rc != LDAP_OPT_SUCCESS ) {
+				Debug( LDAP_DEBUG_ANY,
+					"slap_client_connect: "
+					"error, ldap_set_option "
+					"(%s,SECPROPS,\"%s\") failed!\n",
+					sb->sb_uri.bv_val, sb->sb_secprops, 0 );
+				goto done;
+			}
+		}
+
+		defaults = lutil_sasl_defaults( ld,
+			sb->sb_saslmech.bv_val,
+			sb->sb_realm.bv_val,
+			sb->sb_authcId.bv_val,
+			sb->sb_cred.bv_val,
+			sb->sb_authzId.bv_val );
+		if ( defaults == NULL ) {
+			rc = LDAP_OTHER;
+			goto done;
+		}
+
+		rc = ldap_sasl_interactive_bind_s( ld,
+				sb->sb_binddn.bv_val,
+				sb->sb_saslmech.bv_val,
+				NULL, NULL,
+				LDAP_SASL_QUIET,
+				lutil_sasl_interact,
+				defaults );
+
+		lutil_sasl_freedefs( defaults );
+
+		/* FIXME: different error behaviors according to
+		 *	1) return code
+		 *	2) on err policy : exit, retry, backoff ...
+		 */
+		if ( rc != LDAP_SUCCESS ) {
+			static struct berval bv_GSSAPI = BER_BVC( "GSSAPI" );
+
+			Debug( LDAP_DEBUG_ANY, "slap_client_connect: URI=%s "
+				"ldap_sasl_interactive_bind_s failed (%d)\n",
+				sb->sb_uri.bv_val, rc, 0 );
+
+			/* FIXME (see above comment) */
+			/* if Kerberos credentials cache is not active, retry */
+			if ( ber_bvcmp( &sb->sb_saslmech, &bv_GSSAPI ) == 0 &&
+				rc == LDAP_LOCAL_ERROR )
+			{
+				rc = LDAP_SERVER_DOWN;
+			}
+
+			goto done;
+		}
+#else /* HAVE_CYRUS_SASL */
+		/* Should never get here, we trapped this at config time */
+		assert(0);
+		Debug( LDAP_DEBUG_SYNC, "not compiled with SASL support\n", 0, 0, 0 );
+		rc = LDAP_OTHER;
+		goto done;
+#endif
+
+	} else if ( sb->sb_method == LDAP_AUTH_SIMPLE ) {
+		rc = ldap_sasl_bind_s( ld,
+			sb->sb_binddn.bv_val, LDAP_SASL_SIMPLE,
+			&sb->sb_cred, NULL, NULL, NULL );
+		if ( rc != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_ANY, "slap_client_connect: "
+				"URI=%s DN=\"%s\" "
+				"ldap_sasl_bind_s failed (%d)\n",
+				sb->sb_uri.bv_val, sb->sb_binddn.bv_val, rc );
+			goto done;
+		}
+	}
+
+done:;
+	if ( rc ) {
+		if ( ld ) {
+			ldap_unbind_ext( ld, NULL, NULL );
+			*ldp = NULL;
+		}
+
+	} else {
+		*ldp = ld;
+	}
+
+	return rc;
+}
+
 /* -------------------------------------- */
 
 

Modified: openldap/trunk/servers/slapd/config.h
===================================================================
--- openldap/trunk/servers/slapd/config.h	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/config.h	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* config.h - configuration abstraction structure */
-/* $OpenLDAP: pkg/ldap/servers/slapd/config.h,v 1.2.2.14 2007/09/02 11:51:09 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/config.h,v 1.34.2.4 2007/09/29 08:01:42 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -17,6 +17,8 @@
 #ifndef CONFIG_H
 #define CONFIG_H
 
+#include<ac/string.h>
+
 typedef struct ConfigTable {
 	char *name;
 	char *what;
@@ -30,32 +32,33 @@
 	void *notify;
 } ConfigTable;
 
+/* search entries are returned according to this order */
 typedef enum {
 	Cft_Abstract = 0,
 	Cft_Global,
+	Cft_Module,
 	Cft_Schema,
 	Cft_Backend,
 	Cft_Database,
 	Cft_Overlay,
-	Cft_Include,
-	Cft_Module,
 	Cft_Misc	/* backend/overlay defined */
 } ConfigType;
 
 #define ARGS_USERLAND	0x00000fff
-#define ARGS_TYPES	0x000ff000
-#define ARGS_POINTER	0x0003f000
-#define ARGS_NUMERIC	0x0000f000
+
+/* types are enumerated, not a bitmask */
+#define ARGS_TYPES	0x0000f000
 #define ARG_INT		0x00001000
 #define ARG_LONG	0x00002000
-#define ARG_BER_LEN_T	0x00004000
-#define ARG_ON_OFF	0x00008000
-#define ARG_STRING	0x00010000
-#define ARG_BERVAL	0x00020000
-#define ARG_DN		0x00040000
+#define ARG_BER_LEN_T	0x00003000
+#define ARG_ON_OFF	0x00004000
+#define ARG_STRING	0x00005000
+#define ARG_BERVAL	0x00006000
+#define ARG_DN		0x00007000
+#define ARG_UINT	0x00008000
+
+#define ARGS_SYNTAX	0xffff0000
 #define ARG_IGNORED	0x00080000
-
-#define ARGS_SYNTAX	0xfff00000
 #define ARG_PRE_BI	0x00100000
 #define ARG_PRE_DB	0x00200000
 #define ARG_DB		0x00400000	/* Only applies to DB */
@@ -105,6 +108,11 @@
 
 typedef int (ConfigDriver)(struct config_args_s *c);
 
+typedef struct config_reply_s {
+	int err;
+	char msg[SLAP_TEXT_BUFLEN];
+} ConfigReply;
+
 typedef struct config_args_s {
 	int argc;
 	char **argv;
@@ -114,12 +122,14 @@
 	const char *fname;
 	int lineno;
 	char log[MAXPATHLEN + STRLENOF(": line 18446744073709551615") + 1];
-	char msg[SLAP_TEXT_BUFLEN];
+#define cr_msg reply.msg
+	ConfigReply reply;
 	int depth;
 	int valx;	/* multi-valued value index */
 	/* parsed first val for simple cases */
 	union {
 		int v_int;
+		unsigned v_uint;
 		long v_long;
 		ber_len_t v_ber_t;
 		char *v_string;
@@ -136,6 +146,7 @@
 #define SLAP_CONFIG_ADD		0x4000	/* config file add vs LDAP add */
 	int op;
 	int type;	/* ConfigTable.arg_type & ARGS_USERLAND */
+	Operation *ca_op;
 	BackendDB *be;
 	BackendInfo *bi;
 	Entry *ca_entry;	/* entry being modified */
@@ -150,6 +161,7 @@
 #define CONFIG_ONLINE_ADD(ca)	(!((ca)->lineno))
 
 #define value_int values.v_int
+#define value_uint values.v_uint
 #define value_long values.v_long
 #define value_ber_t values.v_ber_t
 #define value_string values.v_string
@@ -166,7 +178,7 @@
 int init_config_attrs(ConfigTable *ct);
 int init_config_ocs( ConfigOCs *ocs );
 int config_parse_vals(ConfigTable *ct, ConfigArgs *c, int valx);
-int config_parse_add(ConfigTable *ct, ConfigArgs *c);
+int config_parse_add(ConfigTable *ct, ConfigArgs *c, int valx);
 int read_config_file(const char *fname, int depth, ConfigArgs *cf,
 	ConfigTable *cft );
 

Modified: openldap/trunk/servers/slapd/connection.c
===================================================================
--- openldap/trunk/servers/slapd/connection.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/connection.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/connection.c,v 1.296.2.30 2007/06/14 23:49:38 quanah Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/connection.c,v 1.358.2.11 2007/11/27 20:11:48 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -83,25 +83,19 @@
 
 static Connection* connection_get( ber_socket_t s );
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
-
 typedef struct conn_readinfo {
 	Operation *op;
 	ldap_pvt_thread_start_t *func;
 	void *arg;
+	void *ctx;
 	int nullop;
 } conn_readinfo;
 
 static int connection_input( Connection *c, conn_readinfo *cri );
-#else
-static int connection_input( Connection *c );
-#endif
 static void connection_close( Connection *c );
 
 static int connection_op_activate( Operation *op );
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 static void connection_op_queue( Operation *op );
-#endif
 static int connection_resched( Connection *conn );
 static void connection_abandon( Connection *conn );
 static void connection_destroy( Connection *c );
@@ -260,70 +254,19 @@
 
 	if(s == AC_SOCKET_INVALID) return NULL;
 
-#ifndef HAVE_WINSOCK
 	assert( s < dtblsize );
 	c = &connections[s];
 
-#else
-	c = NULL;
-	{
-		ber_socket_t i, sd;
-
-		ldap_pvt_thread_mutex_lock( &connections_mutex );
-		for(i=0; i<dtblsize; i++) {
-			if( connections[i].c_struct_state == SLAP_C_PENDING )
-				continue;
-
-			if( connections[i].c_struct_state == SLAP_C_UNINITIALIZED ) {
-				assert( connections[i].c_conn_state == SLAP_C_INVALID );
-				assert( connections[i].c_sb == 0 );
-				break;
-			}
-
-			ber_sockbuf_ctrl( connections[i].c_sb,
-				LBER_SB_OPT_GET_FD, &sd );
-
-			if( connections[i].c_struct_state == SLAP_C_UNUSED ) {
-				assert( connections[i].c_conn_state == SLAP_C_INVALID );
-				assert( sd == AC_SOCKET_INVALID );
-				continue;
-			}
-
-			/* state can actually change from used -> unused by resched,
-			 * so don't assert details here.
-			 */
-
-			if( sd == s ) {
-				c = &connections[i];
-				break;
-			}
-		}
-		ldap_pvt_thread_mutex_unlock( &connections_mutex );
-	}
-#endif
-
 	if( c != NULL ) {
-		ber_socket_t	sd;
-
 		ldap_pvt_thread_mutex_lock( &c->c_mutex );
 
 		assert( c->c_struct_state != SLAP_C_UNINITIALIZED );
 
-		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
-#ifdef HAVE_WINSOCK
-		/* Avoid race condition after releasing
-		 * connections_mutex
-		 */
-		if ( sd != s ) {
-			ldap_pvt_thread_mutex_unlock( &c->c_mutex );
-			return NULL;
-		}
-#endif
 		if( c->c_struct_state != SLAP_C_USED ) {
 			/* connection must have been closed due to resched */
 
 			assert( c->c_conn_state == SLAP_C_INVALID );
-			assert( sd == AC_SOCKET_INVALID );
+			assert( c->c_sd == AC_SOCKET_INVALID );
 
 			Debug( LDAP_DEBUG_TRACE,
 				"connection_get(%d): connection not used\n",
@@ -341,7 +284,7 @@
 
 		assert( c->c_struct_state == SLAP_C_USED );
 		assert( c->c_conn_state != SLAP_C_INVALID );
-		assert( sd != AC_SOCKET_INVALID );
+		assert( c->c_sd != AC_SOCKET_INVALID );
 
 #ifndef SLAPD_MONITOR
 		if ( global_idletimeout > 0 )
@@ -359,18 +302,20 @@
 	ldap_pvt_thread_mutex_unlock( &c->c_mutex );
 }
 
-long connection_init(
+Connection * connection_init(
 	ber_socket_t s,
 	Listener *listener,
 	const char* dnsname,
 	const char* peername,
 	int flags,
 	slap_ssf_t ssf,
-	struct berval *authid )
+	struct berval *authid
+	LDAP_PF_LOCAL_SENDMSG_ARG(struct berval *peerbv))
 {
 	unsigned long id;
 	Connection *c;
 	int doinit = 0;
+	ber_socket_t sfd = SLAP_FD2SOCK(s);
 
 	assert( connections != NULL );
 
@@ -379,17 +324,16 @@
 	assert( peername != NULL );
 
 #ifndef HAVE_TLS
-	assert( flags != CONN_IS_TLS );
+	assert( !( flags & CONN_IS_TLS ));
 #endif
 
 	if( s == AC_SOCKET_INVALID ) {
 		Debug( LDAP_DEBUG_ANY,
 			"connection_init: init of socket %ld invalid.\n", (long)s, 0, 0 );
-		return -1;
+		return NULL;
 	}
 
 	assert( s >= 0 );
-#ifndef HAVE_WINSOCK
 	assert( s < dtblsize );
 	c = &connections[s];
 	if( c->c_struct_state == SLAP_C_UNINITIALIZED ) {
@@ -397,56 +341,7 @@
 	} else {
 		assert( c->c_struct_state == SLAP_C_UNUSED );
 	}
-#else
-	{
-		ber_socket_t i;
-		c = NULL;
 
-		ldap_pvt_thread_mutex_lock( &connections_mutex );
-		for( i=0; i < dtblsize; i++) {
-			ber_socket_t	sd;
-
-			if ( connections[i].c_struct_state == SLAP_C_PENDING )
-				continue;
-
-			if( connections[i].c_struct_state == SLAP_C_UNINITIALIZED ) {
-				assert( connections[i].c_sb == 0 );
-				c = &connections[i];
-				c->c_struct_state = SLAP_C_PENDING;
-				doinit = 1;
-				break;
-			}
-
-			sd = AC_SOCKET_INVALID;
-			if (connections[i].c_sb != NULL) {
-				ber_sockbuf_ctrl( connections[i].c_sb,
-					LBER_SB_OPT_GET_FD, &sd );
-			}
-
-			if( connections[i].c_struct_state == SLAP_C_UNUSED ) {
-				assert( sd == AC_SOCKET_INVALID );
-				c = &connections[i];
-				c->c_struct_state = SLAP_C_PENDING;
-				break;
-			}
-
-			if( connections[i].c_conn_state == SLAP_C_CLIENT ) continue;
-
-			assert( connections[i].c_struct_state == SLAP_C_USED );
-			assert( connections[i].c_conn_state != SLAP_C_INVALID );
-			assert( sd != AC_SOCKET_INVALID );
-		}
-		ldap_pvt_thread_mutex_unlock( &connections_mutex );
-
-		if( c == NULL ) {
-			Debug( LDAP_DEBUG_ANY,
-				"connection_init(%d): connection table full "
-				"(%d/%d)\n", s, i, dtblsize);
-			return -1;
-		}
-	}
-#endif
-
 	if( doinit ) {
 		c->c_send_ldap_result = slap_send_ldap_result;
 		c->c_send_search_entry = slap_send_search_entry;
@@ -524,15 +419,17 @@
 	assert( c->c_writewaiter == 0);
 
 	c->c_listener = listener;
+	c->c_sd = s;
 
-	if ( flags == CONN_IS_CLIENT ) {
+	if ( flags & CONN_IS_CLIENT ) {
+		c->c_connid = 0;
 		c->c_conn_state = SLAP_C_CLIENT;
 		c->c_struct_state = SLAP_C_USED;
 		c->c_close_reason = "?";			/* should never be needed */
-		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &s );
+		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &sfd );
 		ldap_pvt_thread_mutex_unlock( &c->c_mutex );
 
-		return 0;
+		return c;
 	}
 
 	ber_str2bv( dnsname, 0, 1, &c->c_peer_domain );
@@ -559,25 +456,39 @@
 
 #ifdef LDAP_CONNECTIONLESS
 	c->c_is_udp = 0;
-	if( flags == CONN_IS_UDP ) {
+	if( flags & CONN_IS_UDP ) {
 		c->c_is_udp = 1;
 #ifdef LDAP_DEBUG
 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug,
 			LBER_SBIOD_LEVEL_PROVIDER, (void*)"udp_" );
 #endif
 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_udp,
-			LBER_SBIOD_LEVEL_PROVIDER, (void *)&s );
+			LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd );
 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_readahead,
 			LBER_SBIOD_LEVEL_PROVIDER, NULL );
 	} else
+#endif /* LDAP_CONNECTIONLESS */
+#ifdef LDAP_PF_LOCAL
+	if ( flags & CONN_IS_IPC ) {
+#ifdef LDAP_DEBUG
+		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug,
+			LBER_SBIOD_LEVEL_PROVIDER, (void*)"ipc_" );
 #endif
+		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_fd,
+			LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd );
+#ifdef LDAP_PF_LOCAL_SENDMSG
+		if ( !BER_BVISEMPTY( peerbv ))
+			ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_UNGET_BUF, peerbv );
+#endif
+	} else
+#endif /* LDAP_PF_LOCAL */
 	{
 #ifdef LDAP_DEBUG
 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug,
 			LBER_SBIOD_LEVEL_PROVIDER, (void*)"tcp_" );
 #endif
 		ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_tcp,
-			LBER_SBIOD_LEVEL_PROVIDER, (void *)&s );
+			LBER_SBIOD_LEVEL_PROVIDER, (void *)&sfd );
 	}
 
 #ifdef LDAP_DEBUG
@@ -605,7 +516,7 @@
 	c->c_tls_ssf = 0;
 
 #ifdef HAVE_TLS
-	if ( flags == CONN_IS_TLS ) {
+	if ( flags & CONN_IS_TLS ) {
 		c->c_is_tls = 1;
 		c->c_needs_tls_accept = 1;
 	} else {
@@ -622,7 +533,7 @@
 
 	backend_connection_init(c);
 
-	return id;
+	return c;
 }
 
 void connection2anonymous( Connection *c )
@@ -661,10 +572,10 @@
 static void
 connection_destroy( Connection *c )
 {
-	ber_socket_t	sd;
 	unsigned long	connid;
 	const char		*close_reason;
 	Sockbuf			*sb;
+	ber_socket_t	sd;
 
 	assert( connections != NULL );
 	assert( c != NULL );
@@ -727,6 +638,8 @@
 	}
 #endif
 
+	sd = c->c_sd;
+	c->c_sd = AC_SOCKET_INVALID;
 	c->c_conn_state = SLAP_C_INVALID;
 	c->c_struct_state = SLAP_C_UNUSED;
 	c->c_close_reason = "?";			/* should never be needed */
@@ -738,8 +651,6 @@
 		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
 	}
 
-	ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
-
 	/* c must be fully reset by this point; when we call slapd_remove
 	 * it may get immediately reused by a new connection.
 	 */
@@ -797,7 +708,7 @@
 	while ( (o = LDAP_STAILQ_FIRST( &c->c_txn_ops )) != NULL) {
 		LDAP_STAILQ_REMOVE_HEAD( &c->c_txn_ops, o_next );
 		LDAP_STAILQ_NEXT(o, o_next) = NULL;
-		slap_op_free( o );
+		slap_op_free( o, NULL );
 	}
 
 	/* clear transaction */
@@ -809,7 +720,7 @@
 	while ( (o = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) {
 		LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next );
 		LDAP_STAILQ_NEXT(o, o_next) = NULL;
-		slap_op_free( o );
+		slap_op_free( o, NULL );
 	}
 }
 
@@ -823,18 +734,15 @@
 	/* c_mutex must be locked by caller */
 
 	if( c->c_conn_state != SLAP_C_CLOSING ) {
-		ber_socket_t	sd;
-
-		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
 		Debug( LDAP_DEBUG_TRACE,
 			"connection_closing: readying conn=%lu sd=%d for close\n",
-			c->c_connid, sd, 0 );
+			c->c_connid, c->c_sd, 0 );
 		/* update state to closing */
 		c->c_conn_state = SLAP_C_CLOSING;
 		c->c_close_reason = why;
 
 		/* don't listen on this port anymore */
-		slapd_clr_read( sd, 0 );
+		slapd_clr_read( c->c_sd, 0 );
 
 		/* abandon active operations */
 		connection_abandon( c );
@@ -846,13 +754,13 @@
 			 * connection_resched / connection_close before we
 			 * finish, but that's OK.
 			 */
-			slapd_clr_write( sd, 1 );
+			slapd_clr_write( c->c_sd, 1 );
 			ldap_pvt_thread_mutex_unlock( &c->c_mutex );
 			ldap_pvt_thread_mutex_lock( &c->c_write_mutex );
 			ldap_pvt_thread_mutex_lock( &c->c_mutex );
 			ldap_pvt_thread_mutex_unlock( &c->c_write_mutex );
 		} else {
-			slapd_clr_write( sd, 1 );
+			slapd_clr_write( c->c_sd, 1 );
 		}
 
 	} else if( why == NULL && c->c_close_reason == conn_lost_str ) {
@@ -864,8 +772,6 @@
 static void
 connection_close( Connection *c )
 {
-	ber_socket_t	sd = AC_SOCKET_INVALID;
-
 	assert( connections != NULL );
 	assert( c != NULL );
 
@@ -878,24 +784,17 @@
 
 	/* NOTE: c_mutex should be locked by caller */
 
-	/* NOTE: don't get the file descriptor if not needed */
-#ifdef LDAP_DEBUG
-	if ( slap_debug & LDAP_DEBUG_TRACE ) {
-		ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
-	}
-#endif /* LDAP_DEBUG */
-
 	if ( !LDAP_STAILQ_EMPTY(&c->c_ops) ||
 		!LDAP_STAILQ_EMPTY(&c->c_pending_ops) )
 	{
 		Debug( LDAP_DEBUG_TRACE,
 			"connection_close: deferring conn=%lu sd=%d\n",
-			c->c_connid, sd, 0 );
+			c->c_connid, c->c_sd, 0 );
 		return;
 	}
 
 	Debug( LDAP_DEBUG_TRACE, "connection_close: conn=%lu sd=%d\n",
-		c->c_connid, sd, 0 );
+		c->c_connid, c->c_sd, 0 );
 
 	connection_destroy( c );
 }
@@ -945,11 +844,7 @@
 		int c_struct;
 		if( connections[*index].c_struct_state == SLAP_C_UNINITIALIZED ) {
 			assert( connections[*index].c_conn_state == SLAP_C_INVALID );
-#ifdef HAVE_WINSOCK
-			break;
-#else
 			continue;
-#endif
 		}
 
 		if( connections[*index].c_struct_state == SLAP_C_USED ) {
@@ -997,24 +892,24 @@
 /* FIXME: returns 0 in case of failure */
 #define INCR_OP_INITIATED(index) \
 	do { \
-		ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex ); \
-		ldap_pvt_mp_add_ulong(slap_counters.sc_ops_initiated_[(index)], 1); \
-		ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex ); \
+		ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \
+		ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_initiated_[(index)], 1); \
+		ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \
 	} while (0)
 #define INCR_OP_COMPLETED(index) \
 	do { \
-		ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex ); \
-		ldap_pvt_mp_add_ulong(slap_counters.sc_ops_completed, 1); \
-		ldap_pvt_mp_add_ulong(slap_counters.sc_ops_completed_[(index)], 1); \
-		ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex ); \
+		ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \
+		ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed, 1); \
+		ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed_[(index)], 1); \
+		ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \
 	} while (0)
 #else /* !SLAPD_MONITOR */
 #define INCR_OP_INITIATED(index) do { } while (0)
 #define INCR_OP_COMPLETED(index) \
 	do { \
-		ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex ); \
-		ldap_pvt_mp_add_ulong(slap_counters.sc_ops_completed, 1); \
-		ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex ); \
+		ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \
+		ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed, 1); \
+		ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \
 	} while (0)
 #endif /* !SLAPD_MONITOR */
 
@@ -1024,17 +919,73 @@
 static BI_op_func *opfun[] = {
 	do_bind,
 	do_unbind,
+	do_search,
+	do_compare,
+	do_modify,
+	do_modrdn,
 	do_add,
 	do_delete,
-	do_modrdn,
-	do_modify,
-	do_compare,
-	do_search,
 	do_abandon,
 	do_extended,
 	NULL
 };
 
+/* Counters are per-thread, not per-connection.
+ */
+static void
+conn_counter_destroy( void *key, void *data )
+{
+	slap_counters_t **prev, *sc;
+
+	ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
+	for ( prev = &slap_counters.sc_next, sc = slap_counters.sc_next; sc;
+		prev = &sc->sc_next, sc = sc->sc_next ) {
+		if ( sc == data ) {
+			int i;
+
+			*prev = sc->sc_next;
+			/* Copy data to main counter */
+			ldap_pvt_mp_add( slap_counters.sc_bytes, sc->sc_bytes );
+			ldap_pvt_mp_add( slap_counters.sc_pdu, sc->sc_pdu );
+			ldap_pvt_mp_add( slap_counters.sc_entries, sc->sc_entries );
+			ldap_pvt_mp_add( slap_counters.sc_refs, sc->sc_refs );
+			ldap_pvt_mp_add( slap_counters.sc_ops_initiated, sc->sc_ops_initiated );
+			ldap_pvt_mp_add( slap_counters.sc_ops_completed, sc->sc_ops_completed );
+#ifdef SLAPD_MONITOR
+			for ( i = 0; i < SLAP_OP_LAST; i++ ) {
+				ldap_pvt_mp_add( slap_counters.sc_ops_initiated_[ i ], sc->sc_ops_initiated_[ i ] );
+				ldap_pvt_mp_add( slap_counters.sc_ops_initiated_[ i ], sc->sc_ops_completed_[ i ] );
+			}
+#endif /* SLAPD_MONITOR */
+			slap_counters_destroy( sc );
+			ber_memfree_x( data, NULL );
+			break;
+		}
+	}
+	ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
+}
+
+static void
+conn_counter_init( Operation *op, void *ctx )
+{
+	slap_counters_t *sc;
+	void *vsc = NULL;
+
+	if ( ldap_pvt_thread_pool_getkey( ctx, conn_counter_init, &vsc, NULL ) || !vsc ) {
+		vsc = ch_malloc( sizeof( slap_counters_t ));
+		sc = vsc;
+		slap_counters_init( sc );
+		ldap_pvt_thread_pool_setkey( ctx, conn_counter_init, vsc,
+			conn_counter_destroy );
+
+		ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
+		sc->sc_next = slap_counters.sc_next;
+		slap_counters.sc_next = sc;
+		ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
+	}
+	op->o_counters = vsc;
+}
+
 static void *
 connection_operation( void *ctx, void *arg_v )
 {
@@ -1048,15 +999,14 @@
 	void *memctx_null = NULL;
 	ber_len_t memsiz;
 
-	ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
+	conn_counter_init( op, ctx );
+	ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex );
 	/* FIXME: returns 0 in case of failure */
-	ldap_pvt_mp_add_ulong(slap_counters.sc_ops_initiated, 1);
-	ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
+	ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_initiated, 1);
+	ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex );
 
 	op->o_threadctx = ctx;
-#ifdef LDAP_DEVEL
 	op->o_tid = ldap_pvt_thread_pool_tid( ctx );
-#endif /* LDAP_DEVEL */
 
 	switch ( tag ) {
 	case LDAP_REQ_BIND:
@@ -1115,7 +1065,7 @@
 #endif
 	memsiz = SLAP_SLAB_SIZE;
 
-	memctx = slap_sl_mem_create( memsiz, SLAP_SLAB_STACK, ctx );
+	memctx = slap_sl_mem_create( memsiz, SLAP_SLAB_STACK, ctx, 1 );
 	op->o_tmpmemctx = memctx;
 	op->o_tmpmfuncs = &slap_sl_mfuncs;
 	if ( tag != LDAP_REQ_ADD && tag != LDAP_REQ_MODIFY ) {
@@ -1161,9 +1111,8 @@
 
 	ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
 
-	LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
+	LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);
 	LDAP_STAILQ_NEXT(op, o_next) = NULL;
-	slap_op_free( op );
 	conn->c_n_ops_executing--;
 	conn->c_n_ops_completed++;
 
@@ -1178,44 +1127,44 @@
 
 	connection_resched( conn );
 	ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+	slap_op_free( op, ctx );
 	return NULL;
 }
 
 static const Listener dummy_list = { BER_BVC(""), BER_BVC("") };
 
-int connection_client_setup(
+Connection *connection_client_setup(
 	ber_socket_t s,
 	ldap_pvt_thread_start_t *func,
 	void *arg )
 {
-	int rc;
 	Connection *c;
+	ber_socket_t sfd = SLAP_SOCKNEW( s );
 
-	rc = connection_init( s, (Listener *)&dummy_list, "", "",
-		CONN_IS_CLIENT, 0, NULL );
-	if ( rc < 0 ) return -1;
+	c = connection_init( sfd, (Listener *)&dummy_list, "", "",
+		CONN_IS_CLIENT, 0, NULL
+		LDAP_PF_LOCAL_SENDMSG_ARG(NULL));
+	if ( c ) {
+		c->c_clientfunc = func;
+		c->c_clientarg = arg;
 
-	c = connection_get( s );
-	c->c_clientfunc = func;
-	c->c_clientarg = arg;
-
-	slapd_add_internal( s, 0 );
-	slapd_set_read( s, 1 );
-	connection_return( c );
-	return 0;
+		slapd_add_internal( sfd, 0 );
+		slapd_set_read( sfd, 1 );
+	}
+	return c;
 }
 
 void connection_client_enable(
-	ber_socket_t s )
+	Connection *c )
 {
-	slapd_set_read( s, 1 );
+	slapd_set_read( c->c_sd, 1 );
 }
 
 void connection_client_stop(
-	ber_socket_t s )
+	Connection *c )
 {
-	Connection *c;
 	Sockbuf *sb;
+	ber_socket_t s = c->c_sd;
 
 	/* get (locked) connection */
 	c = connection_get( s );
@@ -1225,6 +1174,7 @@
 	c->c_listener = NULL;
 	c->c_conn_state = SLAP_C_INVALID;
 	c->c_struct_state = SLAP_C_UNUSED;
+	c->c_sd = AC_SOCKET_INVALID;
 	c->c_close_reason = "?";			/* should never be needed */
 	sb = c->c_sb;
 	c->c_sb = ber_sockbuf_alloc( );
@@ -1237,20 +1187,19 @@
 	connection_return( c );
 }
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
-
 static int connection_read( ber_socket_t s, conn_readinfo *cri );
 
 static void* connection_read_thread( void* ctx, void* argv )
 {
 	int rc ;
-	conn_readinfo cri = { NULL, NULL, NULL, 0 };
+	conn_readinfo cri = { NULL, NULL, NULL, NULL, 0 };
 	ber_socket_t s = (long)argv;
 
 	/*
 	 * read incoming LDAP requests. If there is more than one,
 	 * the first one is returned with new_op
 	 */
+	cri.ctx = ctx;
 	if( ( rc = connection_read( s, &cri ) ) < 0 ) {
 		Debug( LDAP_DEBUG_CONNS, "connection_read(%d) error\n", s, 0, 0 );
 		return (void*)(long)rc;
@@ -1290,14 +1239,9 @@
 
 	return rc;
 }
-#endif
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 static int
 connection_read( ber_socket_t s, conn_readinfo *cri )
-#else
-int connection_read(ber_socket_t s)
-#endif
 {
 	int rc = 0;
 	Connection *c;
@@ -1326,15 +1270,9 @@
 	}
 
 	if ( c->c_conn_state == SLAP_C_CLIENT ) {
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 		cri->func = c->c_clientfunc;
 		cri->arg = c->c_clientarg;
 		/* read should already be cleared */
-#else
-		slapd_clr_read( s, 0 );
-		ldap_pvt_thread_pool_submit( &connection_pool,
-			c->c_clientfunc, c->c_clientarg );
-#endif
 		connection_return( c );
 		return 0;
 	}
@@ -1389,10 +1327,7 @@
 		/* if success and data is ready, fall thru to data input loop */
 		if( !ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ) )
 		{
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 			slapd_set_read( s, 1 );
-#endif
-
 			connection_return( c );
 			return 0;
 		}
@@ -1403,10 +1338,7 @@
 	if ( c->c_sasl_layers ) {
 		/* If previous layer is not removed yet, give up for now */
 		if ( !c->c_sasl_sockctx ) {
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 			slapd_set_read( s, 1 );
-#endif
-
 			connection_return( c );
 			return 0;
 		}
@@ -1434,15 +1366,11 @@
 
 	do {
 		/* How do we do this without getting into a busy loop ? */
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 		rc = connection_input( c, cri );
-#else
-		rc = connection_input( c );
-#endif
 	}
 #ifdef DATA_READY_LOOP
 	while( !rc && ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ));
-#elif CONNECTION_INPUT_LOOP
+#elif defined CONNECTION_INPUT_LOOP
 	while(!rc);
 #else
 	while(0);
@@ -1460,33 +1388,18 @@
 		return 0;
 	}
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 	if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
 		slapd_set_write( s, 0 );
 	}
 
 	slapd_set_read( s, 1 );
-#else
-	if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) ) {
-		slapd_set_read( s, 1 );
-	}
-
-	if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
-		slapd_set_write( s, 1 );
-	}
-#endif
-
 	connection_return( c );
 
 	return 0;
 }
 
 static int
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 connection_input( Connection *conn , conn_readinfo *cri )
-#else
-connection_input( Connection *conn )
-#endif
 {
 	Operation *op;
 	ber_tag_t	tag;
@@ -1499,6 +1412,7 @@
 	char 		*cdn = NULL;
 #endif
 	char *defer = NULL;
+	void *ctx;
 
 	if ( conn->c_currentber == NULL &&
 		( conn->c_currentber = ber_alloc()) == NULL )
@@ -1528,15 +1442,12 @@
 	tag = ber_get_next( conn->c_sb, &len, conn->c_currentber );
 	if ( tag != LDAP_TAG_MESSAGE ) {
 		int err = sock_errno();
-		ber_socket_t	sd;
 
-		ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
-
 		if ( err != EWOULDBLOCK && err != EAGAIN ) {
 			/* log, close and send error */
-		Debug( LDAP_DEBUG_TRACE,
-			"ber_get_next on fd %d failed errno=%d (%s)\n",
-			sd, err, sock_errstr(err) );
+			Debug( LDAP_DEBUG_TRACE,
+				"ber_get_next on fd %d failed errno=%d (%s)\n",
+			conn->c_sd, err, sock_errstr(err) );
 			ber_free( conn->c_currentber, 1 );
 			conn->c_currentber = NULL;
 
@@ -1582,7 +1493,8 @@
 		connection_abandon( conn );
 	}
 
-	op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++ );
+	ctx = cri->ctx;
+	op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++, ctx );
 
 	op->o_conn = conn;
 	/* clear state if the connection is being reused from inactive */
@@ -1672,7 +1584,6 @@
 	} else {
 		conn->c_n_ops_executing++;
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 		/*
 		 * The first op will be processed in the same thread context,
 		 * as long as there is only one op total.
@@ -1691,9 +1602,6 @@
 			}
 			connection_op_activate( op );
 		}
-#else
-		connection_op_activate( op );
-#endif
 	}
 
 #ifdef NO_THREADS
@@ -1713,12 +1621,9 @@
 	Operation *op;
 
 	if( conn->c_conn_state == SLAP_C_CLOSING ) {
-		ber_socket_t	sd;
-		ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
-
 		Debug( LDAP_DEBUG_TRACE, "connection_resched: "
 			"attempting closing conn=%lu sd=%d\n",
-			conn->c_connid, sd, 0 );
+			conn->c_connid, conn->c_sd, 0 );
 		connection_close( conn );
 		return 0;
 	}
@@ -1984,10 +1889,23 @@
 void
 connection_fake_init(
 	Connection *conn,
-	Operation *op,
+	OperationBuffer *opbuf,
 	void *ctx )
 {
+	connection_fake_init2( conn, opbuf, ctx, 1 );
+}
+
+void
+connection_fake_init2(
+	Connection *conn,
+	OperationBuffer *opbuf,
+	void *ctx,
+	int newmem )
+{
+	Operation *op = (Operation *) opbuf;
+
 	conn->c_connid = -1;
+	conn->c_conn_idx = -1;
 	conn->c_send_ldap_result = slap_send_ldap_result;
 	conn->c_send_search_entry = slap_send_search_entry;
 	conn->c_send_search_reference = slap_send_search_reference;
@@ -1995,27 +1913,29 @@
 	conn->c_peer_domain = slap_empty_bv;
 	conn->c_peer_name = slap_empty_bv;
 
-	memset(op, 0, OPERATION_BUFFER_SIZE);
-	op->o_hdr = (Opheader *)(op+1);
-	op->o_controls = (void **)(op->o_hdr+1);
+	memset( opbuf, 0, sizeof( *opbuf ));
+	op->o_hdr = &opbuf->ob_hdr;
+	op->o_controls = opbuf->ob_controls;
+
 	/* set memory context */
-	op->o_tmpmemctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx);
+	op->o_tmpmemctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx,
+		newmem );
 	op->o_tmpmfuncs = &slap_sl_mfuncs;
 	op->o_threadctx = ctx;
-#ifdef LDAP_DEVEL
 	op->o_tid = ldap_pvt_thread_pool_tid( ctx );
-#endif /* LDAP_DEVEL */
 
+	op->o_counters = &slap_counters;
 	op->o_conn = conn;
 	op->o_connid = op->o_conn->c_connid;
 	connection_init_log_prefix( op );
 
 #ifdef LDAP_SLAPI
 	if ( slapi_plugins_used ) {
-		conn_fake_extblock *eb = NULL;
+		conn_fake_extblock *eb;
+		void *ebx = NULL;
 
 		/* Use thread keys to make sure these eventually get cleaned up */
-		if ( ldap_pvt_thread_pool_getkey( ctx, connection_fake_init, &eb,
+		if ( ldap_pvt_thread_pool_getkey( ctx, connection_fake_init, &ebx,
 			NULL )) {
 			eb = ch_malloc( sizeof( *eb ));
 			slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn );
@@ -2025,6 +1945,7 @@
 			ldap_pvt_thread_pool_setkey( ctx, connection_fake_init, eb,
 				connection_fake_destroy );
 		} else {
+			eb = ebx;
 			conn->c_extensions = eb->eb_conn;
 			op->o_hdr->oh_extensions = eb->eb_op;
 		}

Modified: openldap/trunk/servers/slapd/controls.c
===================================================================
--- openldap/trunk/servers/slapd/controls.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/controls.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,4 +1,4 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/controls.c,v 1.125.2.24 2007/01/02 21:43:55 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/controls.c,v 1.174.2.8 2007/11/08 19:16:50 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -21,31 +21,33 @@
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "ldif.h"
+#include "lutil.h"
 
 #include "../../libraries/liblber/lber-int.h"
 
 static SLAP_CTRL_PARSE_FN parseAssert;
-static SLAP_CTRL_PARSE_FN parsePreRead;
-static SLAP_CTRL_PARSE_FN parsePostRead;
-static SLAP_CTRL_PARSE_FN parseProxyAuthz;
-#ifdef LDAP_DEVEL
+static SLAP_CTRL_PARSE_FN parseDomainScope;
 static SLAP_CTRL_PARSE_FN parseDontUseCopy;
-static SLAP_CTRL_PARSE_FN parseManageDIT;
-#endif
 static SLAP_CTRL_PARSE_FN parseManageDSAit;
 static SLAP_CTRL_PARSE_FN parseNoOp;
 static SLAP_CTRL_PARSE_FN parsePagedResults;
-#ifdef LDAP_DEVEL
+static SLAP_CTRL_PARSE_FN parsePermissiveModify;
+static SLAP_CTRL_PARSE_FN parsePreRead, parsePostRead;
+static SLAP_CTRL_PARSE_FN parseProxyAuthz;
+static SLAP_CTRL_PARSE_FN parseRelax;
+static SLAP_CTRL_PARSE_FN parseSearchOptions;
+#ifdef SLAP_CONTROL_X_SORTEDRESULTS
 static SLAP_CTRL_PARSE_FN parseSortedResults;
 #endif
-static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
-static SLAP_CTRL_PARSE_FN parsePermissiveModify;
-static SLAP_CTRL_PARSE_FN parseDomainScope;
+static SLAP_CTRL_PARSE_FN parseSubentries;
 #ifdef SLAP_CONTROL_X_TREE_DELETE
 static SLAP_CTRL_PARSE_FN parseTreeDelete;
 #endif
-static SLAP_CTRL_PARSE_FN parseSearchOptions;
-static SLAP_CTRL_PARSE_FN parseSubentries;
+static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+static SLAP_CTRL_PARSE_FN parseSessionTracking;
+#endif
 
 #undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
 
@@ -65,7 +67,8 @@
 	slap_mask_t sc_mask;
 
 	/* Extended operations supported by control */
-	char **sc_extendedops;
+	char **sc_extendedops;		/* input */
+	BerVarray sc_extendedopsbv;	/* run-time use */
 
 	/* Control parsing callback */
 	SLAP_CTRL_PARSE_FN *sc_parse;
@@ -95,106 +98,151 @@
 
 static char *proxy_authz_extops[] = {
 	LDAP_EXOP_MODIFY_PASSWD,
-	LDAP_EXOP_X_WHO_AM_I,
+	LDAP_EXOP_WHO_AM_I,
+	LDAP_EXOP_REFRESH,
 	NULL
 };
 
+static char *manageDSAit_extops[] = {
+	LDAP_EXOP_REFRESH,
+	NULL
+};
+
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+static char *session_tracking_extops[] = {
+	LDAP_EXOP_MODIFY_PASSWD,
+	LDAP_EXOP_WHO_AM_I,
+	LDAP_EXOP_REFRESH,
+	NULL
+};
+#endif
+
 static struct slap_control control_defs[] = {
 	{  LDAP_CONTROL_ASSERT,
  		(int)offsetof(struct slap_control_ids, sc_assert),
 		SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME|
-			SLAP_CTRL_COMPARE|SLAP_CTRL_SEARCH, NULL,
+			SLAP_CTRL_COMPARE|SLAP_CTRL_SEARCH,
+		NULL, NULL,
 		parseAssert, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 	{ LDAP_CONTROL_PRE_READ,
  		(int)offsetof(struct slap_control_ids, sc_preRead),
-		SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME, NULL,
+		SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME,
+		NULL, NULL,
 		parsePreRead, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 	{ LDAP_CONTROL_POST_READ,
  		(int)offsetof(struct slap_control_ids, sc_postRead),
-		SLAP_CTRL_ADD|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME, NULL,
+		SLAP_CTRL_ADD|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME,
+		NULL, NULL,
 		parsePostRead, LDAP_SLIST_ENTRY_INITIALIZER(next) },
  	{ LDAP_CONTROL_VALUESRETURNFILTER,
  		(int)offsetof(struct slap_control_ids, sc_valuesReturnFilter),
- 		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
+ 		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH,
+		NULL, NULL,
 		parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#ifdef LDAP_CONTROL_X_VALUESRETURNFILTER
- 	{ LDAP_CONTROL_X_VALUESRETURNFILTER,
- 		(int)offsetof(struct slap_control_ids, sc_valuesReturnFilter),
- 		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
-		parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
 	{ LDAP_CONTROL_PAGEDRESULTS,
  		(int)offsetof(struct slap_control_ids, sc_pagedResults),
-		SLAP_CTRL_SEARCH, NULL,
+		SLAP_CTRL_SEARCH,
+		NULL, NULL,
 		parsePagedResults, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#ifdef LDAP_DEVEL
+#ifdef SLAP_CONTROL_X_SORTEDRESULTS
 	{ LDAP_CONTROL_SORTREQUEST,
  		(int)offsetof(struct slap_control_ids, sc_sortedResults),
-		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
+		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE,
+		NULL, NULL,
 		parseSortedResults, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
 	{ LDAP_CONTROL_X_DOMAIN_SCOPE,
  		(int)offsetof(struct slap_control_ids, sc_domainScope),
-		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
+		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE,
+		NULL, NULL,
 		parseDomainScope, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+	{ LDAP_CONTROL_DONTUSECOPY,
+ 		(int)offsetof(struct slap_control_ids, sc_dontUseCopy),
+		SLAP_CTRL_GLOBAL|SLAP_CTRL_INTROGATE|SLAP_CTRL_HIDE,
+		NULL, NULL,
+		parseDontUseCopy, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 	{ LDAP_CONTROL_X_PERMISSIVE_MODIFY,
  		(int)offsetof(struct slap_control_ids, sc_permissiveModify),
-		SLAP_CTRL_MODIFY|SLAP_CTRL_HIDE, NULL,
+		SLAP_CTRL_MODIFY|SLAP_CTRL_HIDE,
+		NULL, NULL,
 		parsePermissiveModify, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #ifdef SLAP_CONTROL_X_TREE_DELETE
 	{ LDAP_CONTROL_X_TREE_DELETE,
  		(int)offsetof(struct slap_control_ids, sc_treeDelete),
-		SLAP_CTRL_DELETE|SLAP_CTRL_HIDE, NULL,
+		SLAP_CTRL_DELETE|SLAP_CTRL_HIDE,
+		NULL, NULL,
 		parseTreeDelete, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
 	{ LDAP_CONTROL_X_SEARCH_OPTIONS,
  		(int)offsetof(struct slap_control_ids, sc_searchOptions),
-		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
+		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE,
+		NULL, NULL,
 		parseSearchOptions, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 	{ LDAP_CONTROL_SUBENTRIES,
  		(int)offsetof(struct slap_control_ids, sc_subentries),
-		SLAP_CTRL_SEARCH, NULL,
+		SLAP_CTRL_SEARCH,
+		NULL, NULL,
 		parseSubentries, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 	{ LDAP_CONTROL_NOOP,
  		(int)offsetof(struct slap_control_ids, sc_noOp),
-		SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE, NULL,
+		SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE,
+		NULL, NULL,
 		parseNoOp, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#ifdef LDAP_DEVEL
-	{ LDAP_CONTROL_DONTUSECOPY,
- 		(int)offsetof(struct slap_control_ids, sc_dontUseCopy),
-		SLAP_CTRL_INTROGATE|SLAP_CTRL_HIDE, NULL,
-		parseDontUseCopy, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-	{ LDAP_CONTROL_MANAGEDIT,
- 		(int)offsetof(struct slap_control_ids, sc_manageDIT),
-		SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE, NULL,
-		parseManageDIT, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+	{ LDAP_CONTROL_RELAX,
+ 		(int)offsetof(struct slap_control_ids, sc_relax),
+		SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE,
+		NULL, NULL,
+		parseRelax, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#ifdef LDAP_X_TXN
+	{ LDAP_CONTROL_X_TXN_SPEC,
+ 		(int)offsetof(struct slap_control_ids, sc_txnSpec),
+		SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE,
+		NULL, NULL,
+		txn_spec_ctrl, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
 	{ LDAP_CONTROL_MANAGEDSAIT,
  		(int)offsetof(struct slap_control_ids, sc_manageDSAit),
-		SLAP_CTRL_ACCESS, NULL,
+		SLAP_CTRL_ACCESS,
+		manageDSAit_extops, NULL,
 		parseManageDSAit, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 	{ LDAP_CONTROL_PROXY_AUTHZ,
  		(int)offsetof(struct slap_control_ids, sc_proxyAuthz),
-		SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS, proxy_authz_extops,
+		SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS,
+		proxy_authz_extops, NULL,
 		parseProxyAuthz, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-	{ NULL, 0, 0, NULL, 0, LDAP_SLIST_ENTRY_INITIALIZER(next) }
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+	{ LDAP_CONTROL_X_SESSION_TRACKING,
+ 		(int)offsetof(struct slap_control_ids, sc_sessionTracking),
+		SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS|SLAP_CTRL_BIND|SLAP_CTRL_HIDE,
+		session_tracking_extops, NULL,
+		parseSessionTracking, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#endif
+	{ NULL, 0, 0, NULL, 0, NULL, LDAP_SLIST_ENTRY_INITIALIZER(next) }
 };
 
+static struct slap_control *
+find_ctrl( const char *oid );
+
 /*
  * Register a supported control.
  *
  * This can be called by an OpenLDAP plugin or, indirectly, by a
  * SLAPI plugin calling slapi_register_supported_control().
+ *
+ * NOTE: if flags == 1 the control is replaced if already registered;
+ * otherwise registering an already registered control is not allowed.
  */
 int
-register_supported_control(const char *controloid,
+register_supported_control2(const char *controloid,
 	slap_mask_t controlmask,
 	char **controlexops,
 	SLAP_CTRL_PARSE_FN *controlparsefn,
+	unsigned flags,
 	int *controlcid)
 {
-	struct slap_control *sc;
+	struct slap_control *sc = NULL;
 	int i;
+	BerVarray extendedopsbv = NULL;
 
 	if ( num_known_controls >= SLAP_MAX_CIDS ) {
 		Debug( LDAP_DEBUG_ANY, "Too many controls registered."
@@ -203,11 +251,23 @@
 		return LDAP_OTHER;
 	}
 
-	if ( controloid == NULL ) return LDAP_PARAM_ERROR;
+	if ( controloid == NULL ) {
+		return LDAP_PARAM_ERROR;
+	}
 
-	/* sanity check - should never happen */
+	/* check if already registered */
 	for ( i = 0; slap_known_controls[ i ]; i++ ) {
 		if ( strcmp( controloid, slap_known_controls[ i ] ) == 0 ) {
+			if ( flags == 1 ) {
+				Debug( LDAP_DEBUG_TRACE,
+					"Control %s already registered; replacing.\n",
+					controloid, 0, 0 );
+				/* (find and) replace existing handler */
+				sc = find_ctrl( controloid );
+				assert( sc != NULL );
+				break;
+			}
+
 			Debug( LDAP_DEBUG_ANY,
 				"Control %s already registered.\n",
 				controloid, 0, 0 );
@@ -215,31 +275,62 @@
 		}
 	}
 
-	sc = (struct slap_control *)SLAP_MALLOC( sizeof( *sc ) );
-	if ( sc == NULL ) return LDAP_NO_MEMORY;
+	/* turn compatible extended operations into bervals */
+	if ( controlexops != NULL ) {
+		int i;
 
-	sc->sc_oid = ch_strdup( controloid );
-	sc->sc_mask = controlmask;
-	if ( controlexops != NULL ) {
-		sc->sc_extendedops = ldap_charray_dup( controlexops );
-		if ( sc->sc_extendedops == NULL ) {
-			ch_free( sc );
+		for ( i = 0; controlexops[ i ]; i++ );
+
+		extendedopsbv = ber_memcalloc( i + 1, sizeof( struct berval ) );
+		if ( extendedopsbv == NULL ) {
 			return LDAP_NO_MEMORY;
 		}
+
+		for ( i = 0; controlexops[ i ]; i++ ) {
+			ber_str2bv( controlexops[ i ], 0, 1, &extendedopsbv[ i ] );
+		}
+	}
+
+	if ( sc == NULL ) {
+		sc = (struct slap_control *)SLAP_MALLOC( sizeof( *sc ) );
+		if ( sc == NULL ) {
+			return LDAP_NO_MEMORY;
+		}
+
+		sc->sc_oid = ch_strdup( controloid );
+		sc->sc_cid = num_known_controls;
+
+		/* Update slap_known_controls, too. */
+		slap_known_controls[num_known_controls - 1] = sc->sc_oid;
+		slap_known_controls[num_known_controls++] = NULL;
+
+		LDAP_SLIST_NEXT( sc, sc_next ) = NULL;
+		LDAP_SLIST_INSERT_HEAD( &controls_list, sc, sc_next );
+
 	} else {
-		sc->sc_extendedops = NULL;
+		if ( sc->sc_extendedopsbv ) {
+			/* FIXME: in principle, we should rather merge
+			 * existing extops with those supported by the
+			 * new control handling implementation.
+			 * In fact, whether a control is compatible with
+			 * an extop should not be a matter of implementation.
+			 * We likely also need a means for a newly
+			 * registered extop to declare that it is
+			 * comptible with an already registered control.
+			 */
+			ber_bvarray_free( sc->sc_extendedopsbv );
+			sc->sc_extendedopsbv = NULL;
+			sc->sc_extendedops = NULL;
+		}
 	}
+
+	sc->sc_extendedopsbv = extendedopsbv;
+	sc->sc_mask = controlmask;
 	sc->sc_parse = controlparsefn;
+	if ( controlcid ) {
+		*controlcid = sc->sc_cid;
+	}
 
-	if ( controlcid ) *controlcid = num_known_controls;
-	sc->sc_cid = num_known_controls;
-
-	/* Update slap_known_controls, too. */
-	slap_known_controls[num_known_controls-1] = sc->sc_oid;
-	slap_known_controls[num_known_controls++] = NULL;
-
-	LDAP_SLIST_NEXT( sc, sc_next ) = NULL;
-	LDAP_SLIST_INSERT_HEAD( &controls_list, sc, sc_next );
 	return LDAP_SUCCESS;
 }
 
@@ -277,8 +368,8 @@
 		LDAP_SLIST_REMOVE_HEAD(&controls_list, sc_next);
 
 		ch_free( sc->sc_oid );
-		if ( sc->sc_extendedops != NULL ) {
-			ldap_charray_free( sc->sc_extendedops );
+		if ( sc->sc_extendedopsbv != NULL ) {
+			ber_bvarray_free( sc->sc_extendedopsbv );
 		}
 		ch_free( sc );
 	}
@@ -345,7 +436,7 @@
 	}
 	masks = (slap_mask_t *)SLAP_MALLOC( (n + 1) * sizeof(slap_mask_t) );
 	if  ( masks == NULL ) {
-		ch_free( oids );
+		SLAP_FREE( oids );
 		return LDAP_NO_MEMORY;
 	}
 
@@ -417,9 +508,11 @@
 		return LDAP_COMPARE_TRUE;
 	}
 
+#if 0
 	Debug( LDAP_DEBUG_TRACE,
 		"slap_global_control: unavailable control: %s\n",      
 		oid, 0, 0 );
+#endif
 
 	return LDAP_COMPARE_FALSE;
 }
@@ -479,11 +572,11 @@
 		case LDAP_REQ_EXTENDED:
 			tagmask=~0L;
 			assert( op->ore_reqoid.bv_val != NULL );
-			if( sc->sc_extendedops != NULL ) {
+			if( sc->sc_extendedopsbv != NULL ) {
 				int i;
-				for( i=0; sc->sc_extendedops[i] != NULL; i++ ) {
-					if( strcmp( op->ore_reqoid.bv_val,
-						sc->sc_extendedops[i] ) == 0 )
+				for( i=0; !BER_BVISNULL( &sc->sc_extendedopsbv[i] ); i++ ) {
+					if( bvmatch( &op->ore_reqoid,
+						&sc->sc_extendedopsbv[i] ) )
 					{
 						tagmask=0L;
 						break;
@@ -767,7 +860,6 @@
 	return rs->sr_err;
 }
 
-#ifdef LDAP_DEVEL
 static int parseDontUseCopy (
 	Operation *op,
 	SlapReply *rs,
@@ -778,12 +870,12 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len ) {
-		rs->sr_text = "dontUseCopy control value not empty";
+	if ( !BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "dontUseCopy control value not absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_iscritical != SLAP_CONTROL_CRITICAL ) {
+	if ( !ctrl->ldctl_iscritical ) {
 		rs->sr_text = "dontUseCopy criticality of FALSE not allowed";
 		return LDAP_PROTOCOL_ERROR;
 	}
@@ -792,28 +884,27 @@
 	return LDAP_SUCCESS;
 }
 
-static int parseManageDIT (
+static int parseRelax (
 	Operation *op,
 	SlapReply *rs,
 	LDAPControl *ctrl )
 {
-	if ( op->o_managedit != SLAP_CONTROL_NONE ) {
-		rs->sr_text = "manageDIT control specified multiple times";
+	if ( op->o_relax != SLAP_CONTROL_NONE ) {
+		rs->sr_text = "relax control specified multiple times";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len ) {
-		rs->sr_text = "manageDIT control value not empty";
+	if ( !BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "relax control value not absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	op->o_managedit = ctrl->ldctl_iscritical
+	op->o_relax = ctrl->ldctl_iscritical
 		? SLAP_CONTROL_CRITICAL
 		: SLAP_CONTROL_NONCRITICAL;
 
 	return LDAP_SUCCESS;
 }
-#endif
 
 static int parseManageDSAit (
 	Operation *op,
@@ -825,8 +916,8 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len ) {
-		rs->sr_text = "manageDSAit control value not empty";
+	if ( !BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "manageDSAit control value not absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
@@ -850,11 +941,18 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( BER_BVISEMPTY( &op->o_ndn ) ) {
-		rs->sr_text = "anonymous proxyAuthz not allowed";
-		return LDAP_PROXY_AUTHZ_FAILURE;
+	if ( BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "proxy authorization control value absent";
+		return LDAP_PROTOCOL_ERROR;
 	}
 
+	if ( !( global_allows & SLAP_ALLOW_PROXY_AUTHZ_ANON )
+		&& BER_BVISEMPTY( &op->o_ndn ) )
+	{
+		rs->sr_text = "anonymous proxied authorization not allowed";
+		return LDAP_PROXIED_AUTHORIZATION_DENIED;
+	}
+
 	op->o_proxy_authz = ctrl->ldctl_iscritical
 		? SLAP_CONTROL_CRITICAL
 		: SLAP_CONTROL_NONCRITICAL;
@@ -865,7 +963,7 @@
 		ctrl->ldctl_value.bv_len ?  ctrl->ldctl_value.bv_val : "anonymous",
 		0 );
 
-	if ( ctrl->ldctl_value.bv_len == 0 ) {
+	if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
 		Debug( LDAP_DEBUG_TRACE,
 			"parseProxyAuthz: conn=%lu anonymous\n", 
 			op->o_connid, 0, 0 );
@@ -893,7 +991,7 @@
 			ch_free( dn.bv_val );
 		}
 		rs->sr_text = "authzId mapping failed";
-		return LDAP_PROXY_AUTHZ_FAILURE;
+		return LDAP_PROXIED_AUTHORIZATION_DENIED;
 	}
 
 	Debug( LDAP_DEBUG_TRACE,
@@ -906,7 +1004,7 @@
 	if ( rc ) {
 		ch_free( dn.bv_val );
 		rs->sr_text = "not authorized to assume identity";
-		return LDAP_PROXY_AUTHZ_FAILURE;
+		return LDAP_PROXIED_AUTHORIZATION_DENIED;
 	}
 
 	ch_free( op->o_ndn.bv_val );
@@ -935,7 +1033,7 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len ) {
+	if ( !BER_BVISNULL( &ctrl->ldctl_value ) ) {
 		rs->sr_text = "noop control value not empty";
 		return LDAP_PROTOCOL_ERROR;
 	}
@@ -952,20 +1050,26 @@
 	SlapReply *rs,
 	LDAPControl *ctrl )
 {
+	BerElementBuffer berbuf;
+	BerElement	*ber = (BerElement *)&berbuf;
+	struct berval	cookie;
+	PagedResultsState	*ps;
 	int		rc = LDAP_SUCCESS;
 	ber_tag_t	tag;
 	ber_int_t	size;
-	BerElement	*ber;
-	struct berval	cookie = BER_BVNULL;
-	PagedResultsState	*ps;
 
 	if ( op->o_pagedresults != SLAP_CONTROL_NONE ) {
 		rs->sr_text = "paged results control specified multiple times";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
+	if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
+		rs->sr_text = "paged results control value is absent";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
 	if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
-		rs->sr_text = "paged results control value is empty (or absent)";
+		rs->sr_text = "paged results control value is empty";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
@@ -977,11 +1081,7 @@
 	 *		cookie	OCTET STRING
 	 * }
 	 */
-	ber = ber_init( &ctrl->ldctl_value );
-	if ( ber == NULL ) {
-		rs->sr_text = "internal error";
-		return LDAP_OTHER;
-	}
+	ber_init2( ber, &ctrl->ldctl_value, LBER_USE_DER );
 
 	tag = ber_scanf( ber, "{im}", &size, &cookie );
 
@@ -1000,6 +1100,7 @@
 	ps = op->o_tmpalloc( sizeof(PagedResultsState), op->o_tmpmemctx );
 	*ps = op->o_conn->c_pagedresults_state;
 	ps->ps_size = size;
+	ps->ps_cookieval = cookie;
 	op->o_pagedresults_state = ps;
 
 	/* NOTE: according to RFC 2696 3.:
@@ -1023,11 +1124,10 @@
 	}
 
 done:;
-	(void)ber_free( ber, 1 );
 	return rc;
 }
 
-#ifdef LDAP_DEVEL
+#ifdef SLAP_CONTROL_X_SORTEDRESULTS
 static int parseSortedResults (
 	Operation *op,
 	SlapReply *rs,
@@ -1040,8 +1140,13 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
+	if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
+		rs->sr_text = "sorted results control value is absent";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
 	if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
-		rs->sr_text = "sorted results control value is empty (or absent)";
+		rs->sr_text = "sorted results control value is empty";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
@@ -1068,11 +1173,16 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len == 0 ) {
-		rs->sr_text = "assert control value is empty (or absent)";
+	if ( BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "assert control value is absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
+	if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
+		rs->sr_text = "assert control value is empty";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
 	ber = ber_init( &(ctrl->ldctl_value) );
 	if (ber == NULL) {
 		rs->sr_text = "assert control: internal error";
@@ -1081,6 +1191,7 @@
 	
 	rs->sr_err = get_filter( op, ber, (Filter **)&(op->o_assertion),
 		&rs->sr_text);
+	(void) ber_free( ber, 1 );
 	if( rs->sr_err != LDAP_SUCCESS ) {
 		if( rs->sr_err == SLAPD_DISCONNECT ) {
 			rs->sr_err = LDAP_PROTOCOL_ERROR;
@@ -1125,37 +1236,51 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len == 0 ) {
-		rs->sr_text = "preread control value is empty (or absent)";
+	if ( BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "preread control value is absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
+	if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
+		rs->sr_text = "preread control value is empty";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+#ifdef LDAP_X_TXN
+	if ( op->o_txnSpec ) { /* temporary limitation */
+		rs->sr_text = "cannot perform pre-read in transaction";
+		return LDAP_UNWILLING_TO_PERFORM;
+	}
+#endif
+
 	ber = ber_init( &(ctrl->ldctl_value) );
 	if (ber == NULL) {
 		rs->sr_text = "preread control: internal error";
 		return LDAP_OTHER;
 	}
 
+	rs->sr_err = LDAP_SUCCESS;
+
 	siz = sizeof( AttributeName );
 	off = offsetof( AttributeName, an_name );
 	if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
 		rs->sr_text = "preread control: decoding error";
-		return LDAP_PROTOCOL_ERROR;
+		rs->sr_err = LDAP_PROTOCOL_ERROR;
+		goto done;
 	}
 
 	for( i=0; i<siz; i++ ) {
-		int		rc = LDAP_SUCCESS;
 		const char	*dummy = NULL;
 
 		an[i].an_desc = NULL;
 		an[i].an_oc = NULL;
 		an[i].an_oc_exclude = 0;
-		rc = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
-		if ( rc != LDAP_SUCCESS && ctrl->ldctl_iscritical ) {
+		rs->sr_err = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
+		if ( rs->sr_err != LDAP_SUCCESS && ctrl->ldctl_iscritical ) {
 			rs->sr_text = dummy
 				? dummy
 				: "postread control: unknown attributeType";
-			return rc;
+			goto done;
 		}
 	}
 
@@ -1165,8 +1290,9 @@
 
 	op->o_preread_attrs = an;
 
-	rs->sr_err = LDAP_SUCCESS;
-	return LDAP_SUCCESS;
+done:
+	(void) ber_free( ber, 1 );
+	return rs->sr_err;
 }
 
 static int parsePostRead (
@@ -1183,37 +1309,69 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len == 0 ) {
-		rs->sr_text = "postread control value is empty (or absent)";
+	if ( BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "postread control value is absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
+	if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
+		rs->sr_text = "postread control value is empty";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+#ifdef LDAP_X_TXN
+	if ( op->o_txnSpec ) { /* temporary limitation */
+		rs->sr_text = "cannot perform post-read in transaction";
+		return LDAP_UNWILLING_TO_PERFORM;
+	}
+#endif
+
 	ber = ber_init( &(ctrl->ldctl_value) );
 	if (ber == NULL) {
 		rs->sr_text = "postread control: internal error";
 		return LDAP_OTHER;
 	}
 
+	rs->sr_err = LDAP_SUCCESS;
 	siz = sizeof( AttributeName );
 	off = offsetof( AttributeName, an_name );
 	if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
 		rs->sr_text = "postread control: decoding error";
-		return LDAP_PROTOCOL_ERROR;
+		rs->sr_err = LDAP_PROTOCOL_ERROR;
+		goto done;
 	}
 
-	for( i=0; i<siz; i++ ) {
-		int		rc = LDAP_SUCCESS;
+	for ( i = 0; i < siz; i++ ) {
 		const char	*dummy = NULL;
+		int		rc;
 
 		an[i].an_desc = NULL;
 		an[i].an_oc = NULL;
 		an[i].an_oc_exclude = 0;
 		rc = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
-		if ( rc != LDAP_SUCCESS && ctrl->ldctl_iscritical ) {
-			rs->sr_text = dummy
-				? dummy
-				: "postread control: unknown attributeType";
-			return rc;
+		if ( rc != LDAP_SUCCESS ) {
+			int			i;
+			static struct berval	special_attrs[] = {
+				BER_BVC( LDAP_NO_ATTRS ),
+				BER_BVC( LDAP_ALL_USER_ATTRIBUTES ),
+				BER_BVC( LDAP_ALL_OPERATIONAL_ATTRIBUTES ),
+				BER_BVNULL
+			};
+
+			/* deal with special attribute types */
+			for ( i = 0; !BER_BVISNULL( &special_attrs[ i ] ); i++ ) {
+				if ( bvmatch( &an[i].an_name, &special_attrs[ i ] ) ) {
+					break;
+				}
+			}
+
+			if ( BER_BVISNULL( &special_attrs[ i ] ) && ctrl->ldctl_iscritical ) {
+				rs->sr_err = rc;
+				rs->sr_text = dummy
+					? dummy
+					: "postread control: unknown attributeType";
+				goto done;
+			}
 		}
 	}
 
@@ -1223,8 +1381,9 @@
 
 	op->o_postread_attrs = an;
 
-	rs->sr_err = LDAP_SUCCESS;
-	return LDAP_SUCCESS;
+done:
+	(void) ber_free( ber, 1 );
+	return rs->sr_err;
 }
 
 static int parseValuesReturnFilter (
@@ -1240,11 +1399,16 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len == 0 ) {
-		rs->sr_text = "valuesReturnFilter control value is empty (or absent)";
+	if ( BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "valuesReturnFilter control value is absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
+	if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
+		rs->sr_text = "valuesReturnFilter control value is empty";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
 	ber = ber_init( &(ctrl->ldctl_value) );
 	if (ber == NULL) {
 		rs->sr_text = "internal error";
@@ -1324,8 +1488,8 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len ) {
-		rs->sr_text = "permissiveModify control value not empty";
+	if ( BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "permissiveModify control value not absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
@@ -1346,7 +1510,7 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len ) {
+	if ( BER_BVISNULL( &ctrl->ldctl_value )) {
 		rs->sr_text = "domainScope control value not empty";
 		return LDAP_PROTOCOL_ERROR;
 	}
@@ -1369,8 +1533,8 @@
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	if ( ctrl->ldctl_value.bv_len ) {
-		rs->sr_text = "treeDelete control value not empty";
+	if ( !BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "treeDelete control value not absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
@@ -1391,24 +1555,30 @@
 	ber_int_t search_flags;
 	ber_tag_t tag;
 
-	if ( ctrl->ldctl_value.bv_len == 0 ) {
-		rs->sr_text = "searchOptions control value is empty (or absent)";
+	if ( BER_BVISNULL( &ctrl->ldctl_value )) {
+		rs->sr_text = "searchOptions control value is absent";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
+	if ( BER_BVISEMPTY( &ctrl->ldctl_value )) {
+		rs->sr_text = "searchOptions control value is empty";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
 	ber = ber_init( &ctrl->ldctl_value );
 	if( ber == NULL ) {
 		rs->sr_text = "internal error";
 		return LDAP_OTHER;
 	}
 
-	if ( (tag = ber_scanf( ber, "{i}", &search_flags )) == LBER_ERROR ) {
+	tag = ber_scanf( ber, "{i}", &search_flags );
+	(void) ber_free( ber, 1 );
+
+	if ( tag == LBER_ERROR ) {
 		rs->sr_text = "searchOptions control decoding error";
 		return LDAP_PROTOCOL_ERROR;
 	}
 
-	(void) ber_free( ber, 1 );
-
 	if ( search_flags & LDAP_SEARCH_FLAG_DOMAIN_SCOPE ) {
 		if ( op->o_domain_scope != SLAP_CONTROL_NONE ) {
 			rs->sr_text = "searchOptions control specified multiple times "
@@ -1433,3 +1603,302 @@
 	return LDAP_SUCCESS;
 }
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+struct berval session_tracking_formats[] = {
+	BER_BVC( LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_SESSION_ID ),
+		BER_BVC( "RADIUS-Acct-Session-Id" ),
+	BER_BVC( LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_MULTI_SESSION_ID ),
+		BER_BVC( "RADIUS-Acct-Multi-Session-Id" ),
+	BER_BVC( LDAP_CONTROL_X_SESSION_TRACKING_USERNAME ),
+		BER_BVC( "USERNAME" ),
+
+	BER_BVNULL
+};
+
+static int parseSessionTracking(
+	Operation *op,
+	SlapReply *rs,
+	LDAPControl *ctrl )
+{
+	BerElement		*ber;
+	ber_tag_t		tag;
+	ber_len_t		len;
+	int			i, rc;
+
+	struct berval		sessionSourceIp = BER_BVNULL,
+				sessionSourceName = BER_BVNULL,
+				formatOID = BER_BVNULL,
+				sessionTrackingIdentifier = BER_BVNULL;
+
+	size_t			st_len, st_pos;
+
+	if ( ctrl->ldctl_iscritical ) {
+		rs->sr_text = "sessionTracking criticality is TRUE";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
+		rs->sr_text = "sessionTracking control value is absent";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
+		rs->sr_text = "sessionTracking control value is empty";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	/* TODO: add the capability to determine if a client is allowed
+	 * to use this control, based on identity, ip and so */
+
+	ber = ber_init( &ctrl->ldctl_value );
+	if ( ber == NULL ) {
+		rs->sr_text = "internal error";
+		return LDAP_OTHER;
+	}
+
+	tag = ber_skip_tag( ber, &len );
+	if ( tag != LBER_SEQUENCE ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	/* sessionSourceIp */
+	tag = ber_peek_tag( ber, &len );
+	if ( tag == LBER_DEFAULT ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	if ( len == 0 ) {
+		tag = ber_skip_tag( ber, &len );
+
+	} else if ( len > 128 ) {
+		rs->sr_text = "sessionTracking.sessionSourceIp too long";
+		rs->sr_err = LDAP_PROTOCOL_ERROR;
+		goto error;
+
+	} else {
+		tag = ber_scanf( ber, "m", &sessionSourceIp );
+	}
+
+	if ( ldif_is_not_printable( sessionSourceIp.bv_val, sessionSourceIp.bv_len ) ) {
+		BER_BVZERO( &sessionSourceIp );
+	}
+
+	/* sessionSourceName */
+	tag = ber_peek_tag( ber, &len );
+	if ( tag == LBER_DEFAULT ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	if ( len == 0 ) {
+		tag = ber_skip_tag( ber, &len );
+
+	} else if ( len > 65536 ) {
+		rs->sr_text = "sessionTracking.sessionSourceName too long";
+		rs->sr_err = LDAP_PROTOCOL_ERROR;
+		goto error;
+
+	} else {
+		tag = ber_scanf( ber, "m", &sessionSourceName );
+	}
+
+	if ( ldif_is_not_printable( sessionSourceName.bv_val, sessionSourceName.bv_len ) ) {
+		BER_BVZERO( &sessionSourceName );
+	}
+
+	/* formatOID */
+	tag = ber_peek_tag( ber, &len );
+	if ( tag == LBER_DEFAULT ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	if ( len == 0 ) {
+		rs->sr_text = "sessionTracking.formatOID empty";
+		rs->sr_err = LDAP_PROTOCOL_ERROR;
+		goto error;
+
+	} else if ( len > 1024 ) {
+		rs->sr_text = "sessionTracking.formatOID too long";
+		rs->sr_err = LDAP_PROTOCOL_ERROR;
+		goto error;
+
+	} else {
+		tag = ber_scanf( ber, "m", &formatOID );
+	}
+
+	rc = numericoidValidate( NULL, &formatOID );
+	if ( rc != LDAP_SUCCESS ) {
+		rs->sr_text = "sessionTracking.formatOID invalid";
+		goto error;
+	}
+
+	for ( i = 0; !BER_BVISNULL( &session_tracking_formats[ i ] ); i += 2 )
+	{
+		if ( bvmatch( &formatOID, &session_tracking_formats[ i ] ) ) {
+			formatOID = session_tracking_formats[ i + 1 ];
+			break;
+		}
+	}
+
+	/* sessionTrackingIdentifier */
+	tag = ber_peek_tag( ber, &len );
+	if ( tag == LBER_DEFAULT ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+
+	if ( len == 0 ) {
+		tag = ber_skip_tag( ber, &len );
+
+	} else {
+		/* note: should not be more than 65536... */
+		tag = ber_scanf( ber, "m", &sessionTrackingIdentifier );
+		if ( ldif_is_not_printable( sessionTrackingIdentifier.bv_val, sessionTrackingIdentifier.bv_len ) ) {
+			/* we want the OID printed, at least */
+			BER_BVSTR( &sessionTrackingIdentifier, "" );
+		}
+	}
+
+	/* closure */
+	tag = ber_skip_tag( ber, &len );
+	if ( tag != LBER_DEFAULT || len != 0 ) {
+		tag = LBER_ERROR;
+		goto error;
+	}
+	tag = 0;
+
+	st_len = 0;
+	if ( !BER_BVISNULL( &sessionSourceIp ) ) {
+		st_len += STRLENOF( "IP=" ) + sessionSourceIp.bv_len;
+	}
+	if ( !BER_BVISNULL( &sessionSourceName ) ) {
+		if ( st_len ) st_len++;
+		st_len += STRLENOF( "NAME=" ) + sessionSourceName.bv_len;
+	}
+	if ( !BER_BVISNULL( &sessionTrackingIdentifier ) ) {
+		if ( st_len ) st_len++;
+		st_len += formatOID.bv_len + STRLENOF( "=" )
+			+ sessionTrackingIdentifier.bv_len;
+	}
+
+	if ( st_len == 0 ) {
+		goto error;
+	}
+
+	st_len += STRLENOF( " []" );
+	st_pos = strlen( op->o_log_prefix );
+
+	if ( sizeof( op->o_log_prefix ) - st_pos > st_len ) {
+		char	*ptr = &op->o_log_prefix[ st_pos ];
+
+		ptr = lutil_strcopy( ptr, " [" /*]*/ );
+
+		st_len = 0;
+		if ( !BER_BVISNULL( &sessionSourceIp ) ) {
+			ptr = lutil_strcopy( ptr, "IP=" );
+			ptr = lutil_strcopy( ptr, sessionSourceIp.bv_val );
+			st_len++;
+		}
+
+		if ( !BER_BVISNULL( &sessionSourceName ) ) {
+			if ( st_len ) *ptr++ = ' ';
+			ptr = lutil_strcopy( ptr, "NAME=" );
+			ptr = lutil_strcopy( ptr, sessionSourceName.bv_val );
+			st_len++;
+		}
+
+		if ( !BER_BVISNULL( &sessionTrackingIdentifier ) ) {
+			if ( st_len ) *ptr++ = ' ';
+			ptr = lutil_strcopy( ptr, formatOID.bv_val );
+			*ptr++ = '=';
+			ptr = lutil_strcopy( ptr, sessionTrackingIdentifier.bv_val );
+		}
+
+		*ptr++ = /*[*/ ']';
+		*ptr = '\0';
+	}
+
+error:;
+	(void)ber_free( ber, 1 );
+
+	if ( tag == LBER_ERROR ) {
+		rs->sr_text = "sessionTracking control decoding error";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+
+	return rs->sr_err;
+}
+
+int
+slap_ctrl_session_tracking_add(
+	Operation *op,
+	SlapReply *rs,
+	struct berval *ip,
+	struct berval *name,
+	struct berval *id,
+	LDAPControl *ctrl )
+{
+	BerElementBuffer berbuf;
+	BerElement	*ber = (BerElement *)&berbuf;
+
+	static struct berval	oid = BER_BVC( LDAP_CONTROL_X_SESSION_TRACKING_USERNAME );
+
+	assert( ctrl != NULL );
+
+	ber_init2( ber, NULL, LBER_USE_DER );
+
+	ber_printf( ber, "{OOOO}", ip, name, &oid, id ); 
+
+	if ( ber_flatten2( ber, &ctrl->ldctl_value, 0 ) == -1 ) {
+		rs->sr_err = LDAP_OTHER;
+		goto done;
+	}
+
+	ctrl->ldctl_oid = LDAP_CONTROL_X_SESSION_TRACKING;
+	ctrl->ldctl_iscritical = 0;
+
+	rs->sr_err = LDAP_SUCCESS;
+
+done:;
+	return rs->sr_err;
+}
+
+int
+slap_ctrl_session_tracking_request_add( Operation *op, SlapReply *rs, LDAPControl *ctrl )
+{
+	static struct berval	bv_unknown = BER_BVC( SLAP_STRING_UNKNOWN );
+	struct berval		ip = BER_BVNULL,
+				name = BER_BVNULL,
+				id = BER_BVNULL;
+
+	if ( !BER_BVISNULL( &op->o_conn->c_peer_name ) &&
+		memcmp( op->o_conn->c_peer_name.bv_val, "IP=", STRLENOF( "IP=" ) ) == 0 )
+	{
+		char	*ptr;
+
+		ip.bv_val = op->o_conn->c_peer_name.bv_val + STRLENOF( "IP=" );
+		ip.bv_len = op->o_conn->c_peer_name.bv_len - STRLENOF( "IP=" );
+
+		ptr = ber_bvchr( &ip, ':' );
+		if ( ptr ) {
+			ip.bv_len = ptr - ip.bv_val;
+		}
+	}
+
+	if ( !BER_BVISNULL( &op->o_conn->c_peer_domain ) &&
+		!bvmatch( &op->o_conn->c_peer_domain, &bv_unknown ) )
+	{
+		name = op->o_conn->c_peer_domain;
+	}
+
+	if ( !BER_BVISNULL( &op->o_dn ) && !BER_BVISEMPTY( &op->o_dn ) ) {
+		id = op->o_dn;
+	}
+
+	return slap_ctrl_session_tracking_add( op, rs, &ip, &name, &id, ctrl );
+}
+#endif

Modified: openldap/trunk/servers/slapd/cr.c
===================================================================
--- openldap/trunk/servers/slapd/cr.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/cr.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* cr.c - content rule routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/cr.c,v 1.14.2.5 2007/01/02 21:43:55 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/cr.c,v 1.22.2.2 2007/08/31 23:13:58 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
@@ -30,7 +30,7 @@
 };
 
 static Avlnode	*cr_index = NULL;
-static LDAP_STAILQ_HEAD(CRList, slap_content_rule) cr_list
+static LDAP_STAILQ_HEAD(CRList, ContentRule) cr_list
 	= LDAP_STAILQ_HEAD_INITIALIZER(cr_list);
 
 static int
@@ -372,38 +372,44 @@
 	scr->scr_sclass = oc_find(cr->cr_oid);
 	if ( !scr->scr_sclass ) {
 		*err = cr->cr_oid;
-		return SLAP_SCHERR_CLASS_NOT_FOUND;
+		code = SLAP_SCHERR_CLASS_NOT_FOUND;
+		goto fail;
 	}
 
 	/* check object class usage */
 	if( scr->scr_sclass->soc_kind != LDAP_SCHEMA_STRUCTURAL )
 	{
 		*err = cr->cr_oid;
-		return SLAP_SCHERR_CR_BAD_STRUCT;
+		code = SLAP_SCHERR_CR_BAD_STRUCT;
+		goto fail;
 	}
 
 	if( scr->scr_sclass->soc_flags & SLAP_OC_OPERATIONAL ) op++;
 
 	code = cr_add_auxiliaries( scr, &op, err );
-	if ( code != 0 ) return code;
+	if ( code != 0 ) goto fail;
 
 	code = cr_create_required( scr, &op, err );
-	if ( code != 0 ) return code;
+	if ( code != 0 ) goto fail;
 
 	code = cr_create_allowed( scr, &op, err );
-	if ( code != 0 ) return code;
+	if ( code != 0 ) goto fail;
 
 	code = cr_create_precluded( scr, &op, err );
-	if ( code != 0 ) return code;
+	if ( code != 0 ) goto fail;
 
 	if( user && op ) {
-		return SLAP_SCHERR_CR_BAD_AUX;
+		code = SLAP_SCHERR_CR_BAD_AUX;
+		goto fail;
 	}
 
 	code = cr_insert(scr,err);
 	if ( code == 0 && rscr )
 		*rscr = scr;
 	return code;
+fail:
+	ch_free( scr );
+	return code;
 }
 
 void

Modified: openldap/trunk/servers/slapd/ctxcsn.c
===================================================================
--- openldap/trunk/servers/slapd/ctxcsn.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/ctxcsn.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,5 +1,5 @@
 /* ctxcsn.c -- Context CSN Management Routines */
-/* $OpenLDAP: pkg/ldap/servers/slapd/ctxcsn.c,v 1.31.2.9 2007/01/02 21:43:55 kurt Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/ctxcsn.c,v 1.40.2.4 2007/08/31 23:13:58 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 2003-2007 The OpenLDAP Foundation.
@@ -28,6 +28,7 @@
 
 const struct berval slap_ldapsync_bv = BER_BVC("ldapsync");
 const struct berval slap_ldapsync_cn_bv = BER_BVC("cn=ldapsync");
+int slap_serverID;
 
 void
 slap_get_commit_csn(
@@ -128,7 +129,7 @@
 
 	struct berval bv;
 
-	e = (Entry *) ch_calloc( 1, sizeof( Entry ));
+	e = entry_alloc();
 
 	attr_merge( e, slap_schema.si_ad_objectClass,
 		ocbva, NULL );
@@ -164,7 +165,7 @@
 	ldap_pvt_thread_mutex_lock( op->o_bd->be_pcl_mutexp );
 
 	ber_dupbv( &pending->ce_csn, csn );
-	ber_dupbv_x( &op->o_csn, &pending->ce_csn, op->o_tmpmemctx );
+	ber_bvreplace_x( &op->o_csn, &pending->ce_csn, op->o_tmpmemctx );
 	pending->ce_connid = op->o_connid;
 	pending->ce_opid = op->o_opid;
 	pending->ce_state = SLAP_CSN_PENDING;
@@ -181,13 +182,10 @@
 {
 	if ( csn == NULL ) return LDAP_OTHER;
 
-#ifndef HAVE_GMTIME_R
+	/* gmtime doesn't always need a mutex, but lutil_csnstr does */
 	ldap_pvt_thread_mutex_lock( &gmtime_mutex );
-#endif
-	csn->bv_len = lutil_csnstr( csn->bv_val, csn->bv_len, 0, 0 );
-#ifndef HAVE_GMTIME_R
+	csn->bv_len = lutil_csnstr( csn->bv_val, csn->bv_len, slap_serverID, 0 );
 	ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
-#endif
 
 	if ( manage_ctxcsn )
 		slap_queue_csn( op, csn );

Modified: openldap/trunk/servers/slapd/daemon.c
===================================================================
--- openldap/trunk/servers/slapd/daemon.c	2007-12-15 10:06:08 UTC (rev 891)
+++ openldap/trunk/servers/slapd/daemon.c	2007-12-15 10:25:31 UTC (rev 892)
@@ -1,7 +1,8 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/daemon.c,v 1.318.2.32 2007/07/23 20:34:28 hallvard Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/daemon.c,v 1.380.2.8 2007/11/27 20:11:48 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1998-2007 The OpenLDAP Foundation.
+ * Portions Copyright 2007 by Howard Chu, Symas Corporation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,15 +51,10 @@
 #endif /* ! epoll && ! /dev/poll */
 
 #ifdef HAVE_TCPD
-# include <tcpd.h>
 int allow_severity = LOG_INFO;
 int deny_severity = LOG_NOTICE;
+#endif /* TCP Wrappers */
 
-# define SLAP_STRING_UNKNOWN	STRING_UNKNOWN
-#else /* ! TCP Wrappers */
-# define SLAP_STRING_UNKNOWN	"unknown"
-#endif /* ! TCP Wrappers */
-
 #ifdef LDAP_PF_LOCAL
 # include <sys/stat.h>
 /* this should go in <ldap.h> as soon as it is accepted */
@@ -90,13 +86,13 @@
 #ifdef NO_THREADS
 #define WAKE_LISTENER(w)	do { \
 	if ((w) && ++waking < 5) { \
-		tcp_write( wake_sds[1], "0", 1 ); \
+		tcp_write( SLAP_FD2SOCK(wake_sds[1]), "0", 1 ); \
 	} \
 } while (0)
 #else /* ! NO_THREADS */
 #define WAKE_LISTENER(w)	do { \
 	if (w) { \
-		tcp_write( wake_sds[1], "0", 1 ); \
+		tcp_write( SLAP_FD2SOCK(wake_sds[1]), "0", 1 ); \
 	} \
 } while (0)
 #endif /* ! NO_THREADS */
@@ -105,6 +101,15 @@
 volatile sig_atomic_t slapd_gentle_shutdown = 0;
 volatile sig_atomic_t slapd_abrupt_shutdown = 0;
 
+#ifdef HAVE_WINSOCK
+ldap_pvt_thread_mutex_t slapd_ws_mutex;
+SOCKET *slapd_ws_sockets;
+#define	SD_READ 1
+#define	SD_WRITE	2
+#define	SD_ACTIVE	4
+#define	SD_LISTENER	8
+#endif
+
 static struct slap_daemon {
 	ldap_pvt_thread_mutex_t	sd_mutex;
 #ifdef HAVE_TCPD
@@ -113,28 +118,27 @@
 
 	ber_socket_t		sd_nactives;
 	int			sd_nwriters;
+	int			sd_nfds;
 
 #if defined(HAVE_EPOLL)
 	struct epoll_event	*sd_epolls;
 	int			*sd_index;
 	int			sd_epfd;
-	int			sd_nfds;
 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_DEVPOLL)
 	/* eXperimental */
 	struct pollfd		*sd_pollfd;
 	int			*sd_index;
 	Listener		**sd_l;
 	int			sd_dpfd;
-	int			sd_nfds;
 #else /* ! epoll && ! /dev/poll */
-#ifndef HAVE_WINSOCK
-	/* In winsock, accept() returns values higher than dtblsize
-		so don't bother with this optimization */
-	int			sd_nfds;
-#endif /* ! HAVE_WINSOCK */
+#ifdef HAVE_WINSOCK
+	char	*sd_flags;
+	char	*sd_rflags;
+#else /* ! HAVE_WINSOCK */
 	fd_set			sd_actives;
 	fd_set			sd_readers;
 	fd_set			sd_writers;
+#endif /* ! HAVE_WINSOCK */
 #endif /* ! epoll && ! /dev/poll */
 } slap_daemon;
 
@@ -187,14 +191,12 @@
 # define SLAP_SOCK_CLR_READ(s)		SLAP_EPOLL_SOCK_CLR((s), EPOLLIN)
 # define SLAP_SOCK_CLR_WRITE(s)		SLAP_EPOLL_SOCK_CLR((s), EPOLLOUT)
 
-# ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 #  define SLAP_SOCK_SET_SUSPEND(s) \
 	( slap_daemon.sd_suspend[SLAP_EPOLL_SOCK_IX(s)] = 1 )
 #  define SLAP_SOCK_CLR_SUSPEND(s) \
 	( slap_daemon.sd_suspend[SLAP_EPOLL_SOCK_IX(s)] = 0 )
 #  define SLAP_SOCK_IS_SUSPEND(s) \
 	( slap_daemon.sd_suspend[SLAP_EPOLL_SOCK_IX(s)] == 1 )
-# endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 # define SLAP_EPOLL_EVENT_CLR(i, mode)	(revents[(i)].events &= ~(mode))
 
@@ -361,14 +363,12 @@
 # define SLAP_SOCK_CLR_READ(s)		SLAP_DEVPOLL_SOCK_CLR((s), POLLIN)
 # define SLAP_SOCK_CLR_WRITE(s)		SLAP_DEVPOLL_SOCK_CLR((s), POLLOUT)
 
-# ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 #  define SLAP_SOCK_SET_SUSPEND(s) \
 	( slap_daemon.sd_suspend[SLAP_DEVPOLL_SOCK_IX((s))] = 1 )
 #  define SLAP_SOCK_CLR_SUSPEND(s) \
 	( slap_daemon.sd_suspend[SLAP_DEVPOLL_SOCK_IX((s))] = 0 )
 #  define SLAP_SOCK_IS_SUSPEND(s) \
 	( slap_daemon.sd_suspend[SLAP_DEVPOLL_SOCK_IX((s))] == 1 )
-# endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 # define SLAP_DEVPOLL_EVENT_CLR(i, mode)	(revents[(i)].events &= ~(mode))
 
@@ -466,13 +466,119 @@
 } while (0)
 
 #else /* ! epoll && ! /dev/poll */
+# ifdef HAVE_WINSOCK
+# define SLAP_EVENT_FNAME		"WSselect"
+/* Winsock provides a "select" function but its fd_sets are
+ * actually arrays of sockets. Since these sockets are handles
+ * and not a contiguous range of small integers, we manage our
+ * own "fd" table of socket handles and use their indices as
+ * descriptors.
+ *
+ * All of our listener/connection structures use fds; the actual
+ * I/O functions use sockets. The SLAP_FD2SOCK macro in proto-slap.h
+ * handles the mapping.
+ *
+ * Despite the mapping overhead, this is about 45% more efficient
+ * than just using Winsock's select and FD_ISSET directly.
+ *
+ * Unfortunately Winsock's select implementation doesn't scale well
+ * as the number of connections increases. This probably needs to be
+ * rewritten to use the Winsock overlapped/asynchronous I/O functions.
+ */
+# define SLAP_EVENTS_ARE_INDEXED	1
+# define SLAP_EVENT_DECL		fd_set readfds, writefds
+# define SLAP_EVENT_INIT	do { \
+	int i; \
+	FD_ZERO( &readfds ); \
+	FD_ZERO( &writefds ); \
+	memset( slap_daemon.sd_rflags, 0, slap_daemon.sd_nfds ); \
+	for ( i=0; i<slap_daemon.sd_nfds; i++ ) { \
+		if ( slap_daemon.sd_flags[i] & SD_READ ) \
+			FD_SET( slapd_ws_sockets[i], &readfds );\
+		if ( slap_daemon.sd_flags[i] & SD_WRITE ) \
+			FD_SET( slapd_ws_sockets[i], &writefds ); \
+	} } while ( 0 )
 
+# define SLAP_EVENT_MAX		slap_daemon.sd_nfds
+
+# define SLAP_EVENT_WAIT(tvp, nsp)	do { \
+	int i; \
+	*(nsp) = select( SLAP_EVENT_MAX, &readfds, \
+		nwriters > 0 ? &writefds : NULL, NULL, (tvp) ); \
+	for ( i=0; i<readfds.fd_count; i++) { \
+		int fd = slapd_sock2fd(readfds.fd_array[i]); \
+		if ( fd >= 0 ) { \
+			slap_daemon.sd_rflags[fd] = SD_READ; \
+			if ( fd >= *(nsp)) *(nsp) = fd+1; \
+		} \
+	} \
+	for ( i=0; i<writefds.fd_count; i++) { \
+		int fd = slapd_sock2fd(writefds.fd_array[i]); \
+		if ( fd >= 0 ) { \
+			slap_daemon.sd_rflags[fd] = SD_WRITE; \
+			if ( fd >= *(nsp)) *(nsp) = fd+1; \
+		} \
+	} \
+} while (0)
+
+# define SLAP_EVENT_IS_READ(fd)		(slap_daemon.sd_rflags[fd] & SD_READ)
+# define SLAP_EVENT_IS_WRITE(fd)	(slap_daemon.sd_rflags[fd] & SD_WRITE)
+
+# define SLAP_EVENT_CLR_READ(fd) 	slap_daemon.sd_rflags[fd] &= ~SD_READ;
+# define SLAP_EVENT_CLR_WRITE(fd)	slap_daemon.sd_rflags[fd] &= ~SD_WRITE;
+
+# define SLAP_SOCK_INIT		do { \
+	ldap_pvt_thread_mutex_init( &slapd_ws_mutex ); \
+	slapd_ws_sockets = ch_malloc( dtblsize * ( sizeof(SOCKET) + 2)); \
+	slap_daemon.sd_flags = (char *)(slapd_ws_sockets + dtblsize); \
+	slap_daemon.sd_rflags = slap_daemon.sd_flags + dtblsize; \
+	memset( slapd_ws_sockets, -1, dtblsize * sizeof(SOCKET) ); \
+	slapd_ws_sockets[0] = wake_sds[0]; \
+	slapd_ws_sockets[1] = wake_sds[1]; \
+	wake_sds[0] = 0; \
+	wake_sds[1] = 1; \
+	slap_daemon.sd_nfds = 2; \
+	} while ( 0 )
+
+# define SLAP_SOCK_DESTROY	do { \
+	ch_free( slapd_ws_sockets ); slapd_ws_sockets = NULL; \
+	slap_daemon.sd_flags = NULL; \
+	slap_daemon.sd_rflags = NULL; \
+	ldap_pvt_thread_mutex_destroy( &slapd_ws_mutex ); \
+	} while ( 0 )
+
+# define SLAP_SOCK_IS_ACTIVE(fd) ( slap_daemon.sd_flags[fd] & SD_ACTIVE )
+# define SLAP_SOCK_IS_READ(fd) ( slap_daemon.sd_flags[fd] & SD_READ )
+# define SLAP_SOCK_IS_WRITE(fd) ( slap_daemon.sd_flags[fd] & SD_WRITE )
+# define SLAP_SOCK_NOT_ACTIVE(fd)	(!slap_daemon.sd_flags[fd])
+
+# define SLAP_SOCK_SET_READ(fd)		( slap_daemon.sd_flags[fd] |= SD_READ )
+# define SLAP_SOCK_SET_WRITE(fd)		( slap_daemon.sd_flags[fd] |= SD_WRITE )
+
+# define SLAP_SELECT_ADDTEST(s)	do { \
+	if ((s) >= slap_daemon.sd_nfds) slap_daemon.sd_nfds = (s)+1; \
+} while (0)
+
+# define SLAP_SOCK_CLR_READ(fd)		( slap_daemon.sd_flags[fd] &= ~SD_READ )
+# define SLAP_SOCK_CLR_WRITE(fd)		( slap_daemon.sd_flags[fd] &= ~SD_WRITE )
+
+# define SLAP_SOCK_ADD(s, l)	do { \
+	SLAP_SELECT_ADDTEST((s)); \
+	slap_daemon.sd_flags[s] = SD_ACTIVE|SD_READ; \
+} while ( 0 )
+
+# define SLAP_SOCK_DEL(s) do { \
+	slap_daemon.sd_flags[s] = 0; \
+	slapd_sockdel( s ); \
+} while ( 0 )
+
+# else /* !HAVE_WINSOCK */
+
 /**************************************
  * Use select system call - select(2) *
  **************************************/
 # define SLAP_EVENT_FNAME		"select"
 /* select */
-
 # define SLAP_EVENTS_ARE_INDEXED	1
 # define SLAP_EVENT_DECL		fd_set readfds, writefds
 
@@ -509,25 +615,13 @@
 # define SLAP_SOCK_NOT_ACTIVE(fd)	(!SLAP_SOCK_IS_ACTIVE(fd) && \
 	 !SLAP_SOCK_IS_READ(fd) && !SLAP_SOCK_IS_WRITE(fd))
 
-# ifdef HAVE_WINSOCK
-#  define SLAP_SOCK_SET_READ(fd)	do { \
-	if (!SLAP_SOCK_IS_READ(fd)) { FD_SET((fd), &slap_daemon.sd_readers); } \
-} while (0)
-#  define SLAP_SOCK_SET_WRITE(fd)	do { \
-	if (!SLAP_SOCK_IS_WRITE(fd)) { FD_SET((fd), &slap_daemon.sd_writers); } \
-} while (0)
+# define SLAP_SOCK_SET_READ(fd)	FD_SET((fd), &slap_daemon.sd_readers)
+# define SLAP_SOCK_SET_WRITE(fd)	FD_SET((fd), &slap_daemon.sd_writers)
 
-#  define SLAP_SELECT_ADDTEST(s)	
-#  define SLAP_EVENT_MAX		dtblsize
-# else /* ! HAVE_WINSOCK */
-#  define SLAP_SOCK_SET_READ(fd)	FD_SET((fd), &slap_daemon.sd_readers)
-#  define SLAP_SOCK_SET_WRITE(fd)	FD_SET((fd), &slap_daemon.sd_writers)
-
-#  define SLAP_EVENT_MAX		slap_daemon.sd_nfds
-#  define SLAP_SELECT_ADDTEST(s)	do { \
+# define SLAP_EVENT_MAX		slap_daemon.sd_nfds
+# define SLAP_SELECT_ADDTEST(s)	do { \
 	if ((s) >= slap_daemon.sd_nfds) slap_daemon.sd_nfds = (s)+1; \
 } while (0)
-# endif /* ! HAVE_WINSOCK */
 
 # define SLAP_SOCK_CLR_READ(fd)		FD_CLR((fd), &slap_daemon.sd_readers)
 # define SLAP_SOCK_CLR_WRITE(fd)	FD_CLR((fd), &slap_daemon.sd_writers)
@@ -554,6 +648,7 @@
 	*(nsp) = select( SLAP_EVENT_MAX, &readfds, \
 		nwriters > 0 ? &writefds : NULL, NULL, (tvp) ); \
 } while (0)
+# endif /* !HAVE_WINSOCK */
 #endif /* ! epoll && ! /dev/poll */
 
 #ifdef HAVE_SLP
@@ -584,28 +679,17 @@
 	/* find and expand INADDR_ANY URLs */
 	for ( i = 0; slapd_srvurls[i] != NULL; i++ ) {
 		if ( strcmp( slapd_srvurls[i], "ldap:///" ) == 0 ) {
-			char *host = ldap_pvt_get_fqdn( NULL );
-			if ( host != NULL ) {
-				slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
-					strlen( host ) +
-					sizeof( LDAP_SRVTYPE_PREFIX ) );
-				strcpy( lutil_strcopy(slapd_srvurls[i],
-					LDAP_SRVTYPE_PREFIX ), host );
-
-				ch_free( host );
-			}
-
+			slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
+				strlen( global_host ) +
+				sizeof( LDAP_SRVTYPE_PREFIX ) );
+			strcpy( lutil_strcopy(slapd_srvurls[i],
+				LDAP_SRVTYPE_PREFIX ), global_host );
 		} else if ( strcmp( slapd_srvurls[i], "ldaps:///" ) == 0 ) {
-			char *host = ldap_pvt_get_fqdn( NULL );
-			if ( host != NULL ) {
-				slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
-					strlen( host ) +
-					sizeof( LDAPS_SRVTYPE_PREFIX ) );
-				strcpy( lutil_strcopy(slapd_srvurls[i],
-					LDAPS_SRVTYPE_PREFIX ), host );
-
-				ch_free( host );
-			}
+			slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
+				strlen( global_host ) +
+				sizeof( LDAPS_SRVTYPE_PREFIX ) );
+			strcpy( lutil_strcopy(slapd_srvurls[i],
+				LDAPS_SRVTYPE_PREFIX ), global_host );
 		}
 	}
 
@@ -695,6 +779,42 @@
 }
 #endif /* HAVE_SLP */
 
+#ifdef HAVE_WINSOCK
+/* Manage the descriptor to socket table */
+ber_socket_t
+slapd_socknew( ber_socket_t s )
+{
+	ber_socket_t i;
+	ldap_pvt_thread_mutex_lock( &slapd_ws_mutex );
+	for ( i = 0; i < dtblsize && slapd_ws_sockets[i] != INVALID_SOCKET; i++ );
+	if ( i == dtblsize ) {
+		WSASetLastError( WSAEMFILE );
+	} else {
+		slapd_ws_sockets[i] = s;
+	}
+	ldap_pvt_thread_mutex_unlock( &slapd_ws_mutex );
+	return i;
+}
+
+void
+slapd_sockdel( ber_socket_t s )
+{
+	ldap_pvt_thread_mutex_lock( &slapd_ws_mutex );
+	slapd_ws_sockets[s] = INVALID_SOCKET;
+	ldap_pvt_thread_mutex_unlock( &slapd_ws_mutex );
+}
+
+ber_socket_t
+slapd_sock2fd( ber_socket_t s )
+{
+	ber_socket_t i;
+	for ( i=0; i<dtblsize && slapd_ws_sockets[i] != s; i++);
+	if ( i == dtblsize )
+		i = -1;
+	return i;
+}
+#endif
+
 /*
  * Add a descriptor to daemon control
  *
@@ -720,9 +840,7 @@
 
 	ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 	WAKE_LISTENER(1);
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 }
 
 /*
@@ -870,7 +988,10 @@
 {
 	Debug( LDAP_DEBUG_CONNS, "daemon: closing %ld\n",
 		(long) s, 0, 0 );
-	tcp_close(s);
+	tcp_close( SLAP_FD2SOCK(s) );
+#ifdef HAVE_WINSOCK
+	slapd_sockdel( s );
+#endif
 }
 
 static void
@@ -1125,6 +1246,7 @@
 	int err, addrlen = 0;
 	struct sockaddr **sal, **psal;
 	int socktype = SOCK_STREAM;	/* default to COTS */
+	ber_socket_t s;
 
 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
 	/*
@@ -1144,9 +1266,7 @@
 
 	l.sl_url.bv_val = NULL;
 	l.sl_mute = 0;
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 	l.sl_busy = 0;
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 #ifndef HAVE_TLS
 	if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
@@ -1244,8 +1364,8 @@
 		if( l.sl_is_udp ) socktype = SOCK_DGRAM;
 #endif /* LDAP_CONNECTIONLESS */
 
-		l.sl_sd = socket( (*sal)->sa_family, socktype, 0);
-		if ( l.sl_sd == AC_SOCKET_INVALID ) {
+		s = socket( (*sal)->sa_family, socktype, 0);
+		if ( s == AC_SOCKET_INVALID ) {
 			int err = sock_errno();
 			Debug( LDAP_DEBUG_ANY,
 				"daemon: %s socket() failed errno=%d (%s)\n",
@@ -1253,17 +1373,16 @@
 			sal++;
 			continue;
 		}
+		l.sl_sd = SLAP_SOCKNEW( s );
 
-#ifndef HAVE_WINSOCK
 		if ( l.sl_sd >= dtblsize ) {
 			Debug( LDAP_DEBUG_ANY,
 				"daemon: listener descriptor %ld is too great %ld\n",
 				(long) l.sl_sd, (long) dtblsize, 0 );
-			tcp_close( l.sl_sd );
+			tcp_close( s );
 			sal++;
 			continue;
 		}
-#endif /* ! HAVE_WINSOCK */
 
 #ifdef LDAP_PF_LOCAL
 		if ( (*sal)->sa_family == AF_LOCAL ) {
@@ -1274,7 +1393,7 @@
 #ifdef SO_REUSEADDR
 			/* enable address reuse */
 			tmp = 1;
-			rc = setsockopt( l.sl_sd, SOL_SOCKET, SO_REUSEADDR,
+			rc = setsockopt( s, SOL_SOCKET, SO_REUSEADDR,
 				(char *) &tmp, sizeof(tmp) );
 			if ( rc == AC_SOCKET_ERROR ) {
 				int err = sock_errno();
@@ -1294,7 +1413,7 @@
 #ifdef IPV6_V6ONLY
 			/* Try to use IPv6 sockets for IPv6 only */
 			tmp = 1;
-			rc = setsockopt( l.sl_sd, IPPROTO_IPV6, IPV6_V6ONLY,
+			rc = setsockopt( s , IPPROTO_IPV6, IPV6_V6ONLY,
 				(char *) &tmp, sizeof(tmp) );
 			if ( rc == AC_SOCKET_ERROR ) {
 				int err = sock_errno();
@@ -1312,7 +1431,7 @@
 #ifdef LOCAL_CREDS
 			{
 				int one = 1;
-				setsockopt( l.sl_sd, 0, LOCAL_CREDS, &one, sizeof( one ) );
+				setsockopt( s, 0, LOCAL_CREDS, &one, sizeof( one ) );
 			}
 #endif /* LOCAL_CREDS */
 
@@ -1336,7 +1455,7 @@
 				old_umask = umask( 0 );
 			}
 #endif /* LDAP_PF_LOCAL */
-			rc = bind( l.sl_sd, *sal, addrlen );
+			rc = bind( s, *sal, addrlen );
 #ifdef LDAP_PF_LOCAL
 			if ( (*sal)->sa_family == AF_LOCAL ) {
 				umask( old_umask );
@@ -1348,7 +1467,7 @@
 			Debug( LDAP_DEBUG_ANY,
 				"daemon: bind(%ld) failed errno=%d (%s)\n",
 				(long)l.sl_sd, err, sock_errstr( err ) );
-			tcp_close( l.sl_sd );
+			tcp_close( s );
 			sal++;
 			continue;
 		}
@@ -1389,9 +1508,9 @@
 			inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
 				addr, sizeof addr);
 			port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
-			l.sl_name.bv_len = strlen(addr) + sizeof("IP= 65535");
+			l.sl_name.bv_len = strlen(addr) + sizeof("IP=[]:65535");
 			l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len );
-			snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=%s %d", 
+			snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=[%s]:%d", 
 				addr, port );
 			l.sl_name.bv_len = strlen( l.sl_name.bv_val );
 		} break;
@@ -1446,7 +1565,7 @@
 
 #ifdef HAVE_SYSCONF
 	dtblsize = sysconf( _SC_OPEN_MAX );
-#elif HAVE_GETDTABLESIZE
+#elif defined(HAVE_GETDTABLESIZE)
 	dtblsize = getdtablesize();
 #else /* ! HAVE_SYSCONF && ! HAVE_GETDTABLESIZE */
 	dtblsize = FD_SETSIZE;
@@ -1522,8 +1641,8 @@
 slapd_daemon_destroy( void )
 {
 	connections_destroy();
-	tcp_close( wake_sds[1] );
-	tcp_close( wake_sds[0] );
+	tcp_close( SLAP_FD2SOCK(wake_sds[1]) );
+	tcp_close( SLAP_FD2SOCK(wake_sds[0]) );
 	sockdestroy();
 
 #ifdef HAVE_SLP
@@ -1582,9 +1701,9 @@
 {
 	Sockaddr		from;
 
-	ber_socket_t s;
+	ber_socket_t s, sfd;
 	ber_socklen_t len = sizeof(from);
-	long id;
+	Connection *c;
 	slap_ssf_t ssf = 0;
 	struct berval authid = BER_BVNULL;
 #ifdef SLAPD_RLOOKUPS
@@ -1595,11 +1714,16 @@
 	char	*peeraddr = NULL;
 #ifdef LDAP_PF_LOCAL
 	char peername[MAXPATHLEN + sizeof("PATH=")];
+#ifdef LDAP_PF_LOCAL_SENDMSG
+	char peerbuf[8];
+	struct berval peerbv = BER_BVNULL;
+#endif
 #elif defined(LDAP_PF_INET6)
-	char peername[sizeof("IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")];
+	char peername[sizeof("IP=[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535")];
 #else /* ! LDAP_PF_LOCAL && ! LDAP_PF_INET6 */
 	char peername[sizeof("IP=255.255.255.255:65336")];
 #endif /* LDAP_PF_LOCAL */
+	int cflag;
 
 	Debug( LDAP_DEBUG_TRACE,
 		">>> slap_listener(%s)\n",
@@ -1617,15 +1741,13 @@
 	from.sa_un_addr.sun_path[0] = '\0';
 #  endif /* LDAP_PF_LOCAL */
 
-	s = accept( sl->sl_sd, (struct sockaddr *) &from, &len );
+	s = accept( SLAP_FD2SOCK( sl->sl_sd ), (struct sockaddr *) &from, &len );
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 	/* Resume the listener FD to allow concurrent-processing of
 	 * additional incoming connections.
 	 */
 	sl->sl_busy = 0;
 	WAKE_LISTENER(1);
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 	if ( s == AC_SOCKET_INVALID ) {
 		int err = sock_errno();
@@ -1652,24 +1774,23 @@
 		ldap_pvt_thread_yield();
 		return 0;
 	}
+	sfd = SLAP_SOCKNEW( s );
 
-#ifndef HAVE_WINSOCK
 	/* make sure descriptor number isn't too great */
-	if ( s >= dtblsize ) {
+	if ( sfd >= dtblsize ) {
 		Debug( LDAP_DEBUG_ANY,
 			"daemon: %ld beyond descriptor table size %ld\n",
-			(long) s, (long) dtblsize, 0 );
+			(long) sfd, (long) dtblsize, 0 );
 
-		slapd_close(s);
+		tcp_close(s);
 		ldap_pvt_thread_yield();
 		return 0;
 	}
-#endif /* ! HAVE_WINSOCK */
 
 #ifdef LDAP_DEBUG
 	ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 	/* newly accepted stream should not be in any of the FD SETS */
-	assert( SLAP_SOCK_NOT_ACTIVE( s ));
+	assert( SLAP_SOCK_NOT_ACTIVE( sfd ));
 	ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 #endif /* LDAP_DEBUG */
 
@@ -1690,7 +1811,7 @@
 			int err = sock_errno();
 			Debug( LDAP_DEBUG_ANY,
 				"slapd(%ld): setsockopt(SO_KEEPALIVE) failed "
-				"errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
+				"errno=%d (%s)\n", (long) sfd, err, sock_errstr(err) );
 		}
 #endif /* SO_KEEPALIVE */
 #ifdef TCP_NODELAY
@@ -1702,7 +1823,7 @@
 			int err = sock_errno();
 			Debug( LDAP_DEBUG_ANY,
 				"slapd(%ld): setsockopt(TCP_NODELAY) failed "
-				"errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
+				"errno=%d (%s)\n", (long) sfd, err, sock_errstr(err) );
 		}
 #endif /* TCP_NODELAY */
 	}
@@ -1710,11 +1831,14 @@
 
 	Debug( LDAP_DEBUG_CONNS,
 		"daemon: listen=%ld, new connection on %ld\n",
-		(long) sl->sl_sd, (long) s, 0 );
+		(long) sl->sl_sd, (long) sfd, 0 );
 
+	cflag = 0;
 	switch ( from.sa_addr.sa_family ) {
 #  ifdef LDAP_PF_LOCAL
 	case AF_LOCAL:
+		cflag |= CONN_IS_IPC;
+
 		/* FIXME: apparently accept doesn't fill
 		 * the sun_path sun_path member */
 		if ( from.sa_un_addr.sun_path[0] == '\0' ) {
@@ -1729,7 +1853,11 @@
 			uid_t uid;
 			gid_t gid;
 
-			if( getpeereid( s, &uid, &gid ) == 0 ) {
+#ifdef LDAP_PF_LOCAL_SENDMSG
+			peerbv.bv_val = peerbuf;
+			peerbv.bv_len = sizeof( peerbuf );
+#endif
+			if( LUTIL_GETPEEREID( s, &uid, &gid, &peerbv ) == 0 ) {
 				authid.bv_val = ch_malloc(
 					STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
 					"cn=peercred,cn=external,cn=auth" ) + 1 );
@@ -1760,7 +1888,7 @@
 		peeraddr = (char *) inet_ntop( AF_INET6,
 				      &from.sa_in6_addr.sin6_addr,
 				      addr, sizeof addr );
-		sprintf( peername, "IP=%s %d",
+		sprintf( peername, "IP=[%s]:%d",
 			 peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
 			 (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
 	}
@@ -1768,14 +1896,14 @@
 #  endif /* LDAP_PF_INET6 */
 
 	case AF_INET:
-	peeraddr = inet_ntoa( from.sa_in_addr.sin_addr );
-	sprintf( peername, "IP=%s:%d",
-		peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
-		(unsigned) ntohs( from.sa_in_addr.sin_port ) );
+		peeraddr = inet_ntoa( from.sa_in_addr.sin_addr );
+		sprintf( peername, "IP=%s:%d",
+			peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
+			(unsigned) ntohs( from.sa_in_addr.sin_port ) );
 		break;
 
 	default:
-		slapd_close(s);
+		slapd_close(sfd);
 		return 0;
 	}
 
@@ -1810,47 +1938,44 @@
 				/* DENY ACCESS */
 				Statslog( LDAP_DEBUG_STATS,
 					"fd=%ld DENIED from %s (%s)\n",
-					(long) s,
+					(long) sfd,
 					dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
 					peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
 					0, 0 );
-				slapd_close(s);
+				slapd_close(sfd);
 				return 0;
 			}
 		}
 #endif /* HAVE_TCPD */
 	}
 
-	id = connection_init(s, sl,
+#ifdef HAVE_TLS
+	if ( sl->sl_is_tls ) cflag |= CONN_IS_TLS;
+#endif
+	c = connection_init(sfd, sl,
 		dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
-		peername,
-#ifdef HAVE_TLS
-		sl->sl_is_tls ? CONN_IS_TLS : 0,
-#else /* ! HAVE_TLS */
-		0,
-#endif /* ! HAVE_TLS */
-		ssf,
-		authid.bv_val ? &authid : NULL );
+		peername, cflag, ssf,
+		authid.bv_val ? &authid : NULL
+		LDAP_PF_LOCAL_SENDMSG_ARG(&peerbv));
 
 	if( authid.bv_val ) ch_free(authid.bv_val);
 
-	if( id < 0 ) {
+	if( !c ) {
 		Debug( LDAP_DEBUG_ANY,
 			"daemon: connection_init(%ld, %s, %s) failed.\n",
-			(long) s, peername, sl->sl_name.bv_val );
-		slapd_close(s);
+			(long) sfd, peername, sl->sl_name.bv_val );
+		slapd_close(sfd);
 		return 0;
 	}
 
 	Statslog( LDAP_DEBUG_STATS,
 		"conn=%ld fd=%ld ACCEPT from %s (%s)\n",
-		id, (long) s, peername, sl->sl_name.bv_val,
+		c->c_connid, (long) sfd, peername, sl->sl_name.bv_val,
 		0 );
 
 	return 0;
 }
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 static void*
 slap_listener_thread(
 	void* ctx,
@@ -1891,7 +2016,6 @@
 	}
 	return rc;
 }
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 static void *
 slapd_daemon_task(
@@ -1933,7 +2057,7 @@
 			continue;
 #endif /* LDAP_CONNECTIONLESS */
 
-		if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN_BACKLOG ) == -1 ) {
+		if ( listen( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), SLAPD_LISTEN_BACKLOG ) == -1 ) {
 			int err = sock_errno();
 
 #ifdef LDAP_PF_INET6
@@ -1978,16 +2102,14 @@
 			return (void*)-1;
 		}
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 		/* make the listening socket non-blocking */
-		if ( ber_pvt_socket_set_nonblock( slap_listeners[l]->sl_sd, 1 ) < 0 ) {
+		if ( ber_pvt_socket_set_nonblock( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), 1 ) < 0 ) {
 			Debug( LDAP_DEBUG_ANY, "slapd_daemon_task: "
 				"set nonblocking on a listening socket failed\n",
 				0, 0, 0 );
 			slapd_shutdown = 2;
 			return (void*)-1;
 		}
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 		slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l] );
 	}
@@ -1998,15 +2120,6 @@
 	}
 #endif /* HAVE_NT_SERVICE_MANAGER */
 
-#ifdef SLAP_SEM_LOAD_CONTROL
-	/*
-	 * initialize count and lazyness of a semaphore
-	 */
-	(void) ldap_lazy_sem_init(
-		SLAP_MAX_WORKER_THREADS + 4 /* max workers + margin */,
-		4 /* lazyness */ );
-#endif /* SLAP_SEM_LOAD_CONTROL */
-
 	/* initialization complete. Here comes the loop. */
 
 	while ( !slapd_shutdown ) {
@@ -2076,11 +2189,7 @@
 
 			if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 			if ( lr->sl_mute || lr->sl_busy )
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-			if ( lr->sl_mute )
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
 			{
 				SLAP_SOCK_CLR_READ( lr->sl_sd );
 			} else {
@@ -2155,7 +2264,6 @@
 				continue;
 			}
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 			if ( lr->sl_busy ) {
 				Debug( LDAP_DEBUG_CONNS,
 					"daemon: " SLAP_EVENT_FNAME ": "
@@ -2163,7 +2271,6 @@
 					lr->sl_sd, 0, 0 );
 				continue;
 			}
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 			Debug( LDAP_DEBUG_CONNS,
 				"daemon: " SLAP_EVENT_FNAME ": "
@@ -2222,7 +2329,7 @@
 			char c[BUFSIZ];
 			SLAP_EVENT_CLR_READ( wake_sds[0] );
 			waking = 0;
-			tcp_read( wake_sds[0], c, sizeof(c) );
+			tcp_read( SLAP_FD2SOCK(wake_sds[0]), c, sizeof(c) );
 			Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 );
 			continue;
 		}
@@ -2246,11 +2353,7 @@
 			SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd );
 			ns--;
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 			rc = slap_listener_activate( slap_listeners[l] );
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-			rc = slap_listener( slap_listeners[l] );
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
 		}
 
 		/* bypass the following tests if no descriptors left */
@@ -2262,19 +2365,6 @@
 		}
 
 		Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
-#ifdef HAVE_WINSOCK
-		nrfds = readfds.fd_count;
-		nwfds = writefds.fd_count;
-		for ( i = 0; i < readfds.fd_count; i++ ) {
-			Debug( LDAP_DEBUG_CONNS, " %d%s",
-				readfds.fd_array[i], "r", 0 );
-		}
-		for ( i = 0; i < writefds.fd_count; i++ ) {
-			Debug( LDAP_DEBUG_CONNS, " %d%s",
-				writefds.fd_array[i], "w", 0 );
-		}
-
-#else /* ! HAVE_WINSOCK */
 		nrfds = 0;
 		nwfds = 0;
 		for ( i = 0; i < nfds; i++ ) {
@@ -2297,18 +2387,13 @@
 			}
 			if ( ns <= 0 ) break;
 		}
-#endif /* ! HAVE_WINSOCK */
 		Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
 
 		/* loop through the writers */
 		for ( i = 0; nwfds > 0; i++ ) {
 			ber_socket_t wd;
-#ifdef HAVE_WINSOCK
-			wd = writefds.fd_array[i];
-#else /* ! HAVE_WINSOCK */
 			if ( ! SLAP_EVENT_IS_WRITE( i ) ) continue;
 			wd = i;
-#endif /* ! HAVE_WINSOCK */
 
 			SLAP_EVENT_CLR_WRITE( wd );
 			nwfds--;
@@ -2336,12 +2421,8 @@
 
 		for ( i = 0; nrfds > 0; i++ ) {
 			ber_socket_t rd;
-#ifdef HAVE_WINSOCK
-			rd = readfds.fd_array[i];
-#else /* ! HAVE_WINSOCK */
 			if ( ! SLAP_EVENT_IS_READ( i ) ) continue;
 			rd = i;
-#endif /* ! HAVE_WINSOCK */
 			SLAP_EVENT_CLR_READ( rd );
 			nrfds--;
 
@@ -2354,11 +2435,7 @@
 			 * active.
 			 */
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 			connection_read_activate( rd );
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-			connection_read( rd );
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
 		}
 #else	/* !SLAP_EVENTS_ARE_INDEXED */
 	/* FIXME */
@@ -2381,7 +2458,7 @@
 		Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
 
 		for ( i = 0; i < ns; i++ ) {
-			int	r, w;
+			int	r, w, fd;
 
 			/* Don't log listener events */
 			if ( SLAP_EVENT_IS_LISTENER( i )
@@ -2393,13 +2470,14 @@
 				continue;
 			}
 
+			fd = SLAP_EVENT_FD( i );
 			/* Don't log internal wake events */
-			if ( SLAP_EVENT_FD( i ) == wake_sds[0] ) continue;
+			if ( fd == wake_sds[0] ) continue;
 
 			r = SLAP_EVENT_IS_READ( i );
 			w = SLAP_EVENT_IS_WRITE( i );
 			if ( r || w ) {
-				Debug( LDAP_DEBUG_CONNS, " %d%s%s", SLAP_EVENT_FD(i),
+				Debug( LDAP_DEBUG_CONNS, " %d%s%s", fd,
 				    r ? "r" : "", w ? "w" : "" );
 			}
 		}
@@ -2410,11 +2488,7 @@
 			int rc = 1, fd;
 
 			if ( SLAP_EVENT_IS_LISTENER( i ) ) {
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 				rc = slap_listener_activate( SLAP_EVENT_LISTENER( i ) );
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-				rc = slap_listener( SLAP_EVENT_LISTENER( i ) );
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
 			}
 
 			/* If we found a regular listener, rc is now zero, and we
@@ -2428,7 +2502,7 @@
 				if ( fd == wake_sds[0] ) {
 					char c[BUFSIZ];
 					waking = 0;
-					tcp_read( wake_sds[0], c, sizeof(c) );
+					tcp_read( SLAP_FD2SOCK(wake_sds[0]), c, sizeof(c) );
 					break;
 				}
 
@@ -2456,17 +2530,7 @@
 						fd, 0, 0 );
 
 					SLAP_EVENT_CLR_READ( i );
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 					connection_read_activate( fd );
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-					/*
-					 * NOTE: it is possible that the connection was closed
-					 * and that the stream is now inactive.
-					 * connection_read() must valid the stream is still
-					 * active.
-					 */
-					connection_read( fd );
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
 				} else {
 					Debug( LDAP_DEBUG_CONNS,
 						"daemon: hangup on %d\n", fd, 0, 0 );
@@ -2528,16 +2592,17 @@
 
 	for ( l = 0; slap_listeners[l] != NULL; l++ ) {
 		Listener *lr = slap_listeners[l];
-		long id;
+		Connection *c;
 
 		if ( !lr->sl_is_udp ) {
 			continue;
 		}
 
-		id = connection_init( lr->sl_sd, lr, "", "",
-			CONN_IS_UDP, (slap_ssf_t) 0, NULL );
+		c = connection_init( lr->sl_sd, lr, "", "",
+			CONN_IS_UDP, (slap_ssf_t) 0, NULL
+			LDAP_PF_LOCAL_SENDMSG_ARG(NULL));
 
-		if ( id < 0 ) {
+		if ( !c ) {
 			Debug( LDAP_DEBUG_TRACE,
 				"connectionless_init: failed on %s (%d)\n",
 				lr->sl_url, lr->sl_sd, 0 );
@@ -2651,7 +2716,7 @@
 	 * SIGBREAK is generated when a user logs out.
 	 */
 
-#if HAVE_NT_SERVICE_MANAGER && SIGBREAK
+#if defined(HAVE_NT_SERVICE_MANAGER) && defined(SIGBREAK)
 	if (is_NT_Service && sig == SIGBREAK) {
 		/* empty */;
 	} else

Modified: openldap/trunk/servers/slapd/delete.c
===================================================================



More information about the Pkg-openldap-devel mailing list